WalShadow:从物理 WAL 实现亚秒级 Postgres 到 ClickHouse 复制

查看原文 HN 讨论

文章摘要

ClickHouse 发布了开源复制引擎 WalShadow,它绕开了业界标准的 Postgres 逻辑复制路线,直接消费 Postgres 物理 WAL 流,把数据同步到 ClickHouse。官方基准中,Postgres 提交的事务约 200 毫秒后即可在 ClickHouse 中查询到,持续吞吐达到每秒 28.9 万行,基本跟上了源库自身的写入速率。

传统 CDC 方案依赖 wal_level = logical,需要在源库内部运行逻辑解码插件、维护复制槽,再经由 Kafka 或 JSON 中转写入目标库。WalShadow 走的是另一条路:它订阅的是 Postgres 为物理备库和崩溃恢复生成的同一份 WAL 流,把解码工作整体挪到源库之外。作者把整个链路拆成四个阶段:第一,追踪活跃 schema——过滤出目录(catalog)相关的 WAL 记录,回放到一个「影子」Postgres 实例中,该实例只保存 schema,不存数据,用于维持最新的表、列和类型目录;第二,并行解码数据变更——heap 记录被分发给一组 Rust 编写的解码器,不经过影子实例;第三,构建 ClickHouse 原生数据块——批处理器按表把解码后的行组装成完整的 native block,避免中间格式转换带来的保真度损失;第四,并行插入——独立的插入器池并发写入多个块,使解码与插入可以各自独立扩展。

由于块是并行处理的,到达顺序可能乱序。WalShadow 的做法是给每一行附上源端的 WAL 位置 _lsn,让 ClickHouse 按主键保留最新版本;对必须严格有序的操作(schema 变更、TRUNCATE)则插入屏障,等待此前所有数据落盘后再执行。它支持完整的复制生命周期:初始全量加载、持续复制、schema 演进(ADD/RENAME/DROP COLUMN、CREATE TABLE)、重启恢复以及计划内的源端切换。

对比对象是 ClickHouse 自家收购来的 PeerDB(ClickPipes 背后的引擎):同样 8 vCPU 的 c8i.2xlarge 机器上,PeerDB 的提交可见延迟约 10 秒、吞吐约每秒 12 万行,WalShadow 分别是约 200 毫秒和 28.9 万行,延迟大约低 50 倍。作为参照,原生 Postgres 物理备库的基线约为 50 毫秒。

一个关键限制是:物理 WAL 是 WalShadow 架构的前提,而绝大多数托管 Postgres 服务并不向用户暴露物理 WAL。因此它目前只能用于自托管 Postgres 或 ClickHouse 自家的 Managed Postgres(后者以私有预览形式提供托管版)。作者把这件事放在更大的叙事里:从收购 PeerDB、在 ClickPipes 中推出 Postgres CDC,到推出基于本地 NVMe 的 ClickHouse Managed Postgres,目标都是把 Postgres 的事务能力与 ClickHouse 的分析能力拼成一套统一的数据栈。

HN 评论精华

这条帖子讨论不多(十来条),但几乎全是硬核技术问答,作者 saisrirampur 亲自逐条回复。