一文读懂VictoriaMetrics集群方案
01
简介
VictoriaMetrics集群方案,除了有单节点方案的优点以外,还可以做到水平扩容,当有大量数据存储时,VictoriaMetrics集群方案是个不错的选择。
官方建议是100w/s以下的数据点抓取,使用单节点版,单节点版可以省更多的CPU、内存、磁盘资源。
但是,当遇到如下问题可以考虑集群方案:
抓取数据点过高:大于100w/s数据点抓取(如果lable内容过多,会低于这个值)
海量数据存储:单机磁盘容量已经满足不了,更长时间的存储、海量数据存储需求
要更高性能:要求更高的写入和查询性能
原生高可用:VictoriaMetrics集群方案,原生支持高可用
多租户:想要数据多租户管理
注意:下面无特殊声明统一把VictoriaMetrics简写成VM。
相对于Thanos,VictoriaMetrics主要是一个可水平扩容的本地全量持久化存储方案。
下面简单介绍一下VM集群版各个组件功能,通过这些组件才可以完成VM集群方案。
VM集群版官方架构图:
组件服务和作用:
关于启动参数:
vmstorage、vminsert、vmselect这三个组件关键启动参数要关注的不多,之后内容会对关键参数进行说明。
02
多租户
VM集群版支持多租户概念,可以把不类型的数据,分别放到不同的租户(命名空间)里,每个租户通过 accountID 或 accountID:projectID,在请求的url里做区分。其中:
accountID和projectID:是[0 .. 2^32)的任意整数,projectID可不写,默认0
创建时间:在对某个租户录入数据时,自动创建
性能:租户的数量不影响性能,主要取决于所有租户的活跃总时间序列,每个租户的数据都均匀分布在后端vmstorage存储
隔离:不能跨租户查询
03
API示例
API使用方法基本和VM单节点版差不多,主要多了 租户 和 组件服务名 ,
VM集群版querying API 格式:
http://<vmselect>:8481/select/<accountID>/prometheus/<suffix>
下面以查询主机负载为例,对比区别:
# Prometheus&VM单节点 querying API
http://127.0.0.1:9090/api/v1/query?query=node_load15
# VM集群版 querying API
http://127.0.0.1:8481/select/6666/prometheus/api/v1/query?query=node_load15
如上,和Prometheus的API请求区别,主要多了 "/select/6666/prometheus" ,其它API请求类似。
04
副本、分片以及HA
4.1实现方式
此处是本文的重点!请多看几遍。
VM集群版,可以实现副本和分片功能,来保证数据的冗余和水平扩容。主要是VM集群版的几个组件服务配合实现。
1)vmagent:target均摊和自身冗余抓取功能
promscrape.cluster.membersCount,指定target被vmagent分成多少抓取组
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,具体实现方式如下代码:
参考:
https://github.com/VictoriaMetrics/VictoriaMetrics/blob/f77dde837a043da1e628dd4390da43f769d7621a/lib/promscrape/config.go#L936
05
安全认证
可参考issues:
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/456
06
安装步骤
下面简单演示一下搭建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' #租户ID
MEMBER_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 &
可访问如下地址,进入vmui界面:
http://192.168.1.100:8481/select/6666/vmui
至此,VM集群搭建完成,并可以通过vmui进行数据简单性能数据查看。
07
扩容方案
当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集群版的好处就是灵活,哪里性能不行扩哪里,那种类型组件服务运行在哪类主机上,充分利用系统资源。
08
failover处理
VM集群版,各类组件服务故障后,怎么能够实现故障处理?下面针对关键组件,逐一分析一下:
09
资源规划
VM集群各个组件,可根各自特点放到合适的硬件设备上,充分发挥硬件能力。
根据业务监控量,可简单预估一下需要CPU和内存资源情况:
注:上面只是预估,建议上线之前,还是要根据自己业务类型进行测试,并扩充资源,直到集群变的稳定。
10
总结
参考资料:
https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html
https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1207
https://www.joyk.com/dig/detail/1558605608214852?page=3
相关文章