性能画像分析:基于当前基线结果理解瓶颈分布

结合仓库现有 benchmark 文档,分析 Seastar Log Engine 当前版本的性能基线、参数扫描结果与主要瓶颈。

先说明边界

这一篇只讨论当前仓库里已经落盘的 benchmark 结果和分析文档,主要依据:

  • doc/benchmark-results-2026-04-26.md
  • doc/performance-analysis-2026-04-26.md
  • doc/record-format-optimization-log-2026-05-02.md

因此本文不会给出仓库里没有出处的“1.5M msg/s”“P99 15μs”“CPU 70%”这类精确数字,也不会假装已经做完完整的 CPU / 内存 / 磁盘画像。

当前更准确的说法是:项目已经有一轮可复现的吞吐扫描与若干 profile 实验,可以支持我们讨论趋势和热点,但还不足以支撑一份覆盖所有资源维度的完整容量报告。

当前基线

最直接的一组对比结果来自:

./script/compare_bench.sh

messages=50000payload-size=128 的单次本机结果中:

TargetThroughput (msg/s)Avg submit (us)
log_engine_bench387732.152.5791
glog_bench648441N/A
spdlog_bench1024460N/A

这个结果至少能说明两件事:

  1. 当前 log_engine 明显慢于 glog/spdlog
  2. 这不是简单的“代码写得差”,而是因为三者承担的路径不同

项目自己的分析文档也明确指出,log_engine_bench 包含了:

  • 分片路由
  • per-shard 聚合
  • 编码
  • DMA 对齐写入
  • checkpoint / recovery 语义

glog/spdlog 更接近直接日志写入对比。

当前最可信的参数扫描结论

另一份更有价值的材料是:

./script/compare_bench.sh --scan

当前仓库里已经总结出的几个结论如下。

1. payload 放大对 log_engine 打击最明显

已记录的扫描中:

Targetpayload=128payload=512Change
log_engine373170.53183944.58-50.7%
glog639607538138-15.9%
spdlog967717665442-31.2%
Rendering diagram...

这说明当前实现对 payload 更敏感。

原因并不神秘,主要是 payload 变大时会同时放大:

  1. 记录编码成本
  2. CRC 计算成本
  3. 用户态拷贝和 sanitize 成本
  4. batch flush 阶段的 buffer 搬运成本

换句话说,这里不仅仅是 IO 变大,更是“编码 + 内存搬运 + IO”一起变重。

2. 当前扫描里 batch-size=256 更接近最优

仓库里现有扫描不是用"8KB / 16KB"做主结论,而是:

Batch SizeThroughput (msg/s)
64377233.22
256433538.54
1024426766.81
Rendering diagram...

可见:

  1. 64 太小,flush 频率偏高
  2. 256 有明显收益
  3. 继续增大到 1024 后收益已经消失

所以就当前这轮数据来说,最稳妥的结论是:

当前实现更像“中等 batch 最优”,而不是“batch 越大越快”。

3. inflight 不是越高越好

已记录结果:

InflightThroughput (msg/s)
16348305.84
64383567.95
256371620.12
Rendering diagram...

说明当前瓶颈已经进入平衡区间:

  • 太低:喂不饱 writer
  • 太高:调度、排队、flush 竞争开始抵消收益

因此仓库当前可支持的结论是:

在这轮扫描环境里,inflight=6416256 都更合理。

4. checkpoint 有成本,但不是主瓶颈

CheckpointThroughput (msg/s)
0406649.53
1390097.76
Rendering diagram...

只下降约 4.1%

这说明:

  1. checkpoint 的成本真实存在
  2. 但当前主瓶颈仍在主写链路本身
  3. 如果要继续优化,优先级应放在编码、聚合、DMA 对齐写路径和 record format 上

为什么当前 log_engine 会慢

从代码路径看,一次写入至少会经过:

  1. LogEngine 路由
  2. AsyncWriter 编码并进入 per-shard pending queue
  3. AppendWriter 的 DMA aligned append
  4. 可选 rotate / archive / checkpoint 逻辑

这几层都比“直接把一条字符串写文件”重。

更具体地说,当前热点主要集中在:

  • record_codec
  • flush 阶段的 buffer 管理
  • payload 变大后更明显的 CRC / copy 成本

record format profile 已经给出的信息

record-format-optimization-log-2026-05-02.md 已经把一个关键结论写得很清楚:

1. timestamp 已不是最重热点

项目已经对 timestamp 做了缓存优化,之后 profile 显示:

  • payload=256 时,timestamp on 相对 baseline 吞吐跌幅约 9%11%

这说明 timestamp 有成本,但不是压倒性的主热点。

2. CRC 仍然是最稳定的主热点

