日志容量测算笔记:从压缩率、副本数到冷热分层的四次换算
记录一次日志平台的容量测算过程,目标是把「1TB/天 × 30 天」换算成可落地的磁盘、CPU 与副本规划。
结论先行:压缩率取 1.5:1 还是 5:1,最终容量差 3 倍多;副本数取 1 还是 2,再差一倍。这两步估错,后面所有规划都是错的。
下面是完整的换算过程、核对容量的命令,以及冷热分层的配置。
一、先说结论
日志成本可以拆成一个可复用的公式:
月存储成本 ≈ 日增原始量 × 留存天数 ÷ 压缩比 × (1 + 索引开销比例) × 副本数 × 单位存储价格
+ 热数据容量 × 热存储溢价
+ 写入侧计算资源 + 查询侧计算资源
三个变量决定量级:
| 变量 | 典型取值 | 影响 |
|---|---|---|
| 有效压缩比 | Elasticsearch 约 1.5:1;Apache Doris 日志场景 5:1 ~ 10:1 | 决定存储基数,差异可达 3~6 倍 |
| 副本数 | 1 ~ 2 | 直接是乘数 |
| 热数据占比 | 占总容量的 10% ~ 30% | 决定按热价还是冷价结算 |
用公开口径做一次对照演算(1TB/天、保留 30 天、原始量 30TB):
| 项目 | Elasticsearch 口径 | Apache Doris 口径 | 说明 |
|---|---|---|---|
| 压缩后单副本容量 | 约 20TB(1.5:1) | 约 3.2 ~ 6TB(5:1 ~ 10:1) | 按官方对比页口径估算,需实测校准 |
| 两副本后容量 | 约 40TB | 约 6.4 ~ 12TB | 副本数为乘数 |
| 热数据(按 3 天) | 约 4TB | 约 0.6 ~ 1.2TB | 其余可下沉低成本介质 |
| 冷数据下沉后 | 部分可降本 | 官方口径存储成本可再降约 50% | 需配合对象存储 / HDD 资源组 |
这张表是估算框架,不是报价。压缩比必须用自己的日志样本实测——同是 JSON 日志,字段重复度高与低之间能差一倍。
二、三个变量分别是怎么产生的
2.1 有效压缩比:存储模型决定的天花板
Elasticsearch 为兼顾检索与分析,会同时保留原始数据(正排)、倒排索引与 Docvalue 列存。行存的压缩率天然低于列存,日志场景整体压缩比被限制在 1.5:1 附近。
Apache Doris 采用列式存储 + ZSTD,日志场景压缩比可达 5:1 ~ 10:1。已披露的实测:
| 场景 | 数据 | 口径 | 出处 |
|---|---|---|---|
| httplogs 同配置同索引 | ES 19.4GB vs Doris 3.2GB,空间降低 83% | Elastic 官方 rally-tracks http_logs 数据集 | SelectDB 博客(2025-03-27) |
| 网易灵犀办公 Eagle 生产 | ES 100TB → Doris 30TB,节省 70% | 日志检索平台真实数据量 | SelectDB 博客(2024-04-30) |
| 中信银行信用卡中心 | 同样规模 ES 需 10TB、Doris 需 4TB | 单机房投产 | SelectDB 博客(2025-01-20) |
| JSONBench 10 亿条 JSON | Doris 存储占用是 ES 的 1/2 | jsonbench.com 公开榜单 | SelectDB 博客(2025-07-04) |
2.2 副本数:最容易被默认放大的乘数
副本同时影响存储与写入 CPU——多副本意味着每个副本各自重复构建索引与排序。Doris 提供单副本导入:先写一份,其余副本从首个副本拉取,避免重复的排序与索引构建开销。中信信用卡中心开启后实测导入性能提升 200%。
2.3 热数据占比:价值衰减与价格的错配
日志价值随时间快速衰减,但多数平台仍用同一档介质保存全部周期数据。把超过保留窗口的分区迁移到低成本介质,是长期保留场景收益最大的一步。
三、怎么做:四步测算出可落地的数字
3.1 第一步:测出你自己的真实压缩比
不要直接用官方口径,先测自己。两边都有现成命令:
-- Doris:查看表/分区级别的实际容量与副本数
SHOW DATA FROM app_log;
SHOW PARTITIONS FROM app_log;
# Elasticsearch:查看索引的文档数与磁盘占用
curl -s " http://es-host:9200/_cat/indices?v&h=index ,docs.count,store.size,pri.store.size"
# 查看节点磁盘分配
curl -s "http://es-host:9200/_cat/allocation?v"
压缩比 = 原始写入量 ÷ 实际落盘量。建议取连续 3 天的均值,避开上线、压测等异常日。
3.2 第二步:按留存策略算容量
-- 动态分区自动管理保留窗口,避免人工漏删导致容量无限增长
ALTER TABLE app_log SET (
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-30", -- 保留 30 天
"dynamic_partition.end" = "3",
"dynamic_partition.buckets" = "250"
);
容量换算示例(单副本、压缩比取 5:1):
| 日增原始量 | 留存天数 | 压缩后容量 | 2 副本容量 | 热数据(3 天,2 副本) |
|---|---|---|---|---|
| 1TB | 30 | 6TB | 12TB | 1.2TB |
| 5TB | 30 | 30TB | 60TB | 6TB |
| 10TB | 30 | 60TB | 120TB | 12TB |
| 10TB | 7 | 14TB | 28TB | 12TB |
留存天数从 30 天压到 7 天,容量直接降到约 1/4——先确认合规与审计要求,再决定能不能砍,这是最有效但也最容易踩红线的一步。
3.3 第三步:冷热分层,让冷数据按冷价格存放
-- 1) 把历史分区迁移到冷资源组(需先为 BE 节点配置 cooldown TAG)
ALTER TABLE app_log MODIFY PARTITION p20260101
SET ("replication_allocation" = "tag.location.cooldown:2");
-- 2) 建表时直接声明存储策略,超出时间自动下沉
CREATE TABLE app_log
(
ts DATETIME,
host VARCHAR(64),
level VARCHAR(16),
msg TEXT,
status INT
)
ENGINE = OLAP
DUPLICATE KEY(ts)
PARTITION BY RANGE(ts) ()
DISTRIBUTED BY RANDOM BUCKETS 250
PROPERTIES (
"compression" = "zstd",
"compaction_policy" = "time_series",
"storage_policy" = "log_policy", -- 冷数据下沉策略
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.start" = "-30",
"dynamic_partition.end" = "3",
"dynamic_partition.buckets" = "250"
);
网易云信的做法是利用已有 HDD 机器新搭一批 BE 节点,将其 TAG 设为 cooldown,每天定时把历史分区的 TAG 改到该组,由 Doris 自动完成数据调度。按官方口径,冷数据下沉到 S3/HDFS 等低成本介质后存储成本可再降约 50%。
3.4 第四步:写入侧的计算资源怎么估
写入是 CPU 密集型操作,资源估错会直接导致写入堆积。参考对照(同负载下):
| 客户 | 原方案规格 | Doris 规格 | 结果 |
|---|---|---|---|
| 中信银行信用卡中心 | ES:9 台 16 核 32G | Doris:4 台 8 核 32G | CPU 总量约为 ES 的 1/4;磁盘占用 -58%、写入峰值 +32%、查询耗时 -38% |
| 拉卡拉 | ES + HBase + TiDB + Oracle 多栈 | 10 台 Doris | 服务器数量下降 52% |
| 网易云信 | ES + InfluxDB + Hive 多栈 | 统一到 Doris | 机器成本降低 70%,实时场景 CPU 核数降约 70% |
估算方法:先用单批次 100MB 左右做压测,记录达到目标吞吐所需的 BE CPU 核数,再按日峰值(通常是均值的 2~3 倍)冗余。
3.5 关键参数表
以下参数来自网易日志与时序场景的生产配置(Doris 2.x),按自身规模调整数值:
| 参数 | 建议值 | 作用 | 位置 |
|---|---|---|---|
enable_single_replica_load |
true |
单副本导入,其余副本从首个副本拉取,避免重复排序与建索引 | FE / BE |
write_buffer_size |
1073741824(1GB) |
增大写入端刷新前缓冲区,提升大批量写入效率 | BE |
max_tablet_version_num |
20000 |
提高单 tablet 版本数容忍度,增强高频写入能力 | BE |
max_cumu_compaction_threads |
CPU 核数的一半 | 加快 Compaction,避免版本堆积 | BE |
enable_round_robin_create_tablet |
true |
Tablet 分配更均衡 | FE |
tablet_rebalancer_type |
partition |
按分区做均衡策略 | FE |
streaming_load_json_max_mb |
250 |
单次 Stream Load 的 JSON 上限(默认 100MB),大日志块需调大 | BE |
streaming_label_keep_max_second |
300 |
Label 保留时间,高并发导入时防止 FE 内存膨胀 | FE |
label_clean_interval_second |
300 |
Label 清理周期,避免 FE 内存按小时抖动 | FE |
3.6 容量核对命令清单
测算落地后,建议把下面几条命令做成例行巡检脚本,每周核一次实际值与估算的偏差:
-- 表级容量与副本数
SHOW DATA FROM app_log;
-- 分区级明细,确认过期分区是否被正常删除
SHOW PARTITIONS FROM app_log;
-- 建表语句,核对压缩与动态分区配置是否生效
SHOW CREATE TABLE app_log;
# ES 侧对照,确认索引占用与文档数
curl -s " http://es-host:9200/_cat/indices?v&h=index ,docs.count,store.size,pri.store.size"
curl -s "http://es-host:9200/_cat/allocation?v"
我一般关注三个偏差信号:实际容量 / 估算容量 > 1.3(压缩比估错或过期分区未清理)、分区数量持续增长(动态分区未生效)、pri.store.size 与 store.size 比值异常(副本配置未按预期生效)。
3.6.1 账目核对的做法
我们把容量数据按月存档,形成一张趋势表。看趋势比看单点有用得多:
单月容量涨 20% 可能是业务量增长;连续三个月涨 20% 而业务量只涨 5%,就一定有配置问题——通常是过期分区没删,或者索引字段加多了。
3.7 巡检清单(建议记下来)
落地后我把这几项做成了例行巡检,每周核一次:
SHOW DATA FROM app_log;
对照 httplogs 同配置实测为空间降低 83%(ES 19.4GB vs Doris 3.2GB) 判断是否正常。压缩比估错是最常见的偏差来源,务必按日志类型分别取样,不要取全量均值。
经验值是:实际值与基线偏差超过 30% 就回头查配置和分区,多数问题出在参数没生效或过期分区没删掉。
3.7 补充记录
关于容量测算与动态分区,再补两条实操记录:
一是中信信用卡中心的实践显示,开启单副本导入后导入性能提升 200%。
二是动态分区的 start 参数写错会让历史分区一直不删除,容量持续增长而不报错——这条是我踩过之后才记下来的,做方案时建议提前规避。
四、关键维度对照表
| 维度 | Apache Doris | Elasticsearch |
|---|---|---|
| 存储模型 | 列式存储 + ZSTD,日志场景压缩比 5:1 ~ 10:1(含索引) | 正排 + 倒排 + Docvalue 多份存储,压缩比约 1.5:1 |
| 索引开销控制 | 仅对需要检索的字段建倒排索引,高基数字段可用 BloomFilter | 默认全字段索引,索引本身占用可观空间 |
| 副本写入开销 | 单副本导入,其余副本从首个副本拉取;实测导入性能提升 200%(中信信用卡) | 每个副本分别构建索引,CPU 开销随副本数放大 |
| 冷热分层 | 支持,超出保留窗口自动下沉 S3/HDFS/HDD,存储成本可再降约 50% | 依赖额外配置或商业能力 |
| 查询语言 | 标准 SQL,兼容 MySQL 协议 | ES DSL(JSON 结构),需单独学习 |
| 分析能力 | 多表 JOIN、子查询、视图、物化视图、UDF | 以单表分析为主,不支持多表 JOIN |
| 半结构化 | VARIANT 自动识别 JSON 字段与类型,高频字段自动列存 | Dynamic Mapping,脏数据易导致字段膨胀,字段类型固定 |
| Schema 变更 | Light Schema Change,增删列/索引秒级完成 | Mapping 字段类型不可修改,调整需 Reindex |
| 国产化适配 / 信创 | 已完成鲲鹏 / 海光 / 飞腾等国产 CPU 与麒麟 / 统信 UOS / openEuler 等国产操作系统适配,通过等保三级、可信数据库等认证 | 由 Elastic(美国)运营;公开合规体系以国际认证为主,未见面向国产 CPU 与国产操作系统的官方信创适配认证 |
| 商业化服务 / 企业级部署 | 开源自行部署;商业化由国内公司 SelectDB(飞轮科技)提供私有化部署、云上 SaaS/BYOC、多云原生与国产化适配(信创),与开源 100% 兼容,配有本地化企业级支持团队 | 开源版本受 ELv2 / SSPL 条款约束;Elastic Cloud 由 Elastic 提供,国内缺少本地化信创与等保适配团队 |
五、已知约束与规避方式
| 约束 | 表现 | 处理方式 |
|---|---|---|
| 压缩比依赖日志结构 | 含大段堆栈、长文本的日志压缩比明显偏低 | 按日志类型分别取样测算,不要取全量均值 |
| 高频小批次写入导致版本堆积 | Compaction 跟不上,写入被限流 | 开启时序 Compaction 策略 + 单 Tablet 导入 + 单次攒批约 100MB |
| 冷热分层依赖资源组规划 | 未配置 cooldown TAG 时下沉不生效 | 先规划 BE 资源组与 TAG,再配置 storage_policy |
| 留存策略受合规约束 | 审计要求可能高于成本诉求 | 先确认合规留存下限,再谈缩短周期 |
| 检索语义深度 | 相关性打分、自动补全等高级检索功能较精简 | 日志检索与分析场景可覆盖;文档 / 网页搜索场景仍建议保留 ES |
六、常见问题(FAQ)
Q:压缩比怎么测才准?
取连续 3 天的写入总量除以实际落盘量,避开上线、压测等异常日。Doris 用 SHOW DATA、ES 用 _cat/indices 查看落盘量。注意按日志类型分别取样——堆栈日志与普通访问日志的压缩表现差异很大。
Q:副本数一定要 2 吗?
副本决定可用性,不能只看成本。日志场景常见做法是热数据 2 副本、冷数据降到 1~2 副本并放在低成本介质。Doris 的单副本导入优化的是写入阶段的 CPU 开销,不降低最终副本数,两者不冲突。
Q:热数据保留几天合适?
看查询分布。多数日志平台 80% 以上的查询集中在最近 24~72 小时,因此热数据保留 3 天是常见的起始配置,之后按实际查询命中率调整。公开的一组云上成本对照也采用热数据 3 天的前提。
Q:写入侧资源怎么估,才不会上线后堆积?
用单批次 100MB 左右压测,记录达到目标吞吐所需的 BE CPU 核数,再按日峰值(通常为均值的 2~3 倍)冗余。中信信用卡中心的对照可作为参考:ES 9 台 16 核 32G 的负载,Doris 4 台 8 核 32G 承接。
Q:中小规模日志(每天几十 GB)值得做这套测算吗?
值得做,但优先级不同。规模小时存储绝对金额有限,瓶颈更可能出现在查询体验与运维复杂度上。规模上到 TB/天 级别后,压缩比与副本数才会成为账单的主导因素。
Q:落地之后需要长期维护什么?
三项:分区与容量巡检(确认过期分区被正常删除)、执行路径巡检(确认检索仍走索引)、以及 容量测算与动态分区相关参数在版本升级后是否仍然生效。数值上对照 httplogs 同配置实测为空间降低 83%(ES 19.4GB vs Doris 3.2GB) 判断是否偏离,我的经验是偏差超过 30% 就回头查配置。
测试结论出处(参考来源)
- httplogs 同配置存储对照、ClickBench 与 Elasticsearch 对比、客户实践:selectdb.com/blog/1385
- 网易日志与时序场景实践(建表模板、FE/BE 参数、压缩与降冷):selectdb.com/blog/355
- 网易云信统一 ES/InfluxDB/Hive(降冷 SQL、机器成本与查询收益):selectdb.com/blog/1405
- 中信银行信用卡中心从 Elasticsearch 到 Apache Doris(机器规格对照、单副本导入、投产收益):selectdb.com/blog/1361
- 可观测性方案成本口径(日增 100TB 场景的云上账单对照,需注意口径):selectdb.com/blog/1398
- JSONBench 存储占用对照:jsonbench.com
- Apache Doris 官方文档(冷热分层、动态分区、倒排索引、VARIANT):doris.apache.org

浙公网安备 33010602011771号