绝对的说法都是错误的。

VictoriaMetrics 一些不应该被忽视的细节

VictoriaMetrics 可以作为 Prometheus 完整功能上的替代品(非 100% 兼容),官方的卖点是 Scalable, Reliable, Easy-to-Use & Cost-Efficient,作者之前也出过一些以性能著称的 golang 代码库。作为 Prometheus 的替代品尝试解决很多 Prometheus 已存在的问题,实现了一些对于 Prometheus 来讲可能是 “Out of Scope” 的功能,完整的功能特性可以参考 官网文档

有这样的开源系统出现来解决一些问题是非常好的事情,让大家有了更多的选择,我们肯定是要怀着感恩之心的。但还是要有自己的判断避免轻易被人带节奏,现在也能看到国内有越来越多的厂在用 VictoriaMetrics,没别的意思,这篇文章主要分享一些 VictoriaMetrics 技术实现上鲜为人知(或者大家不关心)的问题,希望可以以此来更好更全面的认识 VictoriaMetrics,至于技术选型各位看完后自行判断,一个系统有什么功能特性不重要重要的是业务场景上需不需要重不重要。

VictoriaMetrics 当前版本为 v1.80.0。

WAL

没有 WAL,非正常停机有较大的丢数据的风险,有意思的是作者写了一篇为什么 WAL 不适合时序数据库的文章,个人觉得这些观点本身不是很站得住脚评论也有质疑比如刷盘并不是只由上层应用主动触发,文章里面提到的 ClickHouse 应该也是默认开启 WAL 的

当然不排除很多场景下没有 WAL 是可接受的,从另一方面来讲多副本也可以一定程度上提高可靠性,但 WAL 可以从更大程度上提高可靠性,对比其它产品少这么个特性可能就少了一个 9,个人以为 WAL 至少应该是可选的。

数据完整性校验

没有存储任何用于数据完整性校验的信息,使用的压缩算法如 zstd 也没有开启数据校验选项,看这行代码也是出于性能考虑故意的,个人觉得这算是一个存储系统设计上的缺陷了至少要有个口子不是,数据损坏并不是那么遥不可及,而给用户错误的数据要比没有数据更不可接受,目前可用的解决方案及相关讨论可以参见我提的这个 Issue: Checksum functionality is missing

异步写 + 内存临时批量缓冲

存储层组件 vmstorage 接受到的最新写入的数据都会先临时放在内存里面,然后定时定量写盘持久化,临时缓冲的数据有些是无法被查询到的(写入成功的数据可能无法被立即查询到)。代理层组件 vminsert 也是会批量缓存再异步写入数据到存储层,数据可能只在应用层面的内存做缓冲然后就给上层写调用返回成功了。

VictoriaMetrics 写入路径上都是这种异步加批量缓冲的模式,一批量多个请求的数据只有最后一个请求能真实得到这一批量写入是否成功的反馈,而这一批量请求互相无感知没有上下文关系(不同层面的组件将让这种关系进一步撕裂开来),这种方式提供的用户接口以个人有限的经验来看是极其不友好的,中间没有高可用的队列来存储数据,写入失败又不能及时得到反馈无法进行及时有效的退避或者重试从而导致数据丢失,丢数据是可以的默默的丢掉部分不太合适。当然内部组件间有重试逻辑正常情况下是有用的。

这篇文章里面介绍了存储层参考了 ClickHouse 的实现,可能是出于性能上的考虑 VictoriaMetrics 选择阉割掉了严格保证数据可靠性的那一部分。

扩缩容/雪崩

存储层组件 vmstorage 扩缩容需要重启所有的写入层代理组件 vminsert 以及所有的查询层计算组件 vmselect,因为不支持自动服务发现,有人也提了 Issue,解决方案肯定是有的无非是会增加复杂度但是个人觉得是值得的,带来的问题是扩缩容各个组件相互感知时间可能较长,集群规模较大或者紧急情况下基本的读写可用性可能都无法有效保障。

VictoriaMetrics 写入会重试所有节点直到写入成功,再结合以上异步加批量缓冲的模式,可以发挥一点想象某个节点挂掉理论上是比较容易引起雪崩的(存储层现在有 maxHourlySeries 这种启动时配置某种维度上可作为单节点的一个自保护手段)。

当然增加足够多的节点和资源也可以一定程度上规避雪崩的问题,参考官方推荐

  • 50% of free RAM across all the node types for reducing the probability of OOM (out of memory) crashes and slowdowns during temporary spikes in workload.
  • 50% of spare CPU across all the node types for reducing the probability of slowdowns during temporary spikes in workload.

可维护性/兼容性

VictoriaMetrics 目前的架构相对而言没那么复杂,所以理论上运维复杂度应该还行。

看过 VictoriaMetrics 的部分代码实现,我可以不负责任的说有点暴力,写起来应该挺爽阅读体验一般,比如很多全局的状态以及硬编码的参数,再比如为了性能做了很多优化可能开发过程中心智负担也不低当然这种优化是无法彻底避免的,性能优化很多时候其实做的是脏活累活,所以代码层面的可维护性个人觉得一般。

设计上考虑欠佳自造的内部协议格式扩展性较差也没有版本概念比如可能与此相关的 v1.78.0 不兼容的改了内部通信协议,升级完成之前查询无法正常工作,这其实是增加变更复杂度和心智负担的。

当然项目主页上也提到了发版迭代很快的,请仔细阅读文档。

最后

VictoriaMetrics 崇尚简单,对高性能低成本的追求是值得称赞的,但是好像是一个充满青春活力的孩子,让一切都发生得太快了,比如出于性能考虑而不留余地的牺牲掉一些可靠性,这种或者上面提到的设计上存在不严谨的地方后续只能通过增加复杂性或者牺牲兼容性的方式来弥补,说到现实情况很多用户对监控没有很多要求作为旁路系统一般情况能用就好但可能有一点是成本要低又不想把自己的手弄脏不愿意根据业务场景做一些数据梳理的工作如此看来 VictoriaMetrics 有点东西的。与 VictoriaMetrics 作为对比,Prometheus 及其部分衍生项目问题也不少,有一些大家都有的共性问题,有资源开销的问题,还有很多设计如此或者 “Out of Scope” 的问题,但个人觉得 Prometheus 及其部分衍生项目毕竟发展时间更长很多基础的细节处理上会显得更成熟稳重些。

没有最好的系统只有最合适的系统。用最合适的系统干最合适的事。