VictoriaMetrics高可用原理

Posted by LANG on January 25, 2025

Victoriametrics 是一个快速,成本低廉且可扩展的监控解决方案和时间序列数据库,Victoriametrics 提供了单机版本和集群版本,那么对于不同的版本,Victoriametrics 是如何实现高可用的?

单机版

对于单机版,可以部署两个相同配置的 VictoriaMetrics 实例,监控指标数据可以同时发到着两个实例,当其中一个 VictoriaMetrics 实例挂了可以迅速切换到另外一个实例,从而实现高可用

集群版

对于集群版本,有比较多的组件,不同组件的高可用保障如下:

  • vlselect 多节点无状态部署
  • vlinsert 多节点无状态部署
  • vlstorage 多节点部署,只要还有一个节点存活,写入理论上不影响,查询则可以通过复制写入解决

写入时开启复制:

vminsert 启动时指定 -replicationFactor=N 参数,其中 N 表示数据复制多少份到 vmstorage 节点,最多有 N-1 个 vmstorage 节点挂掉时数据不会丢,查询不受影响;注意,vmstorage 必须至少有 2*N-1 个节点。

查询时的去重规则:

-dedup.minScrapeInterval 参数不为0时, vlselect 会在这个参数值指定的时间范围内保留重复最大的timestmap,若时间戳相同则保留最大值。

另外,vlselect 同样也需要指定 -replicationFactor=N 参数,这样在不超过 N-1 个vmstorage 节点挂掉时,vmselect 会认为数据没有丢并正常返回数据,否则将在返回的数据中打上 partial 的标记(需要开启partial,否则 vlselect 直接返回错误)

高可用缺陷

Victoriametrics 的集群版虽然有以上的高可用保障,但目前存在以下缺陷:

  • vmstorage 节点没有自动数据平衡,当集群新增 vmstorage 节点后,旧的 vmstorage 节点不会将数据自动迁移到新的 vmstorage 节点上,根据 Victoriametrics 官方的文档说明,表示这样做会在数据同步阶段增加集群的负载,降低了集群的稳定性。个人的看法是,数据同步确实存在这样的风险,其实可以参考 pulsar 的 bookkeeper,vminsert 在发送数据时可以感知 vmstorage 的存储空间或者负载情况等,自动将数据发送到存储充足或负载较低的 vmstorage 节点。目前 Victoriametrics 只能靠人工手动去调整数据写入均衡和负载均衡比较不方便,也容易出问题

  • 缺乏自动的复制数据恢复,例如数据分别复制两份数据到两个节点,其中一个节点挂了,虽然可以到另外一个节点上查询,但假设挂掉的那个节点上的数据永久损坏且无法恢复,Victoriametrics 不会自动恢复复制数据集。目前 Victoriametrics 没有记录复制数据的元数据信息,因此个人认为以目前的架构难以实现复制数据的自动恢复,如果引入第三方元数据存储中心例如 Zookeeper 或者 etcd 等则会加大集群的复杂度。

其他问题

问题:vmstorage滚动更新时,集群负载比较高

原因:Victoriametrics 写入使用一致性哈希算法,指标会被固定写入到某个 vmstorage 节点,当 vmstorage 重启或者故障时,该节点的数据会写到另外的storage节点,节点接收这些新数据时需要重新注册和处理等,负载会变高。

如果只是单纯的重启如滚动更新等场景,官方提出了两种解决方法:

  1. vminsert 设置 -disableReroutingOnUnavailable=true,当 vminsert 检测到节点故障时,不会将数据重新路由到其他节点
  2. vmstorage 设置 -storage.vminsertConnsShutdownDuration 值,vmstorage 重启时会在这个时间内依次断开 vminsert 节点,中间会进行sleep