Grafana Labs Mimir 是 AGPLv3 许可下的新时间序列数据库。工程团队做得很好,充分利用了 Cortex TSDB,降低了它的复杂性,同时提高了可扩展性。
根据 Grafana Labs 的测试,Mimir 可以扩展到十亿个活动时间序列和 5000 万个样本/秒的摄取率。该基准测试需要运行一个具有 7,000 个 CPU 内核和 30 TiB RAM 的集群,这使其成为我所听说的最大和最昂贵的时间序列数据库公共基准测试。做得好!
重现如此规模的基准并不容易。幸运的是,在大多数情况下,用户的工作负载要求要低得多,更容易模拟。在这篇博文中,我将尝试比较 VictoriaMetrics 和 Grafana Mimir 集群在相同硬件上在中等工作负载下运行的性能和资源使用情况。
方法
比较两种不同的产品最复杂的事情是保持透明和公正。特别是当您非常熟悉一种产品而对另一种产品完全陌生时。非常感谢 Mimir 的工程团队,我们在准备此基准时联系了他们。他们愿意并开放地回答与产品相关的问题并解释实施细节,这非常值得赞赏并且非常有帮助。
VictoriaMetrics 和 Grafana Mimir 是时间序列数据库,支持大部分相同的协议和 API。但是,它们具有不同的体系结构和组件,这使得比较更加复杂。在基准测试中,我将使用有限数量的资源,并尽我所能将它们分配给两个集群。
然后,我将运行一轮基准测试,看看这两种解决方案如何处理相同的工作负载,以及它们使用分配的资源的效率如何。
基准测试将在 Google Kubernetes Engine 中运行,该引擎由 e2-standard-16 节点(每个节点有 16 个 vCPU 和 64GiB 内存)和基于标准 SSD 的持久卷组成。
Prometheus-基准测试工具
为了生成负载,我将使用 Prometheus-benchmark 工具。它在 VictoriaMetrics 内部用于测试和基准测试新版本。我认为,由于以下原因,该工具会产生类似生产的工作负载:
●作为摄取指标的来源,它使用真实的 node_exporter 目标,这通常是大多数生产环境的情况;
●作为读取查询的来源,它使用推荐的 node_exporter 警报规则列表;
●非零指标流失率会产生额外的压力,模拟在 Kubernetes 中定期重新部署 pod 的场景。 Benchmark 运行两个相同的隔离服务集。它们中的每一个都被配置为抓取指标,通过远程写入将它们转发到配置的存储,并定期执行警报规则。基准测试的配置如下:
# how frequently to scrape node_exporter targets
scrapeInterval: 15s
# how often to execute configured rules
queryInterval: 15s
# defines the number of node_exporter instances to scrape
targetsCount: 6000
# percent of node_exporter targets to update
# in order to generate series churn rate
scrapeConfigUpdatePercent: 1
# specifies how frequently to update targets
# for generating time series churn rate
scrapeConfigUpdateInterval: 10m
基准测试中的每个 node_exporter 目标生成大约 900 个(取决于运行 node_exporter 的硬件)时间序列。 targetsCount=6000 和 scrapeInterval=15s 以 360k 样本/秒的摄取速率生成大约 550 万个活动系列到每个配置的远程存储。配置的警报列表的 queryInterval=15s 通过即时查询生成大约 1.5 查询/秒的读取负载。 scrapeConfigUpdatePercent=1 和 scrapeConfigUpdateInterval=10m 每 10 分钟生成约 60k 新时间序列的流失率。
Mimir设置
我以前从未使用过 Cortex 或 Mimir,所以开始从这些文档和用于分布式安装的 Helm chart 探索这个项目。其架构如下图:
Mimir 在图中有 7 个不同的组件,给人的第一印象是一个复杂的系统。值得庆幸的是,helm chart 使事情变得更容易,并且还根据有效负载提供了资源分配建议。大工作负载的建议需要大约 140 个 CPU 和 800GB 内存,用于 1000 万个活动系列。对于一个简单的基准测试来说,要求太高了,所以我从面向 100 万个活动系列的小工作负载的推荐配置开始,资源要求约为 30 个 CPU 和 200GB 内存。
通过几次试运行,我意识到推荐的容量规划是相当保守的。小工作量的设置完全能够比这多两倍。通过对组件资源进行一些手动调整,它能够处理更多:
Component | Replicas | CPU | Mem (GiB) |
---|---|---|---|
compactor | 1 | 1.2 | 2 |
distributor | 5 | 2 | 6 |
ingester | 5 | 4 | 25 |
querier | 4 | 2 | 24 |
query-frontend | 1 | 2 | 6 |
store-gateway | 1 | 1 | 6 |
various caches | 1* | 18 | |
Total | 43.2 | 283 |
*1 - helm chart 中大约有 7 个缓存副本和 overrides_exporter,没有明确的限制设置。我假设它们总共消耗 ~1 个 CPU。可以在此处找到舵图值的完整覆盖列表。在测试期间,我不得不突破以下限制:
distributor:
extraArgs:
distributor.ingestion-rate-limit: "10000000000000"
ingester:
extraArgs:
ingester.max-global-series-per-user: "0"
ingester.max-global-series-per-metric: "0"
querier:
extraArgs:
querier.max-fetched-chunks-per-query: "8000000"
mimir:
structuredConfig:
limits:
out_of_order_time_window: 1h
我在此基准测试中使用了 grafana/mimir:2.2.0 版本。
为了监控已部署的设置,我使用了此处列出的仪表板和记录规则。 仪表盘列表非常丰富和详细,但我发现不是很方便,原因如下:
●我没有找到具有全局概览的仪表板,只是为了显示集群是否一切正常;
●仪表板中的某些面板需要部署记录规则,这是有人可能会错过的额外步骤;
●一些面板依赖于带有 cortex_ 前缀和选择器的指标,例如 job=~”(query-frontend.*|cortex|mimir)”。 Cortex 和 Mimir 前缀指标的这种混合起初可能会令人困惑。
总的来说,我发现 Helm 图表非常有用且易于理解。 Mimir 的团队在这里做得很好,让新手更容易安装。
VictoriaMetrics 设置
VictoriaMetrics 集群架构如下所示:
VictoriaMetrics 有 3 种不同类型的组件,也可以通过 helm chart 进行部署。 VictoriaMetrics 集群的组件与 Mimir 的组件及其资源配置文件不同。 虽然 Mimir 的一些组件需要额外的内存,但 VictoriaMetrics 组件需要额外的 CPU。 因此,对于资源分配,我将尽量保持在 Mimir 分配设置的边界内:
Component | Replicas | CPU | Mem (GiB) |
---|---|---|---|
vminsert | 4 | 2 | 4 |
vmselect | 2 | 8 | 16 |
vmstorage | 10 | 2 | 16 |
Total | 44 | 208 |
请注意,我们建议运行具有大量小 vmstorage 节点的集群,而不是运行具有少量大 vmstorage 节点的集群
VictoriaMetrics 资源分配超过 CPU 限制约 1 个核心,并且使用的内存减少了约 80GiB。 可以在此处找到舵图值的完整覆盖列表。
VictoriaMetrics 配置了 -replicationFactor=2,这与 Mimir 的默认复制因子不同。 这是 VictoriaMetrics 的推荐值,稍后将详细介绍。
我在此基准测试中使用了版本 VictoriaMetrics/VictoriaMetrics:1.80.0-cluster。
VictoriaMetrics 配备了 Grafana 仪表板和用于自我监控的预定义警报规则。
衡量标准
快速统计
●基准测试已运行 24 小时;
●发送给 VictoriaMetrics 和 Mimir 的样本总数约为 310 亿:360K 样本/秒 86400;
●基准测试期间生成的新时间序列总数约为 1360 万:550 万初始序列 + 6K 序列/分钟 60 分钟 * 24。
在使用的基准测试实用程序中,摄取负载由 vmagent 生成。 它公开了许多有用的指标,好奇的读者可以在 Grafana 仪表板快照上调查它们。 根据指标,两个远程存储都可以正常摄取。 没有错误返回,没有数据丢失,每个指标都按预期交付。
如前所述,VictoriaMetrics 和 Mimir 都提供了用于监控的工具和仪表板。 为了在比较统计数据时保持客观,我使用与 Mimir 仪表板中使用的相同的磁盘、内存和 CPU 使用查询来编译新的 Grafana 仪表板。 “摄取率”、“活动时间序列”或“延迟”等面板使用不同的指标,因为它们由每个解决方案的内部组件导出。 此仪表板的快照可在此处获得。 可以在面板的左上角找到有关每个使用的查询的详细信息。
结果
Mimir 和 VictoriaMetrics 都完全能够处理 360k 样本/秒的摄取速率:
VictoriaMetrics 和 Mimir 之间的活动时间序列数量有点不同,因为两种解决方案对它们的计数不同。 由于非零流失率,Mimir 的活动时间序列数量不断增长,并在创建新的 TSDB 块时每 2 小时重置一次。
Ingester 是 Mimir 负责接收和处理写入的组件,将接收到的数据存储在内存中。 这种方法显着减少了写入放大并有助于减少接触磁盘的频率。 但是每 2h(可配置)ingester 需要刷新磁盘上的所有缓冲数据,创建一个新的 TSDB 块并将其上传到对象存储。 此操作对磁盘使用指标有影响:
虽然大多数时候 Mimir 的磁盘 IO 仍然很低,几乎比 VictoriaMetrics 低 2 倍,但每 2 小时 Mimir 开始创建一个 TSDB 块并消耗额外的磁盘资源。
解决方案之间的磁盘空间使用量对于 VictoriaMetrics 为 49GiB,对于 Mimir 为 369GiB。 请注意,该面板仅考虑本地文件系统大小。 Mimir 还使用谷歌云存储进行长期存储,额外占用 149GiB:
gsutil du -sh gs://mimir-bench-tsdb/
149.7 GiB gs://mimir-bench-tsdb
一个重要的注意事项是,默认情况下,ingester 在本地文件系统上最多存储 TSDB 块 24 小时,请参阅 -blocks-storage.tsdb.retention-period。 因此可以显着减少本地文件系统占用的磁盘大小。 但是,在此测试中,只有长期存储占用的空间是 VictoriaMetrics 本地存储的 3 倍。
测试完成后发现了更多细节。 压缩器在多个时间间隔运行压缩作业以合并对象存储中的数据块:默认为 2 小时、12 小时和 24 小时。 由于测试只运行了 24 小时,所以并不是所有的压实工作都会发生。 正确的压缩比较需要运行基准测试多天。
VictoriaMetrics 的 CPU 使用率低于 Mimir 的:
对于好奇的读者,快照包含有关每个 pod CPU 使用率的详细信息。 这些指标再次证明这两种解决方案具有截然不同的体系结构和组件设计。 对于 Mimir,最大的 CPU 用户是摄入者——仅他们一个人就负责平均消耗 13 个 CPU 内核,峰值高达 18 个,利用率达到其极限的 80%。 对于 VictoriaMetrics,大部分 CPU 被 vmselects 使用:平均 7 个 CPU,最高可达 12 个 CPU 内核,利用率达到其限制的 70%。 平均而言,在此基准测试中,VictoriaMetrics 消耗的 CPU 比 Mimir 少 1.7 倍。
Mimir 和 VictoriaMetrics 之间的内存使用也不同:
在此基准测试中,与 Mimir 相比,VictoriaMetrics 使用的内存大约少 5 倍。 可以在快照中找到组件之间更详细的比较。 最有价值的收获是 Mimir 的摄取器运行非常接近极限,利用率为 80-90%。 这意味着进一步增加负载可能会导致 OOM 异常。
读取查询的延迟具有以下统计信息:
如前所述,读取负载仅包含即时查询,并由执行 node_exporter 指标警报规则的外部标尺生成。 规则列表包含涉及数小时数据的轻量级查询和重型查询。 这会影响延迟,使两种解决方案的第 50 个百分位数都在 100 到 500 毫秒之间。 但是第 99 个百分位数对于 Mimir 来说最多达到 47 秒,对于 VictoriaMetrics 来说最多达到 20 秒。
我没有在这个基准测试中测试范围查询, 这是将来可以运行的一个很好的测试用例。