一文读懂VictoriaMetrics集群方案

2022-05-12 00:00:00 数据 集群 节点 租户 副本

01

简介

VictoriaMetrics集群方案,除了有单节点方案的优点以外,还可以做到水平扩容,当有大量数据存储时,VictoriaMetrics集群方案是个不错的选择。

官方建议是100w/s以下的数据点抓取,使用单节点版,单节点版可以省更多的CPU、内存、磁盘资源。

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

  • 抓取数据点过高:大于100w/s数据点抓取(如果lable内容过多,会低于这个值)

  • 海量数据存储:单机磁盘容量已经满足不了,更长时间的存储、海量数据存储需求

  • 要更高性能:要求更高的写入和查询性能

  • 原生高可用:VictoriaMetrics集群方案,原生支持高可用

  • 多租户:想要数据多租户管理

注意:下面无特殊声明统一把VictoriaMetrics简写成VM

相对于Thanos,VictoriaMetrics主要是一个可水平扩容的本地全量持久化存储方案

下面简单介绍一下VM集群版各个组件功能,通过这些组件才可以完成VM集群方案。

VM集群版官方架构图

组件服务和作用

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

关于启动参数:

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-1vmstorage不可用或者响应慢时,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

安全认证

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

可参考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集群版,各类组件服务故障后,怎么能够实现故障处理?下面针对关键组件,逐一分析一下:

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


09

资源规划

VM集群各个组件,可根各自特点放到合适的硬件设备上,充分发挥硬件能力。

根据业务监控量,可简单预估一下需要CPU和内存资源情况:


vCPUsRAM
vminsertingestion_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根据读取量评估根据读取量评估

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


10

总结

本文主要带大家了解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

相关文章