我把 ELK 日志栈切到 VictoriaLogs 后,存储成本降了 70%:轻量可观测性改造实录 我把 ELK 日志栈切到 VictoriaLogs 后存储成本降了 70%轻量可观测性改造实录说实话我早就看我们的 ELK 堆栈不顺眼了。倒不是 Elasticsearch 不好用而是它越来越像一个“吞金兽”。三节点数据、一个主节点、Logstash、Kibana光是热数据盘就挂了 45TB SSD。每天 1.5TB 日志进来30 天保留期一卡成本每个月都在账单上跳舞。更要命的是某些全字段检索的查询 P99 能跑到 8 秒以上on-call 同学一边查日志一边骂。上个月我们把 80% 的日志流切到了 VictoriaLogs。迁移后单块存储降了 70%集群节点从 4 台变成 1 台二进制进程查询延迟稳了很多。这篇文章把整个过程、踩的坑和留下的 checklist 记下来给同样被 ELK 账单压得喘不过气的同学参考。背景ELK 为什么成了成本黑洞我们的日志链路比较标准业务服务 → Fluent Bit → Logstash → ElasticsearchKibana 做查询和看板3 个数据节点每个 32C128G挂载 15TB 高性能云盘1 个专用主节点 1 个 Logstash 节点每天大约 1.5TB 原始日志保留 30 天。看起来中规中矩但几个隐藏成本很扎心倒排索引占空间为了支持全文检索ES 对几乎所有字段建索引磁盘占用经常是原始日志的 1.5 倍以上。JVM 内存贵ES 是 Java 堆大户数据节点堆内存配到 64GB 还经常被 GC 警告。分片和节点规划麻烦日志量一涨就要考虑 rollover、索引模板、冷热分层运维成本持续增加。查询慢业务同学爱用message:*timeout*这种 wildcard 搜索数据节点 CPU 直接拉满。我们当时的念头很简单能不能用更轻量的方案只保留我们最需要的日志检索能力选型为什么不是 Loki而是 VictoriaLogs其实 Loki 也考虑过。但 Loki 的 label 设计对我们的日志格式要求比较严格而且当时我们没有 Grafana 全栈迁移成本不低。后来同事推荐了 VictoriaLogs我试了一周发现它有几个特别对我们胃口的地方单二进制一个可执行文件没有 JVM、没有 ZooKeeper、没有复杂集群角色部署简单到离谱。压缩比高它采用列式存储 轻量索引存储占用大概只有 Elasticsearch 的 20%-30%。生态兼容Fluent Bit、Promtail、Vector 都能直接发数据Grafana 有官方数据源插件。查询语言接近 LogQLLogsQL上手很快团队基本不用培训就能写。当然也有取舍复杂全文检索、聚合、嵌套文档支持不如 ES。但我们的日志场景主要是按服务、环境、日志级别过滤然后看时间线和关键字VictoriaLogs 完全够用。迁移三步走没有停服第一步拉起 VictoriaLogs 实例我们用 Docker Compose 部署配置极简services:victorialogs:image:victoriametrics/victoria-logs:v1.5.0-victorialogscontainer_name:victorialogscommand:---storageDataPath/vlogs---retentionPeriod30d---httpListenAddr:9428---memory.allowedPercent60ports:-9428:9428volumes:-/data/vlogs:/vlogsrestart:unless-stopped相比 ES 的一堆 JVM 参数和角色配置这个启动几乎可以说是“解压即用”。我们把数据目录挂到了一块成本更低的 SATA 盘上准备用它扛主要日志流。第二步让 Fluent Bit 双写不想停服所以先让 Fluent Bit双写一份继续给 ES一份给 VictoriaLogs。等 VictoriaLogs 的查询和看板稳定后再逐步关闭 ES 链路。[OUTPUT] Name http Match app.* Host victorialogs Port 9428 URI /insert/jsonline Format json_lines Header Content-Type application/json Header AccountID 0 Header ProjectID 0 json_date_key timestamp json_date_format iso8601这里有几个细节json_date_format一定要统一成iso8601我们刚开始用毫秒时间戳VictoriaLogs 解析后时间戳乱了查了半天。默认按AccountID和ProjectID做多租户隔离header 必须带否则数据会进默认租户。Match规则建议先按app.*分批切不要一次性全切方便回滚。第三步Grafana 数据源和查询改造Grafana 装VictoriaLogs数据源后之前的 Kibana 看板可以逐步迁。最常用的是下面两类查询。按服务查最近 ERROR 日志service:order-service AND level:ERROR AND _time:1h按状态码统计失败请求service:order-service AND status_code:500 AND _time:30m | stats by (status_code) count()做趋势聚合service:payment-service AND level:ERROR | stats by (_time:1m) count()LogsQL 的语法和 LogQL 很像业务同学基本 copy-paste 改改字段名就能用。唯一要适应的是没有 Kibana 那种点选式界面一开始有些人不习惯但写了三天 queries 后都真香了。效果账单和延迟都变了迁移完成一个月后我们对比了主要指标指标迁移前 ELK迁移后 VictoriaLogs30 天日志存储占用45TB13TB数据节点数3 台 32C128G1 台 8C32G全文 wildcard 查询 P998-12s1-3s按 stream 字段过滤查询2-5s200-500ms月度存储计算成本基准 100%约 30%存储成本降了大约 70%主要来自三点VictoriaLogs 的列式压缩和轻量索引让磁盘占用大幅下降。单节点即可顶住我们的日志量省了两台数据节点的计算成本。不需要为全文检索预留大量 JVM 堆内存内存成本也少了。当然这个 70% 是基于我们保留 30 天、以结构化日志为主的场景。如果你的日志全是非结构化文本、需要复杂聚合数字会不一样。踩过的 4 个坑坑 1高基数字段当 stream 字段内存原地爆炸VictoriaLogs 的stream字段类似 Loki 的 label会参与索引。如果直接把trace_id、request_id这种每条日志都不同的字段当 stream 字段内存和查询性能会炸。我们的做法只把service、env、level、host作为 stream 字段高基数字段保留在_msg里用 LogsQL 过滤。service:order-service AND _msg:trace_idabc123 AND _time:1h坑 2时间戳格式不一致导致日志重复或缺失Fluent Bit 默认json_date_format是doubleVictoriaLogs 期望的是秒级 Unix 时间戳或 ISO8601。我们刚开始没统一结果看到同一条日志出现了两次或者某段时间完全空白。统一改成iso8601后问题解决。这个配置建议在迁移前就定好否则后面洗数据很痛苦。坑 3Kibana 的某些聚合看板没法直接平迁VictoriaLogs 不支持 ES 那种多层嵌套聚合和复杂的bucket_script。我们有几个 Kibana 看板需要重新设计改成预聚合指标用 VictoriaMetrics 或自定义 exporter LogsQL 简单统计的方式。经验是不要试图 1:1 复制 Kibana先把最常用的看板迁了其他的慢慢改。坑 4多租户隔离 header 忘记加团队数据串了VictoriaLogs 用AccountID和ProjectIDheader 做租户隔离。我们测试环境忘了加 header结果测试数据混进了生产租户。虽然后来清理了但最好在一开始就通过 Nginx 统一注入 header避免各个客户端自己配置。location /insert/ { proxy_pass http://victorialogs:9428; proxy_set_header AccountID $account_id; proxy_set_header ProjectID $project_id; }写在最后VictoriaLogs 不是银弹。它牺牲了部分全文检索和复杂聚合能力换来了极低的存储和运维成本。如果你的日志场景以“按服务/级别/时间过滤 关键字检索”为主它很可能是比 ELK 更划算的解法。我们现在的策略是80% 的常规应用日志进 VictoriaLogs需要复杂全文检索和安全审计的日志继续留在 Elasticsearch所有新服务默认对接 VictoriaLogs老服务逐步迁移。如果你也在被 ELK 账单追着跑不妨先找一台闲置机器拿一天的日志做下对比测试。数据不会骗人。参考资料VictoriaLogs 官方文档https://docs.victoriametrics.com/victorialogs/Fluent Bit HTTP 输出插件https://docs.fluentbit.io/manual/pipeline/outputs/httpGrafana VictoriaLogs 数据源https://docs.victoriametrics.com/victorialogs/grafana/