【51CTO.com快譯】數據是數據平臺最重要的資源,企業需要對如何將數據攝取到新的數據平臺中進行設計和規劃。
本文將討論變更數據捕獲(CDC)解決方案,如何基于Debezium等開源工具設計標準的復制解決方案,以及CDC可以幫助企業遷移到新的數據平臺的原因。
什么是變更數據捕獲(CDC)
變更數據捕獲(CDC)是一個軟件過程,它捕獲在源數據庫中所做的變更(DDL和DML)以同步另一個數據存儲庫,例如數據庫、內存緩存、數據倉庫或數據湖。CDC用于本文沒有討論的其他互補的用例,例如:
- CQRS模式:其中一種實現涉及具有單獨的寫入(命令)和讀取(查詢)數據庫和數據模型。寫入層支持插入、更新和刪除操作,讀取層支持查詢數據操作。CDC允許將命令操作從寫入數據庫復制到讀取數據庫。
- 分析微服務:提供變更事件流以跟蹤變更發生的時間和內容,并分析行為模式。
CDC解決方案由三個主要組件組成:
- 源連接器:它從數據庫中捕獲變更并生成包含這些變更詳細信息的事件。
- 通道:它是源連接器將這些事件與變更保持在一起的數據存儲庫。
- 接收器連接器:從通道讀取事件并處理應用特定邏輯以將數據整合到目標系統或其他目的(例如分析警報過程)。
實現CDC有多種方法,例如基于日志、基于觸發器或基于SQL腳本。本文將關注基于日志的方法,因為它是一種更有效的方法,以下將描述這種方法的優點。
源連接器發布的事件包含同步遠程數據存儲庫所需的所有信息。它由以下部分組成:
- 元數據:提供諸如表名、操作類型(插入、刪除等)、事務標識符、源連接器進行或捕獲變更時的時間戳等信息。
- 前值:變更前的數據值。
- 后值:變更后的數據值。
- JSON
- {
- "table":"stock"
- "operation": "update",
- "ts_ms" : "1627817475",
- "transaction_id": 2,
- "before" : {
- "id" : "0001",
- "item" : "T-Shirt",
- "quantity" : "10"
- },
- "after" : {
- "id" : "0001",
- "item" : "T-Shirt",
- "quantity" : "5"
- }
- }
并非所有連接器都具有相同的行為。有一些連接器(例如官方的MongoDB連接器)不提供“前值”。
在數據復制的情況下,這些事件由接收器連接器使用,并合并到目標數據庫中。企業必須按照事件生成的順序使用事件,以確保流程的彈性。
如果事件沒有按順序進行,就不能保證復制過程的彈性。以下是可能發生的一些場景的示例:
在復制以外的場景中,基于事件驅動模式以及想要對特定事件做出反應的情況下,按順序使用事件并不重要。
基于日志的CDC優勢
與其他CDC方法或ETL復制過程相比,基于日志的CDC具有以下一些優勢:
- 性能:通過讀取該文件,從事務日志文件中檢索所有變更。與ETL等其他方法相比,這種操作對數據庫性能的影響較小。ETL方法是基于SQL查詢,需要持續優化(索引、分區等),因此將消耗大量計算資源。
- 解耦數據提取:它提供解耦數據提取計算層,與其余工作負載隔離。這個解決方案允許僅在CDC解決方案上進行垂直和水平擴展。觸發器CDC方法使用數據庫計算層,此復制過程可能影響數據庫的性能。
- 接近實時:低計算影響能夠提供接近實時的事件變更,而不會對源數據庫造成風險。檢測有序文件中的變更比對表進行查詢輪詢過程更容易、更快。
- 捕獲所有變更:事務日志按確切順序提供所有數據變更,其中包括刪除操作。ETL過程忽略了ETL執行之間發生的中間數據變更。可以使用其他方法(ETL、基于CDC觸發器、CDC SQL)識別刪除操作需要創建表來注冊此操作,以及確保數據彈性的特定邏輯。
- 不影響數據模型和應用程序:這不需要變更數據模型或源應用程序。ETL和其他CDC解決方案需要創建觸發器和表或向表中添加時間戳。
需要考慮一些重要的細節:
- 無日志事務操作:所有操作都不會在事務日志上注冊。數據倉庫中通常使用目錄級別的操作,例如目標表和臨時表之間的分區移動。這種類型的操作取決于每個數據庫版本以及團隊的工作方式。
- 商業工具:每個數據庫供應商都提供特定于CDC的工具,通常帶有附加許可證。在復雜的多供應商環境中,企業使用不同的CDC工具來復制數據會增加運營成本。
- 開源工具:它們是一個不錯的選擇。通常需要更多時間來更新數據庫供應商發布的新功能。有時,對故障排除或錯誤解決的支持更為復雜。
- 反模式:在某些情況下,必須將特定源數據庫復制到多個目標數據庫。有時,團隊會配置多個CDC復制,所有這些復制都從同一個事務日志中讀取。這是一個危險的反模式。低影響并不意味著沒有影響,CDC會增加I/O操作,因此從同一文件中讀取多個CDC會增加大量I/O操作,并產生I/O的性能問題。而使用中心輻射模式是一種更好的方法。
中心輻射型CDC模式(Data Hub)
中心輻射式架構是最常見的數據集成架構模式之一。這種架構允許一次從數據庫中捕獲變更并多次交付它們。這種模式與Apache Kafka和其他流媒體平臺使用的發布和訂閱模式非常相似,并具備一些好處,例如:
(1)可重用性:更改事件從源數據庫讀取一次,并由接收器連接器多次使用。
(2)減少集成次數:與源數據庫只有一次集成。
(3)標準接口:為所有消費者提供相同的接口。在這種情況下,接收器連接器復制共享同一接口的目標數據庫中的數據。
根據通道的特性,它將允許提供一些Data Hub的功能。數據保留是Data Hub的一項基本功能。如果無法存儲所有歷史數據甚至每個文檔或行的最后狀態,用戶將不得不采用其他工具和流程來補充解決方案。
CDC的常見場景
CDC是一個很好的解決方案,并且有四種常見的場景:
- OLAP數據庫遷移:在企業將所有或部分工作負載從當前數據倉庫遷移到新的OLAP解決方案的情況下,CDC允許將相同的數據復制到另一個系統并使遷移變得更容易。如今,許多企業正在將工作負載從內部部署數據庫遷移到數據云解決方案。
- 將信息從OLTP數據庫復制到OLAP數據庫:將數據從運營數據庫復制到數據倉庫或數據湖。
- 數據庫即服務:為分析沙箱或提供數據庫的副本。
- 從單體到微服務的遷移:應用扼殺者模式將單體應用程序逐步遷移到微服務。在第一階段復制兩個應用程序共存所需的一些數據集。
企業CDC解決方案
下圖描述了CDC進程的行為方式以及組成它的組件。基于此提出以下解決方案架構:
- Debezium作為源連接器:這一部分將負責從源數據庫引擎讀取變更并將其發送到通道。它將作為連接器部署在Kafka Connect集群中。
- Kafka作為通道:它提供中間存儲以及用于事件生產/消費的廣泛API和可部署在Kafka Connect或其他平臺上的大型生態系統連接器。
- Kafka Sink JDBC(Confluent提供)與Event flattering SMT(Debezium提供)作為Sink連接器:這個連接器允許用戶使用一些配置參數在目標數據庫上執行復制。作為一個通用解決方案,這是一個不錯的選擇。在其他情況下,例如Snowflake或其他云服務,JDBC連接器的成本效益和性能比供應商本身提供的其他策略更差。評估切換到供應商本身提供的連接器而不是使用通用JDBC的成本收益是很重要的。
- Kafka Connect as Connector Platform:它提供了一個框架,可以基于簡單的配置將連接器部署為插件,并與Kafka完全集成。這是一個非常好的選擇,因為它允許企業標準化接收器/源連接器管理,例如Debezium復制操作和JDBC接收器連接器。
1.Debezium
Debezium是一個開源解決方案,提供了非常有趣的功能來捕獲數據庫中的變化。Debezium架構提供了一些優勢,例如:
與特定的數據庫供應商解決方案相比,事件標準化是使用Debezium等產品的重要優勢之一。通常情況下,每個供應商解決方案都有不同的事件規范,因為這些解決方案主要設計用于復制來自同一供應商的數據庫。在多個數據庫產品之間進行復制處理的場景中,具有多個事件規范會增加解決方案在操作、可維護性和編碼方面的復雜性。Debezium提供了一個通用、清晰且簡單的事件規范,可以促進與其他第三方產品(例如Kafka Connect接收器連接器)的集成。
以下看一個事件示例(為了便于閱讀而進行了調整):
- JSON
- {
- "after": {
- "field_id": 1,
- "field_1": "Value 1"
- },
- "before": null,
- "op": "c",
- "source": {
- "connector": "mysql",
- "db": "inventory",
- "name": "mysqldb",
- "snapshot": "false",
- "table": "product",
- "ts_ms": 1627489969029,
- "version": "1.6.1.Final",
- (... other source vendor fields ...)
- },
- "transaction": null,
- "ts_ms": 1627489969200
- }
- after:包含表格列及其值的文檔。其值可以為null,例如在刪除操作中。
- before:包含表格列及其值的文檔。其值可以為null,例如在創建(插入)操作中。
- op:在數據庫中運行的操作,如更新、插入或刪除。
- source:事件的元數據。該文檔具有公共信息,但它有幾個字段,具體取決于源數據庫(Oracle、SqlServer、MySQL或PostgreSQL)。
- t source.ts_ms:表示在數據庫中進行更改的時間。
- ts_ms:Debezium處理該事件時的時間戳,與source.ts_ms不同。通過比較這些值,可以確定源數據庫更新和Debezium之間的延遲。
Debezium與Kafka生態系統完全集成。源連接器使用Kafka API發布更改事件,但也可以部署為Kafka連接器。可以使用REST API將其部署在Kafka Connet集群中,以簡化新CDC源連接器的部署和管理。
- JSON
- {
- "name": "debezium-postgres-inventory-connector",
- "config": {
- "connector.class": "io.debezium.connector.postgresql.PostgresConnector",
- "tasks.max": "1",
- "database.hostname": "postgres",
- "database.port": "5432",
- "database.user": "postgres",
- "database.password": "postgres",
- "database.dbname": "postgres",
- "database.server.name": "postgresdb",
- "schema.include": "inventory",
- "table.include.list": "inventory.product"
- }
- }
在這個示例中,在PostgreSQL數據庫中部署了一個新的Debezium源連接器,并啟用了對庫存模式上產品表的變更捕獲。連接器讀取更改并將事件推送到Kafka主題“postgres.inventory.product”。
盡管每個Debezium數據庫連接器都有特定的配置、屬性和選項,但也有通用的連接屬性。作為一個常見的選擇,可以在第一次配置數據庫快照到Kafka或禁用它。這些通用配置屬性加入Kafka連接器API,提供了一個標準的管理源連接器層,可以簡化解決方案的操作。
需要考慮的事項:
雖然有多種Debezium連接器,但并非所有連接器都提供相同的功能:
- MongoDB
- MySQL
- PostgreSQL
- Oracle
- Etc
在做出決定之前,對每一項進行審查非常重要,因為在某些情況下,使用供應商連接器可能會更好,例如:
- Debezium MongoDB Source Connector:目前無法發送文檔的當前狀態,只能發送冪等格式的操作。
- Debezium SQL Server Source Connector:它不是基于日志的連接器,而是基于觸發器的連接器,它需要安裝觸發器過程并創建一個階段表。
2.Kafka
Kafka是提供通道功能的一個很好的選擇,因為它提供了幾個重要的功能,例如:
- 可擴展的事件流平臺:高度可配置以提供高可用性、低延遲、高性能、多次交付和持久性保證。
- 發布/訂閱模式:它促進了一次發布和多次消費的機制,提供了良好的系統,每個用戶可以或按照希望提供的速度工作。
- 大型生態系統:如今已被數千家公司使用。有許多用于數據管道、流分析和數據集成的開源和商業工具。
- 無限存儲和保留:提供具有無限存儲和保留的集中平臺。Confluent最近提供的一些功能讓用戶能夠擁有更好的成本效益存儲層,將存儲和計算資源解耦。
Debezium CDC事件發布在Kafka主題中。一個Kafka事件由三部分組成:
- 鍵:用于確定將附加消息的分區。具有相同事件鍵的事件被寫入同一個分區。Kafka保證分區的事件將被任何消費者以與寫入它們完全相同的順序讀取。
- 值:它包含事件本身。
- 標頭:它是與Kafka記錄關聯的元數據,并提供有關鍵/值對的額外信息。
作為一個鍵,Debezium包含了表的鍵域。這允許用戶按照變更事件在數據庫中發生的順序處理變更事件。
(1)主題策略
活動發布有兩種策略:
- 每個表有一個主題。
- 每個數據庫有一個主題或一對數據庫和模式有一個主題。
最佳策略取決于環境的特征,兩種解決方案各有利弊。“每個表有一個主題”策略的主要問題是所需的主題和分區的數量。Kafka對每個集群有一個分區限制,所以當用戶的很多數據庫有成百上千的表時,不建議使用這種策略。
(2)表現
這個解決方案中有兩個級別的并行性:
- 基于目標數據庫的數量。
- 特定目標數據庫的吞吐量。
Kafka提供了發布/訂閱模式,這允許用戶部署多個接收器連接器來處理事件,并將信息從主題并行復制到多個目標數據庫。為了增加每個接收器連接器的吞吐量,需要組合兩個組件:
- 主題分區的數量。
- Kafka消費者組中的消費者數量。每個接收器連接器都與一個特定且獨特的消費者群體相關聯。在Kafka連接器的情況下,消費者統一體就像一個線程或任務。
資源組的成員劃分分區,以便分區僅由組的消費者使用,并且該消費者將按順序讀取鍵的事件。基于此,可以使用Kafka Connect來處理影響每個鍵的事件以將狀態復制到另一個目標數據庫中,例如一個簡單配置的數據倉庫,例如:
- JSON
- {
- "name": "jdbc-sink",
- "config": {
- "connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
- "tasks.max": "1",
- "topics": "postgres.inventory.product",
- "connection.url": "jdbc:dwhdriver://connection",
- "transforms": "unwrap",
- "transforms.unwrap.type": "io.debezium.transforms.ExtractNewRecordState",
- "transforms.unwrap.drop.tombstones": "false",
- "auto.create": "true",
- "insert.mode": "upsert",
- "delete.enabled": "true",
- "pk.fields": "id",
- "pk.mode": "record_key"
- }
- }
一個連接器可以讀取多個主題,并且可以在作為用戶組工作的任務中進行擴展。使用此配置中定義的屬性,可以執行源的副本,或者可能僅將事件作為歷史演變附加以執行某些分析過程。
(3)數據保留
Kafka數據保留在主題級別進行管理,并且有不同的策略:
- 時間保留:超過時間時,Kafka代理會定期刪除舊事件。
- 大小保留:當超過主題大小時,Kafka代理會定期刪除舊事件。
- 無限制。
作為一個有趣的新功能,Confluent提供了分層存儲:可以將熱數據發送到經濟高效的對象存儲,并且僅在需要更多計算資源時進行擴展。在某些情況下,數據可能需要無限長的存儲時間。
按時間或大小保留并不是Kafka定義清理策略的唯一能力。用戶可以定義一個緊湊策略,其中Kafka代理定期刪除事件,只保留每個鍵的最后一個事件,并在最后一個事件為null作為s值時刪除該鍵。
壓縮策略是CDC解決方案的一個非常有趣的功能。它允許用戶保留行或文檔的最后一個事件。這意味著用戶擁有最后的合并值,但丟失了變更的歷史記錄。
壓縮清理策略是一項代價昂貴的操作,但它允許用戶清理舊事件,保持數據庫的最后狀態,其優點是,如果一年后需要新的使用者,則不需要處理這一年發生的事件。
結論
在有大量數據和技術多樣的復雜環境中,為新的數據平臺提供數據是一個巨大的挑戰。但真正的挑戰是在提供這些數據的同時確保企業做出有價值決策所需的質量。
準確性、一致性、唯一性、及時性是衡量數據質量的一些指標。CDC代替了其他解決方案,使用戶能夠以相對簡單的方式標準化數據攝取并確保數據質量。而標準化和自動化是提高任何流程質量的關鍵。
原文標題:Data Platform: Building an Enterprise CDC Solution,作者:Miguel Garcia,Dario Cazas Pernas
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】