VictoriaLogs 与 Loki、Elasticsearch、OpenSearch、SigNoz 及 ClickStack 在结构化日志摄取方面的对比

Lobsters Hottest 新闻

摘要

VictoriaMetrics 发布了一份开源基准测试,在相同的单节点硬件上对比了 VictoriaLogs、Loki、Elasticsearch、OpenSearch、SigNoz 和 ClickStack 的结构化日志摄取性能及内部实现,重点分析了摄取速度、查询延迟和磁盘占用之间的权衡。

<p><a href="https://lobste.rs/s/76otqu/victorialogs_vs_loki_elasticsearch">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/10/30 09:12

# VictoriaLogs 与 Loki、Elasticsearch、OpenSearch、SigNoz、ClickStack 在结构化日志写入方面的对比 来源:https://victoriametrics.com/blog/structured-log-ingestion-benchmark/index.html 在 VictoriaMetrics,我们持续为产品进行基准测试。这帮助我们保持竞争力,并让每次发布变得更好。随着 VictoriaLogs 被越来越多的团队使用,更多人向我们询问它适合哪些场景,以及切换到它能带来哪些收益。因此,我们将基准测试以[公开仓库](https://github.com/VictoriaMetrics/logs-benchmark)的形式发布,任何人都可以运行以复现我们的结果,我们也会持续在公开环境下开发它。 这不是一篇营销文章,不会告诉你在所有场景下都应该切换到 VictoriaLogs。相反,如果你收集结构化日志——无论来自 Kubernetes 还是其他来源——本文将帮助你选择合适的工具,并找到适合你的权衡方案。 比较不同系统的基准测试总是有争议的,因为每个系统在不同的场景下各有优势。本文只测试一种场景:写入结构化日志,即每一行都包含命名字段的日志,就像 Kubernetes 上许多服务写入的日志那样。每个系统都运行在一台相同配置的机器上。查询性能、集群模式和对象存储将在后续文章中介绍。 仅凭写入速度并不能告诉你应该选择哪个系统,因此本文还深入分析了它们的内部机制: - 为什么 Loki 写入量最大,但一个简单的仪表盘查询却要花好几分钟? - 为什么 SigNoz 和 ClickStack 落后于 VictoriaLogs,尽管这三者都以列式存储日志? - 为什么 Elasticsearch 和 OpenSearch 需要这么多磁盘空间? 这些答案将帮助你规划硬件和成本,并在日志增长时避免意外。 ## 测试与环境配置 {#the-test-and-the-setup} 我们测试了截至 2026 年 10 月的 6 个系统的最新版本,设置接近默认配置: - [VictoriaLogs v1.53.0](https://github.com/VictoriaMetrics/VistaLogs/releases/tag/v1.53.0) - [Loki 3.7.8](https://github.com/grafana/loki/releases/tag/v3.7.8) - [Elasticsearch 9.5.5](https://github.com/elastic/elasticsearch/releases/tag/v9.5.5) - [OpenSearch 3.9.0](https://github.com/opensearch-project/OpenSearch/releases/tag/v3.9.0) - [SigNoz v0.145.0](https://github.com/SigNoz/signoz/releases/tag/v0.145.0) - [ClickStack 2.39.1](https://github.com/hyperdxio/hyperdx/releases/tag/%40hyperdx/app%402.39.1) 我们修改了一些设置,使每个系统能够在单节点上发挥其设计的最大能力,例如 Loki 的写入限制。VictoriaLogs 无需任何修改,因为它被设计为开箱即用即可发挥最佳性能([文档](https://docs.victoriametrics.com/victorialogs/#tuning))。[仓库](https://github.com/VictoriaMetrics/logs-benchmark/tree/main/deploy/systems)中解释了每一处修改。 为了简化测试,每个系统都以单节点模式运行在各自的 Kubernetes 节点上(GCP 上的 n2d-standard-8,配备 8 vCPU 和 32 GB 内存)。SigNoz 和 ClickStack 将日志存储在 ClickHouse 中,而 ClickHouse 本身无法直接接收日志采集器的数据。因此每套栈都在与 ClickHouse 同一台节点上运行自己的采集器,该采集器基于 OpenTelemetry collector 构建。 测试环境:一个写入器将相同的日志发送给 6 个系统。 (https://victoriametrics.com/blog/structured-log-ingestion-benchmark/setup.webp) 我们同时向每个系统发送相同的日志。速率从 10k 行/秒开始,每 10 分钟增加 10k,最高到 180k 行/秒。一个系统的最大写入速率是它在一个完整的 10 分钟阶段中成功存储的最高速率的平均值。如果某个系统崩溃,我们只计算其首次崩溃之前的阶段,因为崩溃即为其极限。 如何读取最大写入速率。 (https://victoriametrics.com/blog/structured-log-ingestion-benchmark/ramp.webp) 我们统计的是每个系统实际存储的行数,而不是它接受的行数。例如,SigNoz 和 ClickStack 在采集器接收到行后立即响应,因此采集器崩溃会导致已接受的行丢失。Loki 是例外。它没有廉价的方式来统计已存储的行数,但它在响应之前会将每一行写入预写日志(write-ahead log),因此对于 Loki,我们统计的是已接受的行数。 写入速率只是故事的一半。为了展示它与查询速度的关系,我们以 35k 行/秒的速度向 VictoriaLogs、Elasticsearch 和 Loki 写入相同的日志,持续 4 小时,然后在冷缓存条件下对它们执行几个常见查询并计时。我们将在后续文章中深入探讨查询性能。 ## 每个系统接收的负载 {#the-workload-that-each-system-receives} 日志可以是任何形态,从纯文本到包含数百个字段的宽事件。本次测试选取了中间水平——包含 30 到 40 个字段的结构化日志行,这在 Kubernetes 中很典型。应用写入其中约 20 到 30 个字段,日志采集器再补充约 10 个字段,如命名空间、节点和标签。 想象一个 125 个节点的 Kubernetes 集群,每个节点运行着 40 个不同应用的 Pod。每个 Pod 的日志构成一个日志流,因此这个集群共有 5,000 个日志流。这是一个中等规模的集群,与我们在 VictoriaLogs 用户中见到的许多集群类似。 测试中的一条日志行,字段按变化频率分组。 (https://victoriametrics.com/blog/structured-log-ingestion-benchmark/workload.webp) 我们希望看到每个系统凭借自身设计能走多远。因此,每个系统接收的是其偏好的格式。例如,Loki 通常从 Grafana Alloy 接收 protobuf。我们不会向所有系统发送相同的格式(如 OTLP)。如果这样做,我们测量的将不仅是它们存储日志的方式,还包括它们对该格式的转换能力。 在实际中,日志通常以 JSON 形式出现在 stdout 上。因此日志采集器需要进行转换,这同样消耗 CPU。如果有足够多的读者提出需求,我们也可以用一种通用格式(如 JSON 或 OTLP)来运行测试。 ## 测试结果 {#results} 我们运行了 3 次主要的写入测试,以下是 3 次运行结果的中位数。完整表格见[仓库](https://github.com/VictoriaMetrics/logs-benchmark/tree/main/results/2026-10-ingest)。 对于 SigNoz 和 ClickStack,CPU 和内存包含了采集器、ClickHouse 及其辅助服务。 本文中提到的一些额外测试(如查询)是仓库之外的一次性运行。 ### 最大写入速率(行/秒) {#maximum-ingestion-rate-liness} 每个系统的最大写入速率。 (https://victoriametrics.com/blog/structured-log-ingestion-benchmark/max-rate.webp) - **Loki** 写入量最高,达到 139k 行/秒。 - **VictoriaLogs** 位居第二,达到 120k 行/秒。 - **Elasticsearch、OpenSearch 和 ClickStack** 达到 28k 至 48k 行/秒。 - **SigNoz** 达到 10k 行/秒,并在 20k 时崩溃。 一行日志约 930 字节的 JSON,因此 120k 行/秒约为 106 MiB/秒,或约每天 9 TiB 的原始日志。 这些数字中的每一个都伴随着查询速度、成本或日志类型方面的权衡。我们在[为什么结果呈现如此表现](https://victoriametrics.com/blog/structured-log-ingestion-benchmark/index.html#why-the-results-look-this-way)中进行解释。 ### CPU 使用率(核) {#cpu-usage-cores} 各写入速率下的平均 CPU 核数。每条线在系统的最大写入速率处结束。 各写入速率下的 CPU 使用率。 (https://victoriametrics.com/blog/structured-log-ingestion-benchmark/cpu-by-rate2.webp) - 在 10k 行/秒时(所有系统都能处理的唯一速率),**VictoriaLogs 和 Loki** 使用 0.4 核,**ClickStack** 0.9 核,**Elasticsearch** 1.0 核,**OpenSearch** 1.5 核,**SigNoz** 4.2 核。 - 差距随速率增大而扩大。在 40k 行/秒时,**VictoriaLogs 和 Loki** 使用 1.6 核,**ClickStack** 4.0 核,**Elasticsearch** 5.2 核。 - 在 120k 行/秒时,**Loki** 使用 6.1 核,**VictoriaLogs** 使用 7.2 核。 在本次测试中,大多数系统的瓶颈在于 CPU。 ### 内存使用(GiB) {#memory-usage-gib} 各写入速率下的峰值内存(不含操作系统页缓存)。每条线在系统能跟上的最后一个速率处结束。 各写入速率下的内存使用情况。 (https://victoriametrics.com/blog/structured-log-ingestion-benchmark/memory-by-rate.webp) - **VictoriaLogs** 在所有速率下使用的内存都最少,在 40k 行/秒时比 Loki 少 14 倍。 - **Elasticsearch 和 OpenSearch** 无论速率如何都使用约 17 GiB 内存,因为它们在启动时会预留固定大小的堆。默认情况下,Elasticsearch 将其设置为机器内存的一半([源代码](https://github.com/elastic/elasticsearch/blob/v9.5.5/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/MachineDependentHeap.java#L128-L143))。OpenSearch 不会自动调整大小,因此我们为其设置了相同的大小。 - **ClickStack** 在 10k 行/秒时使用 1.3 GiB,在 40k 行/秒时使用 2.2 GiB。 - **SigNoz** 在 10k 行/秒时使用 3.1 GiB,这是它在图表上的唯一数据点。 内存决定了机器需要多大、成本有多高,以及还有多少内存可用于缓存和查询。 ### 磁盘空间 {#disk-space} 此图表显示每个系统存储一百万条日志行所需的磁盘空间。作为参考,一百万行日志以原始 JSON 形式约占 887 MiB。SigNoz 的数据为 N/A,因为其采集器不断崩溃,存储的行数太少,且各次运行之间数据变化太大,无法进行比较。 每百万行日志所需的磁盘空间。 (https://victoriametrics.com/blog/structured-log-ingestion-benchmark/disk-space.webp) - **VictoriaLogs** 需要的磁盘空间最少,其次是 **ClickStack** 和 **Loki**。 - **Elasticsearch** 需要的空间几乎是 VictoriaLogs 的 5 倍,**OpenSearch** 则是 10 倍。 日志通常会保留数周,因此磁盘空间增长迅速。例如,50k 行/秒的日志持续 30 天,在 VictoriaLogs 中约占 7 TiB,在 Loki 中约 12 TiB,在 Elasticsearch 中约 33 TiB。 ### 磁盘写入量 {#disk-writes} 此表格显示每个系统为每条存储的日志行写入磁盘的字节数。这比最终磁盘占用空间大,因为每个系统都会定期重写数据以保持紧凑并加快搜索速度。N/A 表示该系统无法跟上该速率。 | 系统 | 10k | 20k | 40k | 80k | 120k | 150k | |---|---|---|---|---|---|---| | Loki (protobuf) | 1,108 | 1,234 | 1,411 | 1,251 | 1,210 | N/A | | VictoriaLogs | 323 | 284 | 226 | 223 | 163 | N/A | | Elasticsearch | 1,393 | 1,815 | 1,917 | N/A | N/A | N/A | | OpenSearch | 2,295 | 3,197 | N/A | N/A | N/A | N/A | | SigNoz | 1,420 | N/A | N/A | N/A | N/A | N/A | | ClickStack | 414 | 461 | 572 | N/A | N/A | N/A | **VictoriaLogs** 每行写入磁盘的数据也最少,而且在更高速率下写入量更少,因为它在一次性写入更多行时压缩效果更好。Loki 每行写入量是其 3 到 7 倍,具体取决于速率。 这一点很重要,因为每块磁盘每秒能写入的字节数都有上限,而更快的磁盘更贵。在我们的测试中,使用的是 GCP 上 500 GiB 的 pd-balanced 磁盘,最高可写入 280 MiB/s,因此没有系统在用完 CPU 之前达到该上限。尽管如此,VictoriaLogs 让你可以使用更便宜的磁盘,而在你自己的硬件上,它也能大幅减缓 SSD 的磨损速度。 ## 为什么结果呈现如此表现 {#why-the-results-look-this-way} ### Loki {#loki} Loki 的高写入速率让我们感到意外,但其设计可以解释这一点。Loki 专为存储大量日志并随后在短时间范围内读取少量日志流而构建。因此它只对日志流标签(此处为节点和应用)建立索引,并将每行日志原样存储。相比之下,VictoriaLogs 将每一行拆分为字段并单独存储每个字段,这样后续查询更快。这使得它在 120k 行/秒时比 Loki 多消耗约 18% 的 CPU。 你发送日志给 Loki 的方式也很重要。Grafana Alloy 和 Vector 默认发送 protobuf,但 Fluent Bit、Fluentd 和 Logstash 发送 JSON。使用 JSON 时,Loki 在一次单独的测试中达到约 99k 行/秒,低于 VictoriaLogs,因为处理 JSON 比 protobuf 消耗多得多的 CPU。所以如果你运行 Loki,建议优先使用 Alloy 或 Vector。 Loki 的设计带来 3 个代价。第一个代价是内存。Loki 将每个日志流的最新行保留在内存中,以便将它们一起压缩。这意味着其内存随日志流数量增长。更大的集群会有更多日志流,而在任何集群的部署期间,每个新 Pod 都会创建一个新的日志流。为了了解这需要多少内存,我们还用 10,000 和 15,000 个日志流运行了测试。 Loki 和 VictoriaLogs 在 5,000、10,000 和 15,000 个日志流下的对比。 (https://victoriametrics.com/blog/structured-log-ingestion-benchmark/loki-streams.webp) 在 15,000 个日志流时,Loki 在 60k 行/秒时内存耗尽并被终止。VictoriaLogs 在日志流数量是其 3 倍的情况下仅多需要 0.2 GiB 内存。更多内存意味着需要更大的机器,也意味着可用于缓存查询数据的内存更少。 第二个代价是磁盘。Loki 将日志行作为纯文本压缩。它没有像 VictoriaLogs 和 ClickHouse 那样利用日志行内部的字段来实现更好的压缩,因此需要比 VictoriaLogs 多 1.8 倍的磁盘空间。 第三个代价,也是最重要的,是查询时间。Loki 只能通过标签缩小查询范围。其他任何条件——一个词或一个字段值——都意味着需要解压并扫描匹配日志流的每一行。在相同的日志上,[配置部分](https://victoriametrics.com/blog/structured-log-ingestion-benchmark/index.html#the-test-and-the-setup)中的查询耗时如下: | 查询 | 时间范围 | VictoriaLogs(秒) | Loki(秒) | |---|---|---|---| | 统计一个应用的错误数 | 1 小时 | 0.06 | 3.5 | | 统计所有应用的错误数 | 1 小时 | 0.59 | 171 | | 包含某个常见词的最新 100 行 | 1 小时 | 2.5 | 32 | | 所有应用的 p99 延迟 | 1 小时 | 1.9 | 302 | | 请求路径 Top 10 | 1 小时 | 8.8 | 拒绝,超过 500 个序列 | 这些是调查事故或构建仪表盘和告警时的日常问题。除了第一个查询外,Loki 在所有查询上都花了半分钟或更长时间,或者拒绝回答。第一个查询仅通过标签读取一个应用,即便如此也比 VictoriaLogs 慢近 60 倍。 Loki 正在添加更快搜索字段的方式,例如布隆过滤器(bloom filter),但它们仍处于实验阶段,默认关闭,且在单节点上不可用,因此我们没有启用。 这些慢查询并不意味着 Loki 不适合日志场景。它的设计目标是以低成本将日志存储在对象存储中,并在需要运行大型查询时通过多个查询工作节点横向扩展。在我们的单台机器上,它用约 8 核中的一半在 171 秒内统计完一个小时内所有应用的错误。粗略估算,要在约 2 秒内完成相同的扫描,大约需要 300 个核。因此,如果你想以低成本将大量日志存储在对象存储中,并且要么只读取其中一小部分,要么能够负担多个核来快速搜索,Loki 适合你。 如果你不想付出这么多成本,同时又需要仪表盘和搜索在几秒内响应,请继续往下读。 ### Elasticsearch 和 OpenSearch {#elasticsearch-and-opensearch} OpenSearch 是 Elasticsearch 的分支,因此本节主要介绍 Elasticsearch,最后说明 OpenSearch 的差异。 Loki 几乎不建立任何索引,并在查询时为此付出代价。Elasticsearch 则相反。它以 3 种形式存储每一行: - 该行的**原始 JSON**。 - ……

相似文章

@XAMTO_AI: OpenObserve 在圈子里炸了,基于 Rust 的可观测平台,专门收拾那些贵得离谱的日志工具。AGPL-3.0 协议,单文件部署,几分钟搞定。 存储成本暴降 140 倍:Parquet + S3 架构,占用小到夸张 全打包:日志、指…

X AI KOLs Timeline

OpenObserve 是一个基于 Rust 的开源可观测平台,支持日志、指标、链路追踪和 RUM,存储成本比 Elasticsearch 低 140 倍,单文件即可部署,是 Datadog 的开源替代方案。

ClickHouse 正在赢得可观测性之战

Lobsters Hottest

本文认为,ClickHouse 凭借其处理高吞吐量、时序日志的性能优势,解决了长期以来日志管理的痛点,从而成为可观测性领域的主流数据库。