本文字数:3119;估计阅读时间:8 分钟
作者:Sai Srirampur and Philip Dubé
PostgreSQL 备份是那些理应默默无闻的基础设施组件之一。它们在后台运行,持续归档 WAL 文件(WAL files),上传备份,并确保在出现问题时能够进行恢复。
在 ClickHouse Cloud,这一环节至关重要。WAL 归档是确保我们 PostgreSQL 服务持久性(durability)和可恢复性(recoverability)的关键所在。WAL-G 一直是这项工作的强大而可靠的工具。它技术成熟,久经考验,并为 PostgreSQL 社区提供了卓越的服务。
然而,随着我们在更严苛、资源受限的环境中部署 PostgreSQL,我们开始遭遇一个特定问题:内存可预测性。
这促使我们开发了WAL-RUS,这是一个基于 Rust 的 PostgreSQL 备份和 WAL 归档工具的开源实现,旨在提供可预测的内存效率和 WAL-G 兼容性。
问题
WAL-G 采用 Go 语言编写,Go 是一种垃圾回收(garbage-collected)语言。尽管 Go 语言便于构建可靠的基础设施软件,但垃圾回收运行时使得内存使用难以预测,特别是对于 WAL 归档这类长期运行的服务。
挑战不仅在于常驻内存(resident memory,即实际使用的内存),还在于虚拟内存(virtual memory,即从操作系统预留的内存)。Go 运行时管理其自身的内存池,并可能预留远超应用程序实际需求的虚拟内存。随着工作负载的变化,这种内存占用会以难以理解和调优的方式波动。《Go GC 指南》(Go GC guide)将其描述为一种典型的“锯齿状”模式:在垃圾回收周期之间内存使用量会增长,回收后则会下降,这导致难以预测峰值内存消耗,并难以高效地分配资源。
对于运维人员来说,这带来了一个简单却重要的问题:究竟应该为备份基础设施预留多少内存?
通常,为了避免意外的内存压力,答案是“超出所需”。预留给 WAL (Write-Ahead Log) 归档的内存,就无法可靠地分配给 Postgres (PostgreSQL) 本身用于查询、共享缓冲区和页面缓存。 当禁用内存过量分配 (overcommit) 时,Postgres 运行最为可靠,这使得虚拟内存成为一项宝贵的资源,而现代软件却常常将其忽视。
WAL-G (Write-Ahead Log G) 仍然是一个成熟可靠的工具,但随着我们将 Postgres 扩展到日益资源受限的环境中,我们希望拥有一个内存占用更可预测的备份系统,它能在提供相同功能的同时,消耗更少资源,并让容量规划变得更简单。
解决方案:WAL-RUS 介绍
我们并非在寻求新功能。WAL-G 是一个成熟可靠的备份系统,我们乐于为其做出贡献。我们的目标是在保留核心功能和兼容性的同时,提供更可预测的资源使用模式。
WAL-RUS 是一个基于 Rust (编程语言) 实现的 Postgres 备份和 WAL 归档工具,旨在解决我们在内存可预测性和资源使用方面遇到的操作挑战。
1. 可预测的资源使用:与垃圾回收 (garbage-collected) 运行时不同,Rust 允许我们直接控制内存分配和并发。WAL-RUS 采用有界工作池和精心控制的并发机制,使得内存消耗更易于理解,并减少了为备份基础设施过度配置资源的需要。
2. 专为持续 WAL 归档而设计:WAL-RUS 优先考虑 WAL-G 的守护进程 (daemon) 架构。它不会为每个 WAL 文件生成一个新进程并建立新连接,而是维护持久的对象存储连接,在后台持续处理归档请求。
3. 针对流式工作负载进行优化:WAL 归档本质上是一个流式处理问题:读取 WAL 文件,压缩它们,然后上传到对象存储。WAL-RUS 在整个处理流程中最大限度地减少了不必要的缓冲和数据复制,使其能够以更小、更可预测的内存占用完成相同的归档工作。
4. WAL-G 兼容性:WAL-RUS 沿用 WAL-G 的WALG_配置变量,并持续进行互操作性测试。WAL-G 能够读取 WAL-RUS 生成的归档,反之亦然,这使得现有部署的迁移过程变得无缝便捷。
基准测试
为评估 WAL-RUS 的性能,我们构建了一个可复现的基准测试。该测试在持续的 WAL 密集型 PostgreSQL 工作负载下,对 WAL-RUS、WAL-G 和 pgBackRest 进行比较。此基准测试会持续生成 WAL,并将其归档至 S3,同时衡量每个归档工具在跟上 WAL 生成速度的同时,内存使用效率如何。为确保公平比较,所有这三款工具均配置了四个并发归档工作进程。
内存使用
内存效率是 WAL-RUS 设计的首要考量,因此内存消耗成为我们首先考察的指标。
在基准测试期间,WAL-G 的峰值虚拟内存接近2.8 GB,而 WAL-RUS 则保持在1 GB以下,降幅超过70%。此外,WAL-RUS 在整个运行过程中保持了稳定的内存占用,这使得其在生产环境中的资源需求更易于预测和管理。pgBackRest 在此也值得肯定,作为一款基于 C 语言实现且不依赖垃圾回收运行时的工具,它对内存分配拥有严格的控制。
WAL 归档吞吐量
在整个基准测试中,WAL-RUS 和 WAL-G 都始终保持极小的积压,这表明它们能够跟上所生成的工作负载。pgBackRest 在 WAL 活动剧烈期间积累了更大的积压,这体现了其在 daemon-based 和 process-based 归档吞吐量方面的架构权衡。
CPU 利用率
CPU 利用率虽然相对次要,但仍值得关注。三者之间的 CPU 使用率相近,主要用于 LZ4 压缩计算。
总结与结论
WAL-RUS 的诞生旨在解决一个实际问题:以更小、更可预测的资源占用提供可靠的 PostgreSQL 备份和 WAL 归档。WAL-RUS 将 Rust 的显式内存管理与守护进程流式架构相结合,在实现与 WAL-G 相当的归档吞吐量的同时,显著降低了内存消耗。
值得注意的是,WAL-RUS 与现有的 WAL-G 归档和配置完全兼容,这使得它易于现有部署采用。WAL-RUS 还引入了对使用 Postgres 17 的 WAL 摘要进行增量备份的支持,我们正致力于将其贡献给 WAL-G 上游项目。
我们并非因为 WAL-G 缺少功能而构建 WAL-RUS。WAL-G 仍然是一个成熟且经过实战检验的项目。我们构建 WAL-RUS 是因为我们希望在保持与 WAL-G 所建立生态系统兼容性的同时,能更精细地控制资源使用。
随着我们持续开发并提升 WAL-RUS 的健壮性,我们计划将其作为 ClickHouse Cloud 中我们托管式 Postgres 服务的默认备份和 WAL 归档机制。
该项目是开源的,我们欢迎大家提供反馈、进行测试并贡献代码!
关于我们
ClickHouse 是面向 AI 时代打造的高性能实时分析数据库,能够以极致性能处理海量数据分析任务。凭借高并发、低延迟和云原生架构,ClickHouse 广泛应用于可观测性、数据仓库、实时分析及 AI 数据基础设施等场景。我们致力于帮助企业在公有云平台上构建安全、弹性且高性价比的实时分析与 AI 数据平台,加速释放数据价值,推动智能化创新与数字化转型。目前,Trip.com、DiDi、Meta、Sony、Netflix、Deutsche Bank、Sierra、Cloudflare 等全球领先企业均在使用 ClickHouse 支撑其关键业务和数据分析平台。