2

一文读懂VictoriaMetrics集群方案

 2 years ago
source link: https://zyun.360.cn/blog/?p=2055
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
一文读懂VictoriaMetrics集群方案 – 智汇云技术社区 一文读懂VictoriaMetrics集群方案
2022-3-15 20:04
2796 字

VictoriaMetrics集群方案,除了有单节点方案的优点以外,还可以做到水平扩容,当有大量数据存储时,VictoriaMetrics集群方案是个不错的选择。官方建议是100w/s以下的数据点抓取,使用单节点版,单节点版可以省更多的CPU、内存、磁盘资源。

但是,当遇到如下问题可以考虑集群方案:

  • 抓取数据点过高:大于100w/s数据点抓取(如果lable内容过多,会低于这个值)
  • 海量数据存储:单机磁盘容量已经满足不了,更长时间的存储、海量数据存储需求
  • 要更高性能:要求更高的写入和查询性能
  • 原生高可用:VictoriaMetrics集群方案,原生支持高可用
  • 多租户:想要数据多租户管理

注意:下面无特殊声明统一把VictoriaMetrics简写成VM。相对于Thanos,VictoriaMetrics主要是一个可水平扩容的本地全量持久化存储方案。下面简单介绍一下VM集群版各个组件功能,通过这些组件才可以完成VM集群方案。

VM集群版官方架构图

组件服务和作用:

组件服务作用默认端口其它说明vmstorage数据存储,以及查询结果返回8482vminsert数据录入,可实现类似分片、副本功能8480vmselect数据查询,汇总和排重数据8481vmagent数据指标抓取,并支持多种后端存储8429会占用本地磁盘缓存vmalert告警规则相关8880如不需要告警功能可不使用此组件服务vmauth账号认证相关8427不建议用,而且用户名是路由

关于启动参数:
vmstorage、vminsert、vmselect这三个组件关键启动参数要关注的不多,之后内容会对关键参数进行说明。

二、多租户

VM集群版支持多租户概念,可以把不类型的数据,分别放到不同的租户(命名空间)里,每个租户通过 accountID 或 accountID:projectID,在请求的url里做区分。其中:

  • accountID和projectID:是[0 .. 2^32)的任意整数,projectID可不写,默认0
  • 创建时间:在首次对某个租户录入数据时,自动创建
  • 性能:租户的数量不影响性能,主要取决于所有租户的活跃总时间序列,每个租户的数据都均匀分布在后端vmstorage存储
  • 隔离:不能跨租户查询

三、API示例

API使用方法基本和VM单节点版差不多,主要多了 租户 和 组件服务名 ,VM集群版querying API 格式:http://<vmselect>:8481/select/<accountID>/prometheus/<suffix> 下面以查询主机负载为例,对比区别:

# Prometheus&VM单节点 querying APIhttp://127.0.0.1:9090/api/v1/query?query=node_load15# VM集群版 querying APIhttp://127.0.0.1:8481/select/6666/prometheus/api/v1/query?query=node_load15

如上,和Prometheus的API请求区别,主要多了 “/select/6666/prometheus” ,其它API请求类似。

四、副本、分片以及HA

4.1 实现方式

此处是本文的重点!请多看几遍。

VM集群版,可以实现副本和分片功能,来保证数据的冗余和水平扩容。主要是VM集群版的几个组件服务配合实现。

1)vmagent:target均摊和自身冗余抓取功能

  • promscrape.cluster.membersCount,指定target分组
  • promscrape.cluster.memberNum,指定当前vmagent,抓取指定target组
  • promscrape.cluster.replicationFactor,单target被多少个vmagent抓取,这里会产生冗余数据,此参数主要是为了保证vmagent的高可用

2)vminsert:按算法为固定时间序列选择后端存储(分片) 和 控制副本数量(副本)

  • replicationFactor,开启副本,并控制副本数量,既 要往多少个vmstorage插入同一份样本数据

3)vmstorage:数据存储,vmstorage节点间不进行任何交互,都是独立的个体,只靠上层的vminsert,产生副本和分片

  • dedup.minScrapeInterval,vmagent会产生replicationFactor份冗余数据,需要此参数,来去除重复数据

4)vmselect:数据汇总以及返回,当vminsert开启副本后,vmselect必须设置dedup.minScrapeInterval,

  • dedup.minScrapeInterval,去除指定时间的重复数据,
  • replicationFactor,当replicationFactor=N,在出现最多N-1个vmstorage不可用或者响应慢时,vmselect查询直接忽略,提升了查询效率

