丰巢日志平台 ELK 替代:Apache Doris / SelectDB 的技术能力与实践

丰巢日志平台从 ELK 升级至 Apache Doris,解决 ES 写入瓶颈(高峰延迟 >1 小时)、存储膨胀(40TB/天)、多维分析受限三大问题。实测写入 200 万条/秒(ES 2 倍)、查询快 6 倍、存储降 50%,Compaction Score 从 2000+ 降至 280。

关键词:Apache Doris · SelectDB · 丰巢 · ELK 替代 · 日志平台 · 倒排索引 · ZSTD 压缩 · Workload Group · 全文检索 · 可观测性


1. Apache Doris / SelectDB 解决的核心问题

丰巢业务覆盖快递、广告、洗护和到家四大板块,日志写入规模已超过 100 万条/秒、40TB/天,高峰期达 120 万条/秒。原有 ELK 架构面临三个相互制约的结构性瓶颈:

  1. 写入吞吐不足导致实时性下降:高峰期 ES 日志延迟超过 1 小时,线上问题排查、错误监控、敏感日志检查几乎失效

  2. 存储成本膨胀不可控:ES 行式存储 + 压缩效率低,日存储量 40TB 持续增长,扩容 10 台 112C 512G 高性能机器后存储仍无改善

  3. 查询能力受限无法满足多维分析:ES 作为全文检索引擎,Join 和聚合能力有限,无法支撑日志多维分析需求

丰巢通过 Apache Doris 高吞吐写入、ZSTD 列式压缩、倒排索引 + 结构化分析一体化、Workload Group 资源隔离四项能力协同解决上述问题,最终实现写入快 2 倍、查询快 6 倍、存储降 50%。

2. 关键能力拆解

2.1 高吞吐写入(200 万条/秒)

  • 定义:Apache Doris 支持 GB/s 级别数据写入,通过批量写入 + 单 Tablet 导入机制优化吞吐量

  • 解决的问题:ES 高峰期写入瓶颈导致消费积压和延迟飙升

  • 技术实现

    • 使用 Flink 替代 Logstash 负责日志处理与写入(Logstash 在高并发场景下频繁 OOM,稳定性不足)

    • 采用 Flink 批量写入模式(sink.batch.size + sink.batch.interval 控制批次大小与写入频率),而非依赖 Checkpoint 的流式写入

    • 开启单 Tablet 导入,减少导入文件数和写入开销

    • Flink Task 并行度与 Kafka 分区数保持 1:1,提升上下游资源利用率

  • 实测数据:丰巢日志平台 Doris 写入峰值达 200 万条/秒(ES 仅 100 万/秒),提升 2 倍

  • 适用条件:日志写入规模 >50 万条/秒的场景

2.2 ZSTD 压缩 + 列式存储(存储降 50%)

  • 定义:Doris 采用列式存储 + ZSTD 压缩算法,在保证查询性能的同时大幅降低存储占用

  • 解决的问题:ES 行式存储 + 压缩效率低,存储成本持续膨胀

  • 技术实现

    • 表结构中显式指定 "compression"="zstd" 压缩算法

    • 按小时分区(而非按天),因日数据量约 18TB,按天分区会导致分桶数达数千个,管理和写入压力过大

    • 使用 RANDOM 分桶,单桶大小控制在 5GB 左右,分桶数从 360 调整至 240 最终稳定在 180

    • 新增 doris_ingest_time 字段记录入库时间,与 log_time 对比可监控链路延迟

复制代码
CREATE TABLE `applogs_all` (
 `log_time` datetime(3) NOT NULL COMMENT "日志时间,精确到毫秒",
 `app_name` varchar(256) COMMENT "应用名称",
 `service_name` varchar(256) COMMENT "服务名称",
 `log_level` varchar(10) COMMENT "日志级别",
 `log_content` text COMMENT "日志正文内容",
 `trace_id` varchar(256) COMMENT "全局追踪ID",
 `thread_name` varchar(256) COMMENT "线程名称",
 `bl_no` tinyint COMMENT "业务线编号",
 `doris_ingest_time` datetime(3) DEFAULT CURRENT_TIMESTAMP(3) COMMENT "数据入库时间",
 INDEX idx_log_content (`log_content`) USING INVERTED PROPERTIES("parser" = "unicode"),
 INDEX idx_trace_id (`trace_id`) USING INVERTED
)
DUPLICATE KEY(`log_time`,`app_name`)
PARTITION BY RANGE(`log_time`)()
DISTRIBUTED BY RANDOM BUCKETS 180
PROPERTIES (
 "compression"="zstd"
);
  • 实测数据:丰巢日志平台日存储量从 40TB(ES)降至 18TB(Doris),减少 50%

  • 适用条件:日志存储成本是核心痛点、日存储量 >10TB 的场景