现有 profile 记录显示:

  • payload=256 时,crc on 相对 baseline 吞吐跌幅约 33%
  • payload=256/1024/4096 下,这个跌幅都稳定在约 33%

这很关键,因为它说明:

  1. CRC 成本不是小 payload 特例
  2. 它是跨多种 payload 都稳定存在的热点
  3. 后续优化应继续优先盯住 CRC 路径

3. “换个 CRC 实现”不能自动解决问题

仓库里已经试过:

  • 切到 zlib crc32
  • 手写 slicing-by-8
  • copy + CRC 单遍历
  • 针对特殊字符的专用扫描

结果都表明收益有限,或者不稳定。

所以当前更准确的结论不是“再换一个 CRC 库就能大幅提速”,而是:

单纯微调 CRC 内核,已经很难拿到数量级收益;更可能有效的是减少 CRC 路径总处理量,或者改变它与 payload 写入的耦合方式。

当前 multi-shard 结果该怎么放进画像

仓库里已经有一份 benchmark-multi-shard-analysis-2026-05-03.md,它补上了 1/2/4 shards、route_keys=0/4/16、不同 payload 和 backpressure 窗口下的初步扫描。

这组结果最有价值的地方,不是证明“shard 越多越快”,而是把 multi-shard 的边界说清楚了:

  1. route_keys=0 时,多 shard 基本不扩展,因为流量没有真正分散。
  2. route_keys>0 后,吞吐有明显改善,尤其是较大 payload 场景。
  3. 4 shards 相对 2 shards 并没有稳定线性收益,小 payload 和中等 payload 下甚至可能更差。
  4. 过小的 max_pending_bytes 会明显伤害吞吐和尾延迟。

所以当前更准确的说法是:项目已经有了初步 shard 扩展扫描,可以支撑“multi-shard 依赖 route key 分布和 payload 大小”的判断;但它还不是完整容量报告。

当前还不能严肃下结论的部分

仓库里目前还没有足够材料支持以下几类“精确画像”:

  1. CPU 用户态/内核态占比表
  2. 精确内存峰值分解
  3. NVMe 带宽利用率表
  4. 完整 1/2/4/8+ shard 容量曲线和扩展效率归因
  5. flush-ms 全量扫描
  6. 长时间 soak 下的延迟漂移统计

这些方向在项目文档里已经被列为下一轮更值得补的实验项,但当前还没有足够实测结果支撑成文。

当前最保守、也最有用的调优建议

基于现有数据,先给出不夸大的建议。

1. 优先确认业务 payload 分布

因为 payload 是当前最敏感维度。

如果真实业务 payload 经常从 128B 膨胀到 512B 或更大,那么吞吐变化会非常明显,调优时不能只看默认基线。

2. 不要盲目把 batch 一路调大

当前扫描结论更支持:

  • 先从 batch-size=256 一类中等值开始
  • 再结合场景验证更大 batch 是否真的有收益

3. inflight 建议从中档开始试

当前基线更支持把 inflight 放在中档,而不是极低或极高。

如果你在当前实现上做业务接入,64 这种量级比 1256 更值得先试。

4. 如果目标是先提吞吐,先看 record format

优先检查这些开关是否真的必要:

  • record_crc_enabled
  • record_timestamp_enabled
  • record_level_enabled
  • record_shard_id_enabled
  • record_sequence_enabled

其中 CRC 开关最值得先单独做 A/B 对比。

下一轮最值得补的画像

如果继续做性能研究,当前最值钱的实验不是再写一堆漂亮表格,而是把下面几项补全:

  1. 扩展 shard 扫描到更多 core 数,并补 per-shard skew
  2. flush-ms 扫描
  3. write_behind / stream_buffer_size 扫描
  4. record_crc_enabledrecord_crc_class 开关对照实验
  5. 长时间 bench_soak 下的吞吐与尾延迟漂移

这些实验能更直接回答:

  • 瓶颈更偏编码还是更偏 flush 路径
  • 当前 shard 扩展是否已经碰到调度上限
  • flush-ms 对吞吐与尾延迟的真实影响
  • record format 的功能负担到底值不值得

总结

当前仓库能支撑的性能结论,核心其实只有三条:

  1. log_engine 明显慢于 glog/spdlog,但这是功能路径更重带来的结果
  2. payload 放大是当前最敏感的性能维度
  3. CRC 仍然是最稳定、最值得继续优化的主热点

如果要把这版性能画像说得准确一点,可以概括为:

项目已经具备稳定的吞吐基线和若干 profile 结论,但当前最有价值的是“趋势判断和热点定位”,还不是“完整资源画像和容量定标”。


下一篇:《尾延迟优化实践:从 P95 到 P99.9 的优化之旅》