編者薦語:
隨著用戶對實(shí)時(shí)數(shù)據(jù)計(jì)算的需求越來越多, 現(xiàn)在市場上的CDC工具也越來越成熟没咙, 本文將分享一種大眾耳熟能詳?shù)拈_源技術(shù)CDC猩谊,當(dāng)面臨挑戰(zhàn)進(jìn)行工具選型時(shí),希望能夠幫你破壁祭刚。本文來自石原子科技合伙人祁國輝老師牌捷,歡迎大家閱讀。
以下文章來源于ITPUB 涡驮,作者祁國輝
作者 | 祁國輝
編輯 | 宇亭
頭圖 | Yeekin
責(zé)編 | 韓 楠
實(shí)時(shí)數(shù)倉的浪潮來襲暗甥, 對于用戶最大的挑戰(zhàn), 就是業(yè)務(wù)數(shù)據(jù)的變化需要實(shí)時(shí)反饋到后臺系統(tǒng)捉捅, 甚至需要針對這些變化撤防, 快速做出反應(yīng), 那么就需要一種技術(shù)來支持傳統(tǒng)業(yè)務(wù)系統(tǒng)向?qū)崟r(shí)轉(zhuǎn)型的工具棒口。
本文簡單介紹一種大眾耳熟能詳?shù)拈_源技術(shù)寄月,也希望能夠幫助你在討論實(shí)時(shí)數(shù)倉的時(shí)候可以侃侃而談, 言之有物无牵。
CDC(Change Data Capture)變化數(shù)據(jù)捕獲是指通過技術(shù)手段漾肮, 把系統(tǒng)中最新的數(shù)據(jù)變化(包括增刪改)記錄下來, 然后傳輸給后端系統(tǒng)進(jìn)行消費(fèi)的一種技術(shù)茎毁, 目前CDC被廣泛用于各種場景:
- 變化數(shù)據(jù)捕獲
- 數(shù)據(jù)倉庫ETL
- 業(yè)務(wù)讀寫分離
- 應(yīng)用系統(tǒng)多對一合并
- 一對多數(shù)據(jù)分發(fā)
- 數(shù)據(jù)跨平臺容災(zāi)復(fù)制
- 數(shù)據(jù)平臺滾動升級
變化數(shù)據(jù)捕獲的主流技術(shù)路線
目前克懊, 常用的CDC技術(shù)有如下幾種, 我們分別展開聊一聊。
#1.1 表級別時(shí)間戳或數(shù)據(jù)版本
在成熟的ERP應(yīng)用中保檐, 都會在表中設(shè)計(jì)諸如Last_update耕蝉、 Date_modified等字段, 通過對這類時(shí)間戳字段的讀取和篩選夜只, 用戶就可以知道數(shù)據(jù)的修改時(shí)間垒在, 而對于數(shù)據(jù)刪除, 也可以通過定義deleted 字段, 來標(biāo)記數(shù)據(jù)是否已被標(biāo)記為刪除趁尼。但是缺點(diǎn)就在于數(shù)據(jù)量會持續(xù)增長凯力,因?yàn)樗袆h除只是邏輯刪除,應(yīng)用處理邏輯也需要隨之做出修改踢关。
遺憾的是, 對于不少業(yè)務(wù)系統(tǒng)粘茄, 由于設(shè)計(jì)時(shí)沒有考慮到CDC的需求签舞,系統(tǒng)中沒有設(shè)定時(shí)間戳, 數(shù)據(jù)刪除也會直接刪掉柒瓣, 所以基于時(shí)間戳或者數(shù)據(jù)版本的CDC技術(shù)儒搭,受業(yè)務(wù)系統(tǒng)設(shè)計(jì)約束, 應(yīng)用并不普遍芙贫。
#1.2 變化數(shù)據(jù)對比
基于數(shù)據(jù)快照或者全表在本地或者異地進(jìn)行全量對比的方式搂鲫, 也是針對無法進(jìn)行時(shí)間戳數(shù)據(jù)比對的系統(tǒng)來捕獲數(shù)據(jù)變化量的一種手段。
這種技術(shù)計(jì)算量大磺平, 無論在本地還是異地進(jìn)行全量對比魂仍, 都會消耗大量的CPU和存儲IO, 所以該種對比大多數(shù)是基于存儲硬件級別的加持拣挪,來實(shí)現(xiàn)大量數(shù)據(jù)的全量對比擦酌, 而且只能發(fā)現(xiàn)指定時(shí)間窗口內(nèi)的數(shù)據(jù)最終狀態(tài),不能記錄數(shù)據(jù)變化過程菠劝。
比如一個(gè)賬戶在時(shí)間窗口中賬戶余額變動多次赊舶, 最終在期末達(dá)到和期初一樣的數(shù)額, 那么這種全量對比的方式就沒有辦法捕獲賬戶中間的變化闸英,所以基于變化數(shù)據(jù)對比的方式收益率不高锯岖, 試用場景并不廣泛。
#1.3 表級觸發(fā)器
現(xiàn)代數(shù)據(jù)庫都具備在表上建立觸發(fā)器的功能甫何,基于三種操作出吹,Insert、Update 和Delete分別建立對應(yīng)的觸發(fā)器辙喂。
基于觸發(fā)器捶牢,可以將原始表的所有變化量都保存在另外一張專門記錄原始表數(shù)據(jù)變化的變更歷史表中 這個(gè)變更歷史表中就保存了所有的數(shù)據(jù)變更歷史鸠珠,那么在數(shù)據(jù)ETL的時(shí)候,就可以精準(zhǔn)地獲取某個(gè)指定時(shí)間之后的所有數(shù)據(jù)變化 或者某個(gè)時(shí)間窗口中的數(shù)據(jù)變化情況秋麸。
但是缺點(diǎn)在于渐排,觸發(fā)器會帶來系統(tǒng)額外的性能和數(shù)據(jù)容量的開銷,在需要大量數(shù)據(jù)快速入庫的場景中灸蟆,會導(dǎo)致性能急劇下降驯耻,乃至出現(xiàn)數(shù)據(jù)堆積,影響系統(tǒng)的正常運(yùn)行炒考。
#1.4 基于日志的變化數(shù)據(jù)抽取
目前市面上最流行的變化數(shù)據(jù)捕獲方案可缚,主要基于對源數(shù)據(jù)庫的日志的解析,實(shí)現(xiàn)對指定數(shù)據(jù)庫表的變化數(shù)據(jù)的捕獲斋枢,日志解析可以部署在數(shù)據(jù)庫所在主機(jī)帘靡,也可以部署在數(shù)據(jù)庫服務(wù)器之外,從而最大限度降低對源數(shù)據(jù)庫的性能的影響和侵入瓤帚。而且可以實(shí)現(xiàn)對業(yè)務(wù)系統(tǒng)的松耦合描姚,靈活配置。并且可以輕松實(shí)現(xiàn)跨平臺戈次,跨數(shù)據(jù)庫的變化數(shù)據(jù)捕獲和傳遞轩勘。
主流數(shù)據(jù)庫
<p align=center>基于日志捕獲變化數(shù)據(jù)的配置要求</p>
#2.1 MySQL
MySQL 中的基于日志的CDC, 主要是通過對Binlog的解析來實(shí)現(xiàn)的朝扼, 主要要求如下:
- MySQL數(shù)據(jù)庫為5.7或以上版本赃阀。
- 不支持采集二進(jìn)制類型的字段霎肯,例如:TINYBLOB擎颖、BLOB、MEDIUMBLOB观游、LONGBLOB搂捧。
Binlog 有三種格式:
- Statement
(Statement-Based Replication,SBR):每一條會修改數(shù)據(jù)的 SQL 都會記錄在 binlog 中。日志量最小懂缕,但是由于只記錄SQL允跑,那么有可能會出現(xiàn)數(shù)據(jù)一致性問題;
- Row
(Row-Based Replication,RBR):不記錄 SQL 語句上下文信息搪柑,僅保存哪條記錄被修改聋丝。Row格式會清楚地記錄數(shù)據(jù)的變化, 可以確保數(shù)據(jù)一致性工碾,所以日志量會比較大弱睦;
- Mixed
(Mixed-Based Replication,MBR):Statement 和 Row 的混合體。綜合上述兩種日志類型渊额,自動判斷采用什么模式况木, 可以實(shí)現(xiàn)性能和功能的最大化垒拢。
如果需要對MySQL 進(jìn)行CDC的話, 推薦使用后面兩種模式火惊。
#2.2 Oracle
因?yàn)镺racle Redo log會循環(huán)使用求类, 如果在主庫業(yè)務(wù)繁忙的時(shí)候, 有可能會出現(xiàn)數(shù)據(jù)丟失的現(xiàn)象屹耐, 所以尸疆, 推薦開啟歸檔模式, 確保所有數(shù)據(jù)庫日志不丟失惶岭。
另外仓技,Oracle 補(bǔ)充日志(supplemental log)又叫附加日志,可以指示數(shù)據(jù)庫在日志中添加額外信息到日志流中俗他,以支持基于日志的工具脖捻,比如邏輯standby、streams兆衅、GoldenGate地沮、LogMiner。所以為了保證捕獲完整羡亩, 必須打開附加日志摩疑。
Oracle 19C不支持 continuous_mine
Oracle LogMiner 是 Oracle 為其 Oracle 數(shù)據(jù)庫的購買者提供的實(shí)用程序,提供查詢對 Oracle 數(shù)據(jù)庫所做的記錄更改的方法畏铆,主要是通過引用 Oracle 重做日志中的數(shù)據(jù)的 SQL 命令雷袋。它主要由 DBA 用于查詢事務(wù)日志。Oracle LogMiner 具有從 Oracle 重做日志提供實(shí)時(shí)更改的功能辞居。大多數(shù)第三方 CDC 工具使用此功能為其客戶復(fù)制 Oracle 數(shù)據(jù)楷怒。在 19C中,Oracle 也棄用了此功能瓦灶, 其官方推薦使用Oracle Golden Gate鸠删。
目前有不少第三方工具已經(jīng)找到work around 來解決這一問題。
#2.3 PostgreSQL
邏輯解碼是 PostgreSQL 的基于日志的 CDC(邏輯復(fù)制)的正式名稱贼陶。邏輯解碼使用 PostgreSQL 預(yù)寫日志的內(nèi)容來存儲數(shù)據(jù)庫中發(fā)生的所有活動刃泡。
PG 從PG10 開始提供邏輯復(fù)制, 可以通過讀取配置復(fù)制槽的方式碉怔, 通過解析WAL日志來把數(shù)據(jù)變化傳輸出來烘贴,到指定邏輯槽, 下游可以使用 pg_recvlogical消費(fèi)邏輯槽中的數(shù)據(jù)撮胧。
#2.4 MongoDB
Change Stream是 v3.6 中引入的一個(gè) MongoDB API桨踪。Change Streams 允許應(yīng)用程序監(jiān)聽實(shí)時(shí)數(shù)據(jù)更改,而不會有拖尾oplog(數(shù)據(jù)庫上所有修改操作的滾動記錄)的復(fù)雜性和風(fēng)險(xiǎn)趴樱。應(yīng)用程序可以使用更改流來訂閱單個(gè)集合馒闷、數(shù)據(jù)庫或整個(gè)部署上的所有數(shù)據(jù)更改酪捡,并立即對其做出反應(yīng)。
更改流僅適用于副本集纳账。這個(gè)限制是因?yàn)樽兏鞯膶?shí)現(xiàn)是基于 oplog 的逛薇,它只在副本集上可用。
流行開源CDC工具
#3.1 Debezium
Debezium是一個(gè)開源的捕獲數(shù)據(jù)更改(CDC)平臺疏虫,并且利用Kafka和Kafka Connect實(shí)現(xiàn)了自己的持久性永罚、可靠性和容錯性。
每一個(gè)部署在Kafka Connect分布式的卧秘、可擴(kuò)展的呢袱、容錯性的服務(wù)中的connector監(jiān)控一個(gè)上游數(shù)據(jù)庫服務(wù)器,捕獲所有的數(shù)據(jù)庫更改翅敌,然后記錄到一個(gè)或者多個(gè)Kafka topic(通常一個(gè)數(shù)據(jù)庫表對應(yīng)一個(gè)kafka topic)羞福。
Kafka確保所有這些數(shù)據(jù)更改事件都能夠多副本并且總體上有序(Kafka只能保證一個(gè)topic的單個(gè)分區(qū)內(nèi)有序),這樣更多的客戶端可以獨(dú)立消費(fèi)同樣的數(shù)據(jù)更改事件蚯涮,而同時(shí)對上游數(shù)據(jù)庫系統(tǒng)造成的影響降到很小(如果N個(gè)應(yīng)用都直接去監(jiān)控?cái)?shù)據(jù)庫更改治专,對數(shù)據(jù)庫的壓力為N,而用debezium匯報(bào)數(shù)據(jù)庫更改事件到kafka遭顶,所有的應(yīng)用都去消費(fèi)kafka中的消息张峰,可以把對數(shù)據(jù)庫的壓力降到1)。
另外棒旗,客戶端可以隨時(shí)停止消費(fèi)喘批,然后重啟,從上次停止消費(fèi)的地方接著消費(fèi)铣揉。每個(gè)客戶端可以自行決定他們是否需要exactly-once或者at-least-once消息交付語義保證饶深,并且所有的數(shù)據(jù)庫或者表的更改事件是按照上游數(shù)據(jù)庫發(fā)生的順序被交付的。
圖源 Debezium Architecture :: Debezium Documentation
#3.2 TapData
Tapdata 開源項(xiàng)目的定位是一個(gè)實(shí)時(shí)數(shù)據(jù)服務(wù)平臺老速,目前已上線的 1.0 版本核心覆蓋實(shí)時(shí)數(shù)據(jù)同步粥喜、實(shí)時(shí)數(shù)據(jù)開發(fā)凸主、Fluent ETL 等場景橘券,具備全量和增量復(fù)制、異構(gòu)數(shù)據(jù)庫間的同步與轉(zhuǎn)換卿吐,表級同步以及任務(wù)監(jiān)控等能力旁舰。其工作機(jī)制主要包含以下四個(gè)環(huán)節(jié)的功能特性:
- 基于 CDC 的無侵入數(shù)據(jù)源實(shí)時(shí)采集;
- 異構(gòu)數(shù)據(jù)模型自動推斷與轉(zhuǎn)換嗡官;
- 數(shù)據(jù)處理箭窜,流式計(jì)算,緩存存儲一體架構(gòu)衍腥;
- 一鍵將模型發(fā)布為數(shù)據(jù)服務(wù)的閉環(huán)能力磺樱。
文檔 - https://tapdata.github.io/
**#3.3 Canal******
Canal 是阿里巴巴旗下的一款開源項(xiàng)目纳猫,純 Java 開發(fā)≈褡剑基于數(shù)據(jù)庫增量日志解析芜辕,提供增量數(shù)據(jù)實(shí)時(shí)訂閱和消費(fèi),目前主要支持了 MySQL块差,也支持 mariaDB侵续。
很多大型的互聯(lián)網(wǎng)項(xiàng)目生產(chǎn)環(huán)境中都有部署,包括阿里憨闰、美團(tuán)等状蜗,是一個(gè)非常成熟的數(shù)據(jù)庫同步方案,基礎(chǔ)的使用只需要進(jìn)行簡單的配置即可鹉动。
圖源 GitHub - alibaba/canal: 阿里巴巴 MySQL binlog 增量訂閱&消費(fèi)組件
MySQL主備復(fù)制原理
圖源 GitHub - alibaba/canal:阿里巴巴 MySQL binlog 增量訂閱&消費(fèi)組件
- MySQL master 將數(shù)據(jù)變更寫入二進(jìn)制日志( binary log轧坎,其中記錄叫做二進(jìn)制日志事件binary log events,可以通過 show binlog events 進(jìn)行查看)泽示;
- MySQL slave 將 master 的 binary log events 拷貝到它的中繼日志(relay log)眶根;
- MySQL slave 重放 relay log 中事件,將數(shù)據(jù)變更反映它自己的數(shù)據(jù)边琉。
Canal 工作原理
- Canal 模擬 MySQL slave 的交互協(xié)議属百,偽裝自己為 MySQL slave ,向 MySQL master 發(fā)送dump 協(xié)議变姨;
- MySQL master 收到 dump 請求族扰,開始推送 binary log 給 slave (即 canal );
- Canal 解析 binary log 對象(原始為 byte 流)定欧。
GitHub 地址:https://github.com/alibaba/canal
當(dāng)前的Canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x渔呵。
#3.4 Maxwell
Maxwell 是一個(gè)能實(shí)時(shí)讀取 MySQL 二進(jìn)制日志 binlog,并生成 JSON 格式的消息砍鸠,作為生產(chǎn)者發(fā)送給 Kafka扩氢,Kinesis、RabbitMQ爷辱、Redis录豺、Google Cloud Pub/Sub、文件或其它平臺的應(yīng)用程序饭弓。
應(yīng)用場景:ETL双饥、維護(hù)緩存、收集表級別的 dml 指標(biāo)弟断、增量到搜索引擎咏花、數(shù)據(jù)分區(qū)遷移、切庫 binlog 回滾方案等阀趴。
GitHub 地址:https://github.com/zendesk/maxwell
官網(wǎng) (http://maxwells-daemon.io)
- 支持 SELECT * FROM table 的方式進(jìn)行全量數(shù)據(jù)初始化昏翰;
- 支持在主庫發(fā)生 failover 后苍匆,自動恢復(fù) binlog 位置 (GTID);
- 可以對數(shù)據(jù)進(jìn)行分區(qū)棚菊,解決數(shù)據(jù)傾斜問題锉桑,發(fā)送到 kafka 的數(shù)據(jù)支持 database、table窍株、column 等級別的數(shù)據(jù)分區(qū)民轴;
- 工作方式是偽裝為 Slave,接收 binlog events球订,然后根據(jù) schemas 信息拼裝后裸,可以接受 ddl、xid冒滩、row 等各種 event微驶。
#3.5 Flink CDC
Flink CDC Connectors 是 Flink 的一組 Source 連接器,是 Flink CDC 的核心組件开睡,這些連接器負(fù)責(zé)從 MySQL因苹、PostgreSQL、Oracle篇恒、MongoDB 等數(shù)據(jù)庫讀取存量歷史數(shù)據(jù)和增量變更數(shù)據(jù)扶檐。Flink CDC Connectors 是一個(gè)獨(dú)立的開源項(xiàng)目。
圖源 Overview — CDC Connectors for Apache Flink? documentation (ververica.github.io)
Debezium 官方架構(gòu)圖中胁艰,是通過 Kafka Streams 直接實(shí)現(xiàn)的 CDC 功能款筑。而Flink CDC優(yōu)勢在于 :
- Flink 的算子和 SQL 模塊更為成熟和易用;
- Flink 作業(yè)可以通過調(diào)整算子并行度的方式腾么,輕松擴(kuò)展處理能力奈梳;
- Flink 支持高級的狀態(tài)后端(State Backends),允許存取海量的狀態(tài)數(shù)據(jù)解虱;
- Flink 提供更多的 Source 和 Sink 等生態(tài)支持攘须;
- Flink 有更大的用戶基數(shù)和活躍的支持社群,問題更容易解決殴泰;
- Flink 的開源協(xié)議允許云廠商進(jìn)行全托管的深度定制于宙。
Supported Connectors
#3.6 Integrate.io
Integrate.io被廣泛認(rèn)為是市場上最好的ETL工具之一。它是一個(gè)基于云的ETL數(shù)據(jù)集成平臺艰匙,可以輕松地將多個(gè)數(shù)據(jù)源聯(lián)合起來限煞。該平臺有一個(gè)簡單、直觀的界面员凝,能夠在大量的來源和目的地之間建立數(shù)據(jù)管道。
該平臺還具有高度的可擴(kuò)展性奋献,任何數(shù)據(jù)量或使用情況都可以健霹,它使你能夠?qū)?shù)據(jù)無縫地匯總到倉庫旺上、數(shù)據(jù)庫、運(yùn)營系統(tǒng)和數(shù)據(jù)存儲中糖埋。有100多個(gè)流行的數(shù)據(jù)存儲和SaaS應(yīng)用程序包與Integrate.io宣吱,包括MongoDB、MySQL瞳别、亞馬遜Redshift征候、谷歌云平臺和Facebook。
寫在最后
隨著用戶對實(shí)時(shí)數(shù)據(jù)計(jì)算的需求越來越多祟敛, 現(xiàn)在市場上的CDC工具也越來越成熟疤坝, 通過CDC工具把業(yè)務(wù)系統(tǒng)中的數(shù)據(jù)變化直接傳遞到下游的系統(tǒng)中進(jìn)行消費(fèi), 可以是數(shù)據(jù)分析馆铁, 可以是實(shí)時(shí)大屏跑揉, 也可以是用戶實(shí)時(shí)推薦。當(dāng)然也有用戶可以利用CDC工具進(jìn)行新舊系統(tǒng)切換埠巨, 不同平臺之間的數(shù)據(jù)容災(zāi)历谍。甚至可以實(shí)現(xiàn)云上云下的準(zhǔn)實(shí)時(shí)同步。
當(dāng)然辣垒, 除了開源的CDC工具望侈, 也有不少成熟的商業(yè)化產(chǎn)品, 比如OGG勋桶、 DSG甜无、英方的i2stream, 對于希望得到企業(yè)軟件支持的用戶哥遮, 也可以選用這類產(chǎn)品岂丘。