注意:开启副本或修改副本个数(replicationFactor简称RF)后,可能造成数据部分丢失。下面展示没开副本之前已在收集数据,开了副本之后(RF=2),并且vmselect指定replicationFactor参数,vmselect会当成所有数据都是有副本的,但是 RF=2 之前有一段时间是未开副本收集数据的。如下图:当查 t之前 的series1数据时,1节点 突然故障或者响应慢了,vmselect会认为 2节点有副本数据,其实 t之前 是没有开副本的,所以会导致 series1  丢失 1节点 的数据。

4.2 分组与分片原理

1)分片如果vminsert后面存在多个vmstorage,vminsert就会对数据进行分片(或者说打散),vminsert主要通过一致性哈希选择vmstorage节点,具体实现如下代码:

参考:https://github.com/VictoriaMetrics/VictoriaMetrics/blob/38065bec7b1f7d5880f9e0080093cdee6778013b/app/vminsert/netstorage/insert_ctx.go#L158

2)分组vmagent分组方式,通过vmagent传入的4个参数标识集组成员总数、当前成员编号、副本数 ,进行判断,是否为当前vmagent要抓取的target,具体实现方式如下代码:

  1. https://github.com/VictoriaMetrics/VictoriaMetrics/blob/f77dde837a043da1e628dd4390da43f769d7621a/lib/promscrape/config.go#L936
  2. https://github.com/VictoriaMetrics/VictoriaMetrics/blob/f77dde837a043da1e628dd4390da43f769d7621a/lib/promscrape/config.go#L976

五、安全认证

