项目进度复盘:Seastar Log Engine 已完成什么,还缺什么

从当前代码和文档出发,总结 Seastar Log Engine 的完成进度、已具备的工程能力、仍然存在的短板,以及后续可以继续发展的方向。

先给一个总体判断

seastar-log-engine 当前已经不是概念原型。

它已经从早期“验证 Seastar 能不能做高吞吐日志写入”的阶段,推进到一套具备完整主链路的单机日志引擎实现。现在项目里最核心的能力已经串起来了:

route -> per-shard writer -> batch/flush -> DMA aligned append
     -> rotate/archive/checkpoint/recovery
     -> read/query/metrics/benchmark

这意味着它已经可以被当成一个可运行的工程组件来看待,而不是停留在 demo 或单点实验代码。

但反过来说,它也还没有到“成熟通用日志平台”的程度。当前更准确的定位是:

一个面向 Seastar 服务内部使用的单机 append-only 日志 / 轻量 WAL 引擎。

已经完成的主链路

项目当前完成度最高的是写入主链路。

LogEngine 负责统一入口和路由,内部持有 seastar::sharded<AsyncWriter>。每个 shard 上都有自己的 AsyncWriter,再向下交给 AppendWriter 做 DMA 对齐写入。

从能力上看,写入链路已经包含:

  1. per-shard writer
  2. 批量提交和批量刷盘
  3. 定时 flush
  4. 字节级 pending backpressure
  5. write_ack / sync_ack 两档确认语义
  6. 写失败重试与退避
  7. 统一 DMA aligned append
Rendering diagram...

这里最关键的进展,是项目已经不再保留历史上的多条写路径。当前实现收敛到一条统一路径:上层负责路由、批量和生命周期,下层负责对齐写和 tail buffer。

这个收敛很重要。它减少了“某个模式能跑、另一个模式语义不同”的维护成本,也让后续性能分析、恢复测试和文档说明都更容易对齐。

路由和 multi-shard 已经具备基本形态

当前路由能力也比较完整。

项目支持:

  • hash_modulo
  • consistent_hashing
  • routing_virtual_nodes
  • empty_route_policy=local
  • empty_route_policy=round_robin

这意味着它不是简单把所有日志写到一个全局文件里,而是明确把 route key 作为写入模型的一部分。非空 route key 会稳定映射到目标 shard;空 route key 则按配置决定是落在本地 shard,还是轮转分发。

更进一步,append_batch() 已经不是朴素地逐条 invoke。它包含几类快路径:

  1. consistent hashing 下整批同 key 直接发往同一 shard
  2. 空 key + local 直接本地提交
  3. 空 key + round-robin 按 shard 拆分后并行提交
  4. 整批最终落同一 shard 时保留整批 submit_many()

不过 multi-shard 的性能结论还不能写得太满。已有 benchmark 显示:只有 route key 真的把流量分散出去,多 shard 才能带来明显收益;4 shards 对比 2 shards 也并不总是更好,尤其在小 payload 场景下扩展效率还比较弱。

所以当前状态可以概括为:

multi-shard 语义已经建立,性能收益已经出现,但扩展效率还需要继续定位和优化。

存储生命周期已经闭环

日志引擎只会写还不够,长期运行时还要回答几个问题:

  • active log 会不会无限增长?
  • rotate 后文件怎么命名和管理?
  • archive 能不能被查询?
  • checkpoint 和 recovery 能不能接上?
  • gzip archive 出错时系统怎么暴露状态?

这些能力当前已经基本闭环。

项目里已经有:

  1. 按大小 rotate
  2. 按时间 rotate
  3. archive 目录管理
  4. gzip archive
  5. 按保留时间清理
  6. 按每 shard 最大归档数清理
  7. checkpoint sidecar
  8. active log verified scan
  9. incomplete / stale checkpoint fallback
  10. 查询时同时覆盖 active log 和 archive

这里的重点不是“功能很多”,而是这些功能已经彼此协作起来。rotate 会影响 checkpoint;archive 会影响 query;recovery 又依赖 active log 的可信边界;gzip 损坏会反映到 reader stats 和 health 状态里。

这说明项目已经走过了“只关心一次写入是否成功”的阶段,开始处理日志组件真正麻烦的长期运行问题。

查询与观测已经可用

当前查询链路的定位也比较清楚:它不是做一个复杂日志检索系统,而是提供运维排障和一致性观察入口。

已经落地的能力包括:

  • log_engine_read
  • log_engine_verify
  • HTTP query_server
  • gRPC query_server
  • HTTP /healthz
  • HTTP /v1/status
  • HTTP /v1/route
  • HTTP /v1/records
  • gRPC GetStatus
  • gRPC Route
  • gRPC QueryRecords
  • 独立 metrics server

状态接口里已经能看到路由配置、reader 统计、log manager 统计和 health 汇总。Reader 和 Health 指标也能进入 Prometheus 暴露面。

这对一个偏底层的日志组件很关键。因为这类系统最怕的不是“没有功能”,而是出了问题之后只有一句“写入不稳定”。当前 query 和 metrics 至少已经提供了拆分问题的入口:写路径、读路径、archive、checkpoint、gzip、recovery fallback 可以分开看。

测试和 benchmark 已经有基础,但还不够完整

当前项目已经有不少验证脚本:

  • test_unit.sh
  • test_rotation.sh
  • test_recovery.sh
  • test_fault_injection.sh
  • test_read.sh
  • test_query_consistency.sh
  • test_soak_and_fault.sh
  • bench_regression.sh
  • bench_soak.sh
  • bench_multi_profile.sh

这说明项目已经开始把 correctness、recovery、fault injection 和 benchmark 放到同一套工程闭环里,而不是只跑一次吞吐数字。

已有 benchmark 也给出了一些比较可信的方向:

  1. 当前实现比 glog/spdlog benchmark 慢,但功能路径更重。
  2. payload 放大会明显影响吞吐。
  3. CRC 是 record-format 路径上的稳定成本。
  4. 中等 batch 往往比极小或极大 batch 更合理。
  5. multi-shard 收益依赖 route key 分布和 payload 大小。

不过这些测试还不能等同于完整生产级验证。当前更准确的说法是:项目已经具备持续验证的框架,但覆盖矩阵和长期环境数据还需要继续补。

当前最明显的不足

1. 还不是分布式日志系统

项目当前是单机日志引擎,不是 Kafka、Pulsar 或分布式 WAL 服务。

它没有:

  • 跨节点复制
  • leader / follower
  • quorum commit
  • 自动 failover
  • 分布式元数据管理
  • 跨节点 shard rebalance

这不是小缺口,而是定位边界。当前实现适合放在 Seastar 服务内部,作为本地持久化日志或轻量 WAL;如果要变成集群级日志系统,需要重新引入复制协议、成员管理和一致性模型。

2. 查询能力刻意很窄

当前 query path 能看状态、查路由、读记录,但它不是日志检索平台。

还没有:

  • 全文索引
  • 二级索引
  • cursor 分页
  • streaming query
  • 查询缓存
  • 复杂过滤表达式
  • ACL / auth
  • query rate limit

这对于当前阶段是合理取舍。查询链路现在服务的是排障和一致性验证,而不是面向业务用户的搜索产品。

3. 性能画像还不够完整

已有 benchmark 能支持趋势判断,但还不足以完成容量定标。

目前仍然缺少:

  • CPU 用户态 / 内核态比例
  • 内存峰值和分配热点
  • NVMe 带宽利用率
  • 更多 core 数下的 shard 扩展曲线
  • per-shard skew 统计
  • flush-ms 的完整扫描
  • 长时间 soak 下的尾延迟漂移分析

这会影响后续工程决策。比如 4 shards 为什么部分场景不如 2 shards,是跨 shard 调度、编码成本、队列竞争、I/O 并发,还是 benchmark workload 本身造成的,还需要进一步拆开。

4. record format 仍是核心优化点

当前 record format 已经具备结构化字段、CRC class 和恢复校验能力,但它仍然是性能热点。

尤其是:

  • payload sanitize
  • 字段拼装
  • CRC 更新
  • structured fields 组合
  • 大 payload 下的内存搬运

这些成本会直接影响写入吞吐。当前最实际的优化方向,不是简单换一个更快的 CRC 库,而是减少 CRC 路径处理量、优化 payload 扫描和复制方式,并让不同日志类型可以选择不同完整性等级。

5. 文档和博客仍需要持续去重

项目文档和博客已经比较丰富,但也带来一个问题:历史结论容易滞后。

例如早期文章可能会保留过时性能数据、旧 record format 假设或已经删除的写入模式。后续维护时,文档要坚持一个原则:

能从当前源码、脚本或 benchmark 文档验证的内容,才能写成事实。

否则技术博客很容易从“工程复盘”变成“架构想象”。

未来可以发展的方向

1. 先把单机能力打磨成熟

最现实的下一步不是立刻做分布式,而是把单机引擎的成熟度继续拉高。

优先级比较高的方向包括:

  1. 固定 benchmark profile
  2. 增加 per-shard skew 统计
  3. 补全 recovery + rotate + gzip 的组合测试
  4. 扩展 soak testing 的时长和故障组合
  5. 把 health reason 和 metrics 做得更适合排障

这一步做扎实,后面无论是作为库接入,还是继续演进成更大的系统,基础都会更稳。

2. 继续优化 record format

record format 是当前最值得长期投入的性能点。

可以继续看的方向包括:

  • payload sanitize 是否能减少重复扫描
  • CRC class 是否能按日志类别选择
  • payload_hash 模式在大 payload 下是否稳定收益
  • structured fields 是否需要更紧凑的编码方式
  • 是否需要为纯 payload 场景保留更极简的 fast path

这里要避免一个误区:不要为了追求极限吞吐,把恢复和查询语义重新打散。这个项目现在最有价值的地方,恰恰是写入、恢复和 query 已经能按一套格式协作。

3. 提升 query path 的工程可用性

查询链路目前是排障入口,后续可以继续补实用能力:

  1. cursor 分页
  2. streaming records
  3. query timeout
  4. query rate limit
  5. 简单 auth / token
  6. 更明确的错误码和错误结构

这些能力不一定会改变核心写路径,但会让这个组件更容易在真实服务里被运维和调试工具使用。

4. 做更系统的 crash consistency 验证

当前已经有 checkpoint fallback、broken tail、bad checkpoint、stale checkpoint、broken gzip 等测试方向。

后续可以继续把 crash consistency 做得更系统:

  • 写入中断电模拟
  • rotate 中断
  • checkpoint tmp 残留
  • gzip tmp 残留
  • cleanup 与 query 并发
  • 多 shard 同时恢复
  • 大 payload 下 partial write

这类测试不一定带来新功能,但会显著提升日志引擎的可信度。

5. 谨慎评估分布式演进

如果未来要从单机日志引擎走向分布式系统,方向大概会变成另一类工程:

  • 多副本复制
  • raft 或其他共识机制
  • segment 元数据服务
  • shard migration
  • 数据再均衡
  • 跨节点查询
  • 故障转移

这不是在现有代码上加几个接口就能完成的扩展,而是一次架构层级的升级。

更务实的路线是:先把当前单机 append-only 引擎做成稳定内核,再考虑是否把它作为某个分布式日志系统的 local log layer。

当前阶段的合理结论

如果用项目完成度来概括,可以分成三层。

第一层,已经完成:

Rendering diagram...
  • 单机 per-shard 写入
  • 路由和批量提交
  • DMA 对齐写
  • rotate / archive / gzip
  • checkpoint / recovery
  • query / metrics
  • benchmark / fault injection / soak 基础脚本

第二层,还在收敛:

  • record format 性能
  • multi-shard 扩展效率
  • 长时间运行下的尾延迟
  • query path 的完整自测
  • 文档和 benchmark 结论去重

第三层,尚未进入当前实现范围:

  • 分布式复制
  • 跨节点容灾
  • 高级日志检索
  • 多租户权限和资源隔离
  • 生产级容量模型

所以对这个项目最准确的评价不是"已经完成一个通用日志平台",也不是"只是一个 demo"。它处在一个更具体的位置:

核心单机日志引擎已经成型,工程闭环已经建立;下一阶段的重点是性能画像、稳定性验证和真实接入边界,而不是继续堆功能名词。

这也是后续继续做下去最应该守住的方向。