想把日志从 Elasticsearch 迁走,厂商自己发的写入压测能信几分?

VictoriaMetrics 在 10 月 29 日发了一篇结构化日志写入的对比,配套的 logs-benchmark 仓库也公开了。仓库 README 里有张路线图:六个系统的单机写入测试标着 done,单机查询测试是 in progress,集群模式和对象存储都还在 planned。正打算换掉 Elasticsearch 的团队,看这类文章之前最好先看看这张表。这份压测回答的只是单机能吞下多少,离换过去以后日常用着顺不顺,还差好几步。

这份压测测了什么

按博客和 README 的说明:

  • 每个系统单节点部署,各占一台 Kubernetes 节点,机型是 GCP 的 n2d-standard-8(8 vCPU、32 GB 内存)。
  • 写入速率从每秒 1 万行起步,每 10 分钟加 1 万,最高到 18 万。成绩按系统实际存下来的行数算,不按接受的请求数算。Loki 没法低成本地数出存下的行数,所以用的是接受数。
  • 日志由程序生成,每行 30 到 40 个字段,平均约 930 字节的 JSON。模拟的是一个 125 个节点、5000 条日志流的集群,生成器用固定种子。
  • 每个系统按自己偏好的格式接收,比如 Loki 收 protobuf,Elasticsearch 和 OpenSearch 收 bulk JSON。
  • 配置尽量贴近默认,每处改动都在 deploy/systems/<engine>.yml 里写了注释。Elasticsearch 用的是 LogsDB 索引模式。
  • 主写入测试跑了 3 次,取中位数。

博客里也贴了几组查询耗时,作者自己说明那是仓库之外的单次测试,查询会在后续文章里专门讲。README 说得更明确:查询数字还没发布,各引擎之间暂时不能拿来比。

写入快和查询快往往互相牵制

写入时少做事,比如只给少量标签建索引、整行原样存,查询时就得解压、扫更多数据。反过来,写入时把每个词、每个字段都建好索引,写入阶段的 CPU 和磁盘就会上去。这是设计取舍,单看写入峰值,看不出你们常用的那些查询会落在哪一头。博客里也承认,这次用的结构化日志正好发挥自家产品的长处。这份数据适合拿来理解各家架构差在哪,选型还是得看自己的查询。

还有一处容易忽略:现实里日志多半先以 JSON 写到 stdout,再由采集端转成各家偏好的格式,这一步要花 CPU。README 里说得很清楚,这部分开销目前没算进去。

自己跑一遍要准备什么

第一个基准的 runbook 在 deploy/benchmarks/all-systems/README.md。跑这个基准要一个带七个节点池的 Kubernetes 集群,六个配置相同的给被测系统,一个更大的给压测程序。完整跑一次大约 4 小时:3 小时加压,再留最多 1 小时等磁盘稳定下来才能读占用。

只想比较现有的 Elasticsearch 和一两个候选的话,能不能只部署其中几个、换成接近生产的机型,要照着 runbook 自己试一下。数据这块,生成器在 internal/source/synthetic/,各家的编码器在 internal/systems/<engine>.go。合成数据再像,字段分布也未必和你们的一样。有条件的话改一下写入端,拿一段脱敏后的真实日志回放,参考价值会高不少。

厂商压测之外还该补的

  • 你们 Dashboard 上最常用的几条查询:按服务数错误、关键词搜索、P99 延迟、Top N 请求路径。README 说写入测试期间不跑查询,所以这些要放在有写入压力的情况下单独测。
  • 保留期内的总磁盘占用:拿自己的日写入量乘保留天数估个总量,另外留意后台合并时的写盘量,云盘的写入带宽是有上限的。
  • 日志流数量变多时的内存:发版高峰会冒出一批新 Pod,流数会跟着跳。
  • 持久性的差别:README 提到 Elasticsearch 和 OpenSearch 默认在应答前 fsync,其他几家应答得更早。关掉 fsync(index.translog.durability: async)后 Elasticsearch 的速率变化不大。生产上要不要这么配,是另一件事。
  • 从现有采集端切到新系统的格式转换成本,以及迁移期双写的开销。

你们换日志存储时,最后是被哪项指标说服的?