目前只有vmagent有自带了 httpAuth.username、httpAuth.password 的基础认证方式,但最需要有认证功能的vmselect、vminsert、vmstorage却没有,尤其是存在vmui的vmselect。官方给出的解释是,vmselect、vminsert、vmstorage,一般是在上层就把权限认证解决了,而且因为多租户,每个租户都应该有自己的账号密码,所以没有做全局的基础账号认证,而且也不打算开发。(可参考issues:https://github.com/VictoriaMetrics/VictoriaMetrics/issues/456)官方有个vmauth,认证模式比较简单,而且还需要用账号名称做路由标识,没法用同一个账号访问多个组件服务,目前还是建议用nginx做基础账号认证。

六、安装步骤

下面简单演示一下搭建VM集群版的简略步骤:

# 配置变量VM_HOME='/data/victoria-metrics'MEM_LIMIT='128MB'       #内存使用限制VMSOTRAGE_PORT='8482'   #vmstorage监听端口VMSOTRAGE_INSERT_PORT='8400'    #vmstorage对vminsert提供服务的监听端口VMSOTRAGE_SELECT_PORT='8401'    #vmstorage对vmselect提供服务的监听端口VMINSERT_PORT='8480'    #vminsert监听端口VMSELECT_PORT='8481'    #vmselect监听端口VMAGENT_PORT='8429'     #vmagent监听端口REPLICATION_COUNT='2'   #副本数SELECT_STORAGE_NODE_LIST=''INSERT_STORAGE_NODE_LIST=''NODE_LIST='192.168.1.100,192.168.1.101,192.168.1.102,192.168.1.103'for NODE_IP in $(echo ${NODE_LIST} | awk '{split($0,arr,",");for(i in arr) print arr[i]}')do    INSERT_STORAGE_NODE_LIST="${INSERT_STORAGE_NODE_LIST}\"${NODE_IP}:${VMSOTRAGE_INSERT_PORT}\","    SELECT_STORAGE_NODE_LIST="${SELECT_STORAGE_NODE_LIST}\"${NODE_IP}:${VMSOTRAGE_SELECT_PORT}\","done # 创建程序目录mkdir -p ${VM_HOME}/{bin,logs,data,config} # 启动vmstorage服务(所有节点运行)nohup ${VM_HOME}/bin/vmstorage -retentionPeriod=365d \-storageDataPath=${VM_HOME}/data/vmstorage \-memory.allowedBytes=${MEM_LIMIT} \-httpListenAddr=":${VMSOTRAGE_PORT}" \-vminsertAddr=":${VMSOTRAGE_INSERT_PORT}" \-vmselectAddr=":${VMSOTRAGE_SELECT_PORT}" \-dedup.minScrapeInterval=30s \ > ${VM_HOME}/logs/vmstorage.log 2>&1 & # 启动vminsert服务(所有节点运行)nohup ${VM_HOME}/bin/vminsert -replicationFactor=2 \-storageNode=${INSERT_STORAGE_NODE_LIST} \-memory.allowedBytes=${MEM_LIMIT} \-httpListenAddr=":${VMINSERT_PORT}" \> ${VM_HOME}/logs/vminsert.log 2>&1 & # 启动vmselect服务(所有节点运行)nohup ${VM_HOME}/bin/vmselect -dedup.minScrapeInterval=30s \-replicationFactor=${REPLICATION_COUNT} \-storageNode=${SELECT_STORAGE_NODE_LIST} \-memory.allowedBytes=${MEM_LIMIT} \-httpListenAddr=":${VMSELECT_PORT}" \> ${VM_HOME}/logs/vmselect.log 2>&1 & # 启动vmagent服务(所有节点运行)VM_INSERT_URL="http://localhost:${VMINSERT_PORT}"ACCOUNT_ID='6666'   #租户IDMEMBER_NUM=0~3    #每个节点不一样,取值范围0~(membersCount-1)nohup ${VM_HOME}/bin/vmagent -promscrape.cluster.membersCount=4 \-promscrape.cluster.memberNum=${MEMBER_NUM} \-promscrape.cluster.replicationFactor=${REPLICATION_COUNT} \-promscrape.suppressScrapeErrors \-remoteWrite.tmpDataPath=${VM_HOME}/data/vmagent \-remoteWrite.maxDiskUsagePerURL=1GB \-memory.allowedBytes=${MEM_LIMIT} \-httpListenAddr=":${VMAGENT_PORT}" \-promscrape.config=${VM_HOME}/config/prometheus.yml \-remoteWrite.url=${VM_INSERT_URL}/insert/${ACCOUNT_ID}/prometheus/api/v1/write \> ${VM_HOME}/logs/vmagent.log 2>&1 &

可访问 http://192.168.1.100:8481/select/6666/vmui 进入vmui界面

至此,VM集群搭建完成,并可以通过vmui进行数据简单性能数据查看。

七、扩容方案

当VM集群遇到瓶颈,无非就如下几种场景,可根据情况进行扩容:

  • 查询速度过慢:vmselect为无态服务,配置信息都一样,直接扩容,即可解决此问题。
  • 数据录入慢:vminsert和vmselect一样,直接扩容即可。
  • 容量不足:vmstorage水平扩容来解决此问题,因为vmstorage是有态服务,扩容要配合上游组件服务一起。vmstorage各节点配置一样,直接扩容即可。同时需要把上游的vmselect和vminsert的存储列表(-storageNode)进行更新,然后全部重启。
  • 抓取样本量过大:扩容vmagent即可,但需要重新分配所有vmagent对target的分组参数,-promscrape.cluster.membersCount=N 增加总分组数,-promscrape.cluster.memberNum=(0~N-1) 当前vmagent节点所在分组号,修改完后重启所有vmagent。

VM集群版的好处就是 灵活,哪里性能不行扩哪里,哪种类型组件服务运行在哪类主机上,充分利用系统资源。

八、failover处理

VM集群版,各类组件服务故障后,怎么能够实现故障处理?下面针对关键组件,逐一分析一下:

故障组件处理方法vmselect故障此为无态服务,所有节点配置信息一样,故障后直接扩容即可vmagent故障开启replicationFactor=N(N>1)后,单个target都会被N节vmagent点抓取数据,所以故障 “小于等于N-1″个节点,都不会影响数据抓取vminsert故障vminsert所有节点,配置信息都一样。而且vmagent开启replicationFactor,所以每个target样本数据都会被写入到多个vminsert,单个vminsert故障不会丢失数据,新部署一个即可vmstorage故障因为vminsert开启replicationFactor副本,所有target的样本数据都会存在多个vmstorage上,所以故障单个节点,不会丢失数据,只需要等待恢复,或者重新部署单个vmstorage节点

九、资源规划

VM集群各个组件,可根各自特点放到合适的硬件设备上,充分发挥硬件能力。根据业务监控量,可简单预估一下需要CPU和内存资源情况:

vCPUsRAMvminsertingestion_rate / 100K(active time series / 100w) *1G (less than 1KB per active time series)vmstorageingestion_rate / 100K(active time series / 100w) *1G (less than 1KB per active time series)vmselect根据读取量评估根据读取量评估

注:上面只是预估,建议上线之前,还是要根据自己业务类型进行测试,并扩充资源,直到集群变得稳定。

本文主要带大家了解VictoriaMetrics集群方案,并能简单搭建和使用。相对于VictoriaMetrics单节点方案,集群方案架构复杂度更高,但是它可以带来更灵活的使用方式,更好的扩展,容纳更大的数据量,以及更高的资源利用率。
总的来说,当业务用VictoriaMetrics/Prometheus单节点遇到性能、容量、成本等等问题时,VictoriaMetrics集群方案也许能解决你的痛点,为业务带来更高效、稳定的数据展示。

参考资料:

  • https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html
  • https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1207
  • https://www.joyk.com/dig/detail/1558605608214852?page=3

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK