我们如何将CDC推送到Postgres
将事务性数据库中的数据提供给分析型数据库是现代数据架构的重要组成部分。这也是一场与脆弱工具、高成本和复杂操作的永久斗争。当我们开始在Snowflake构建Postgres服务时,解决这个问题自然而然成为我们的首要任务。本文深入探讨了数据镜像背后的工程原理:我们如何从零开始重新构想Postgres复制。优化Postgres复制Postgres是一个出色的操作数据库,但其变更数据捕获(CDC)功能仍然有许多不尽如人意之处。许多数据管道最终会变得脆弱,因为复制工具承受着处理连续数据与架构变化、快照和故障之间复杂相互作用的重担。为了为Snowflake Postgres构建一个可靠的开箱即用体验,我们必须从头开始重新发明Postgres复制。数据镜像是Snowflake Postgres的一个新特性,正在公开预览中,以低成本、低延迟和事务一致性执行高度可靠的数据复制。在后台,它通过批量将更改直接从Postgres推送到Apache Iceberg™表中来工作。这些批量会以事务性和无服务器的方式自动应用到Snowflake中的表中。“将事务推送到数据湖,在Snowflake中事务应用,无需额外基础设施”的简单性使得复制流程从一个充满复杂故障条件的混乱过程,变成了一个简单的钟表机制,可以永远运行。你只需按下一个按钮,就可以在Snowflake中得到你的Postgres表。从拉取到推送:将变更数据捕获迁移到Postgres变更数据捕获是指从事务性数据库中捕获更改的过程,以便在另一系统上重放。在Postgres中,主要的设施是“逻辑解码”,即将WAL记录解码为逻辑行级插入/更新/删除操作。这些操作通过网络以数据流的形式暴露。从那时起,负担就落在客户身上。在实践中,复制涉及更多步骤。回填、架构变化、处理创建/添加/删除/丢弃表操作、新表快照、故障重新启动、有效合并更改、保留事务边界、适当定位等。即使是Postgres中内置的逻辑复制也仅处理其中的一些方面。逻辑解码方法的一个问题是,消费更改的外部系统对Postgres的状态一无所知。例如,它不知道何时发生架构变化,表快照与更改如何对齐,或者Postgres是否仍然在运行,还是网络出现了故障。解决这个问题的方法相当简单:将更改从Postgres推送到数据湖,在我们的案例中是推送到Iceberg表(使用压缩的Parquet)。像亚马逊S3这样的对象存储是高度可扩展和可靠的,已经被用于Postgres备份。这也是进行变更数据捕获的正确目的地。镜像使用了一种名为snowflake_cdc的新Postgres扩展,它会在后台持续将批量更改推送到每个表的变更日志和一个“元日志”(使用“基本工作者”)。使用扩展的好处在于它确切知道Postgres中发生的事情。它能够仔细协调架构变化以及复杂的数据操纵语言(DML)和数据定义语言(DDL)事务。它可以在推送更改的同时进行快照,并将快照与更改对齐。基于推送的变更数据捕获避免了一整类基础设施及相关问题,并通过对象存储有效地解耦了生产者和消费者。解开复制时间线在构建像数据镜像这样的复制系统时,一个重要方面是数据库的时间线。复制进程处理数据库近期的状态。每次写入Postgres实际上会经过四个阶段,每个阶段代表一个在同一时间线上的连续过程,但位于不同时间点:写入:写入修改表并添加到WAL(在“现在”);解码:过去的WAL被转化为行级更改;捕获:过去的行级更改以批量形式捕获;应用:将过去的更改批量合并到目标表中。解码过程依赖于Postgres中的一个特殊设施来读取写入时的目录表(“历史快照”)。通过这种方式,即使在解码记录时,表已经被修改或删除,二进制WAL记录仍然可以被理解为逻辑行更改。在数据镜像的情况下,记录会进入临时文件。周期性地,解码器会收到一个信号,以完成其当前的批次并向捕获进程发送一条消息,表明批次已经准备好。捕获进程将最终值附加到临时文件中。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