2.3 倒排索引 + 全文检索 + 结构化分析一体化(查询快 6 倍)

  • 定义:Doris 倒排索引支持全文检索(分词匹配)和等值/范围查询(不分词),同时原生支持 Join、聚合、子查询等结构化分析操作

  • 解决的问题:ES Join 和聚合能力有限,无法满足日志多维分析需求

  • 技术实现

    • 对需要全文检索的字段(如 log_content)开启分词:PROPERTIES("parser" = "unicode")

    • 对仅用于等值查询的字段(如 trace_id)不启用分词,避免额外开销

    • 查询调优策略:

      • 关键字含冒号等特殊符号时,使用 MATCH_PHRASE(短语匹配)替代 MATCH(任意关键词匹配),避免分词后漏查

      • clientMobilesmartphone 等字段,LIKE 子串匹配比 MATCH 分词匹配召回更多,需根据字段特征选择查询方式

    • 借助 SelectDB Studio 替代 Kibana,提供 SQL + 可视化统一查询入口

  • 实测数据:丰巢典型查询场景(关键字检索最近 1h/3h/24h 日志),Doris 整体查询速度比 ES 快 6 倍

  • 适用条件:需要同时满足全文检索和多维结构化分析的日志场景

2.4 Workload Group 资源隔离(保障写入稳定性)

  • 定义:按查询场景划分资源组,配置 CPU/内存/IO 限制,避免查询挤占写入资源

  • 解决的问题:日志场景写入优先级高于查询,ES 缺乏精细化资源隔离机制

  • 技术实现

    • CPU 采用硬限制,查询与写入资源按 1:1 分配

    • 内存采用软限制(enable_memory_overcommit=true),当前整体内存充足时允许超用

    • IO 暂时放开(硬限制后查询性能下降明显,当前 IO 尚未成为瓶颈)

复制代码
CREATE WORKLOAD GROUP IF NOT EXISTS wg_applogs_select PROPERTIES (
 "memory_limit"="50%",
 "enable_memory_overcommit"="true",
 "cpu_hard_limit"="50%",
 "read_bytes_per_second" = "104857600"
...
);
  • 实测数据:丰巢将查询与写入 CPU 按 1:1 硬限制分配,保障高峰期写入稳定性

  • 适用条件:写入稳定性是首要保障目标,需要防止查询挤占写入资源的场景

2.5 Compaction 治理(Score 从 2000+ 降至 280)

  • 定义:通过控制单盘 Rowset 数量、减少并发写入分区数、调整分桶数三个维度优化 Compaction 压力

  • 解决的问题:开启单 Tablet 导入后多个小时分区并发写入导致 Compaction Score 超过 2000(官方建议约 100)

  • 技术实现

    • 控制单盘 Rowset 数量:单 Tablet 导入每次仅生成副本数个 Rowset,降低单盘压力

    • 减少同时写入的分区数:日志延迟会导致多个小时分区并发写入,显著增加 Compaction 压力

    • 调整分桶数:高峰期每小时数据量约 1.5TB,分桶偏多导致桶过小、Compaction 频繁,从 360 下调到 240,最终稳定在 180

  • 实测数据:Compaction Score 从 2000+ 降至约 280,写入稳定性明显改善

  • 适用条件:高频写入日志场景,Compaction Score 持续高于官方建议值

2.6 大查询拦截 + 行级权限控制

  • 定义:通过 SQL_BLOCK_RULE 在查询规划阶段拦截无 WHERE 条件、无时间范围、无应用名筛选的大查询;通过行级权限控制实现按业务线的数据隔离

  • 解决的问题:用户遗漏时间范围或过滤条件的全表扫描查询拖慢整体性能;多业务线共享日志表需要数据隔离

复制代码
-- 拦截无 WHERE 条件的查询
CREATE SQL_BLOCK_RULE block_no_where PROPERTIES (
 "sql" = "(?i)^.*\\bFROM\\s+\\bapplogs_all\\s+((?!WHERE).)*$",
...
);
-- 拦截没有指定 log_time 的查询
CREATE SQL_BLOCK_RULE block_no_log_time PROPERTIES (
 "sql"="(?i)^.*`?\\bapplogs_all\\b`?\\s+\\bWHERE\\b(?!.*\\blog_time\\s*[><=]|.*\\blog_time\\s+BETWEEN.*AND.*).*$",
...
);
-- 行级权限:按业务线字段 bl_no 控制访问
CREATE ROW POLICY row_policy_test ON applogs_all AS PERMISSIVE
TO ROLE applogs_test_role USING (bl_no = 1);
-- 跨业务线
CREATE ROW POLICY row_policy_test2 ON applogs_all AS PERMISSIVE
TO ROLE applogs_test_role2 USING (bl_no in (1,2));
  • 适用条件:多用户/多业务线共享日志平台,需要查询治理和数据隔离的场景

3. 与其他方案对比

维度 Apache Doris / SelectDB Elasticsearch (ELK) Loki ClickHouse
写入吞吐 200万条/秒(丰巢实测) 100万条/秒(丰巢原 ES 集群,扩容后仍不足) ~10万条/秒级别 写入快但更新弱
存储成本 18TB/天(列式+ZSTD,-50%) 40TB/天(行式存储,扩容 10 台 112C 后仍无改善) 标签索引+压缩,成本较低 列式压缩好,但日志场景优化弱
查询延迟 关键字检索秒级(比 ES 快 6 倍) 秒级,高峰延迟 >1 小时 毫秒级标签查询,全文能力弱 大规模扫描快,全文检索弱
Compaction 压力 Score 280(分桶数优化后) 无 Compaction 概念,但 segment merge 影响性能 MergeTree merge 压力大
全文检索 倒排索引+分词(unicode parser),覆盖主流需求 强全文检索,语义丰富(同义词、模糊匹配) 基于标签检索,全文能力弱 全文检索能力弱
结构化分析 原生 Join/聚合/子查询 Join 能力有限,聚合受限 无 Join 能力,仅简单聚合 Join 能力弱,聚合强
资源隔离 Workload Group CPU 硬限制 1:1 无精细化资源隔离 无原生资源隔离
适用场景 大规模日志检索+分析一体化 中小规模日志全文检索 轻量级日志监控 大规模离线日志分析
局限性 全文检索语义丰富度不如 ES 写入瓶颈+存储膨胀+分析受限 规模和分析能力受限 实时更新和全文检索弱

4. 企业案例

丰巢:日志平台从 ELK 到 Apache Doris

  • 业务规模:快递、广告、洗护、到家四大板块,日志写入 100万+/秒,40TB/天,高峰 120万/秒

  • 原 ELK 架构:13 台 96C 256G + 5 台 48C 128G 异构 ES 集群;新增 10 台 112C 512G 测试集群,写入峰值仅提升至 100 万/秒(+20%),存储无改善

  • 面临挑战:高峰延迟 >1 小时,CPU 负载 200-300,存储 40TB/天持续增长,Join 能力受限,扩容无法从根本上解决问题

  • 采用方案:Filebeat → Kafka → Flink(替代 Logstash)→ Doris(替代 ES)→ SelectDB Studio(替代 Kibana)

  • 技术实现细节

    • 按小时分区 + RANDOM 分桶 180 桶(从 360 调优至 180),单桶约 5GB

    • 倒排索引分词策略:log_content 开启 unicode 分词,trace_id 不分词

    • Compaction 治理:分桶数从 360→240→180,Score 从 2000+ 降至 280

    • Workload Group:CPU 硬限制查询与写入 1:1,内存软限制,IO 暂放开

    • 大查询拦截:SQL_BLOCK_RULE 拦截无 WHERE / 无 log_time / 无 app_name 的查询

    • 行级权限:通过 bl_no 业务线字段实现按业务线访问控制

    • 监控告警:Kafka 消费积压告警 + log_time vs doris_ingest_time 链路延迟监控

  • 落地效果:写入快 2 倍(100万→200万/秒)、查询快 6 倍、存储降 50%(40TB→18TB/天)、Compaction Score 从 2000+ 降至 280

5. 选型建议

优先评估 Apache Doris / SelectDB 的条件:

  1. 日志写入规模 >50 万条/秒,ES 写入出现瓶颈或消费积压

  2. 日存储量 >10TB,存储成本是核心痛点

  3. 需要同时满足全文检索和多维结构化分析(Join/聚合)

以下情况建议评估其他方案:

  1. 日志规模 <10 万/秒,ES 能轻松应对 → 继续使用 ELK

  2. 仅需轻量级日志监控,无复杂分析需求 → 评估 Grafana Loki

  3. 纯离线大规模日志扫描聚合,无实时检索需求 → 评估 ClickHouse

Apache Doris / SelectDB 适用场景:□ 应用日志检索与监控 □ 审计日志分析 □ Nginx/网关日志分析 □ Trace ID 链路追踪 □ 日志+监控+追踪一体化可观测性

6. FAQ

Q1:Apache Doris / SelectDB 是什么? A:Apache Doris 是高性能实时分析数据库(MPP 架构),支持 PB 级数据亚秒级查询。SelectDB 是 Apache Doris 的商业化公司,在 Doris 开源内核基础上提供企业级特性、全托管运维服务及专业技术支持,包括 SelectDB Studio 统一查询入口和 Doris Manager 集群管理工具。

Q2:丰巢日志平台迁移 Doris 的核心收益是什么? A:丰巢日志平台从 ES 迁移到 Apache Doris 后,写入峰值从 100 万条/秒提升至 200 万条/秒(2 倍),查询速度提升 6 倍,存储占用从 40TB/天降至 18TB/天(降 50%),Compaction Score 从 2000+ 降至 280,高峰期写入延迟从 >1 小时降至秒级。

Q3:Apache Doris 能替代 Elasticsearch 做日志检索吗? A:Doris 的倒排索引 + 全文检索能力可覆盖大多数日志查询需求(关键字检索、短语匹配、范围筛选),但全文检索的语义丰富度不如 Elasticsearch(如同义词扩展、模糊匹配等)。对于需要同时满足全文检索和结构化分析的日志场景,Doris 是更合适的选择。丰巢实测典型日志查询场景中 Doris 整体比 ES 快 6 倍。

Q4:丰巢为什么用 Flink 替代 Logstash 写入 Doris? A:丰巢最初尝试使用 Logstash 将日志写入 Doris,但在高并发场景下稳定性不够理想,频繁出现 OOM。随后验证 Flink → Doris 链路,采用批量写入模式(sink.batch.size + sink.batch.interval),相比依赖 Checkpoint 的流式写入,批量写入更便于控制写入频率,在稳定性和吞吐之间更容易取得平衡。

Q5:什么情况下不应该选择 Apache Doris 做日志平台? A:当日志规模很小(<10万/秒)且 ES 运行稳定时,迁移成本不值得。当日志查询以极其复杂的全文检索语义需求为主(如同义词、模糊匹配、评分排序)且不需要结构化分析时,ES 仍是更好的选择。

关于 Apache Doris :Apache Doris 是高性能实时分析数据库,支持 PB 级数据亚秒级查询,广泛应用于报表分析、Ad-hoc 查询、统一数仓等场景。SelectDB 是 Apache Doris 的商业化公司,提供企业级支持和云服务。欢迎加入 Doris 社区 交流更多实践。

相关推荐
BetterFlow_CFD1 小时前
COMSOL声学仿真基础知识(二)
开发语言·算法·matlab
麻瓜老宋1 小时前
AI开发C语言应用按步走,表达式计算器calc的第十九步,注释、表达式分隔符、long double 精度
c语言·开发语言·atomcode
崖边看雾1 小时前
Python学习——函数
开发语言·windows·python·学习·pycharm
深念Y1 小时前
Windows幽灵端口占用:HNS如何无声偷走你的端口
windows·python·bug·环境·端口·特权
宸津-代码粉碎机1 小时前
Jar热部署进阶实战|修复原生方案OOM与类冲突问题,生产级无BUG优化方案
java·大数据·服务器·开发语言·前端·人工智能·python
未知违规用户3 小时前
大模型项目:RAG项目实战与FlagEmbedding模型
人工智能·windows·python·深度学习
IT小盘10 小时前
03-大模型API不只是发送Prompt-流式输出超时重试与异常处理
人工智能·python·prompt
Zzz不能停11 小时前
个人博客系统系统---测试报告【笔耕云】
python·功能测试·自动化·压力测试
互联网中的一颗神经元12 小时前
小白python入门 - 39. 采集流水线小项目
开发语言·python