CDC是個(gè)啥,它是如何工作的?
譯文【51CTO.com快譯】從廣泛意義上說,全球許多企業(yè)每天都需要通過頻繁的數(shù)據(jù)批量處理與加載,來定期將數(shù)據(jù)從一個(gè)數(shù)據(jù)庫遷移到另一個(gè)數(shù)據(jù)庫(或數(shù)據(jù)倉庫)。這類定期批量加載的工作,往往既耗費(fèi)時(shí)間,又會(huì)消耗原始系統(tǒng)的大量處理能力。因此,管理員只能在業(yè)務(wù)運(yùn)行的間歇期間運(yùn)行數(shù)據(jù)的批量傳輸與復(fù)制作業(yè),否則會(huì)產(chǎn)生嚴(yán)重的效率影響。而顯然,這與24x7的不間斷業(yè)務(wù)需求是背道而馳的。
近年來,變更數(shù)據(jù)捕獲(Change Data Capture,CDC)已成為了在高速數(shù)據(jù)流通環(huán)境中,各種關(guān)系型數(shù)據(jù)庫、云端數(shù)據(jù)庫、以及數(shù)據(jù)倉庫之間,進(jìn)行低延遲、高可靠性且可擴(kuò)展式數(shù)據(jù)復(fù)制的理想化解決方案。
什么是變更數(shù)據(jù)捕獲?
CDC是指從源數(shù)據(jù)庫捕獲到數(shù)據(jù)和數(shù)據(jù)結(jié)構(gòu)(也稱為模式)的增量變更,近乎實(shí)時(shí)地將這些變更,傳播到其他數(shù)據(jù)庫或應(yīng)用程序之處。通過這種方式,CDC能夠向數(shù)據(jù)倉庫提供高效、低延遲的數(shù)據(jù)傳輸,以便信息被及時(shí)轉(zhuǎn)換并交付給專供分析的應(yīng)用程序。
在數(shù)據(jù)不斷變化,且無法中斷與在線數(shù)據(jù)庫連接的情況下,對(duì)于各種時(shí)間敏感(time-sensitive)類信息的復(fù)制,往往也是云端遷移的重要組成部分。與批量復(fù)制相比,變更數(shù)據(jù)的捕獲通常具有如下三項(xiàng)基本優(yōu)勢:
- CDC通過僅發(fā)送增量的變更,來降低通過網(wǎng)絡(luò)傳輸數(shù)據(jù)的成本。
- CDC可以幫助用戶根據(jù)最新的數(shù)據(jù)做出更快、更準(zhǔn)確的決策。例如,CDC會(huì)將事務(wù)直接傳輸?shù)綄9┓治龅膽?yīng)用上。
- CDC最大限度地減少了對(duì)于生產(chǎn)環(huán)境網(wǎng)絡(luò)流量的干擾。
變更數(shù)據(jù)捕獲的方法
目前,業(yè)界有多種CDC方法,可用于跟蹤和傳輸變更的數(shù)據(jù),您可以根據(jù)應(yīng)用程序的實(shí)際要求,及其對(duì)于性能下降的容忍度,從中進(jìn)行選取。下面,我將向您介紹四種不同的CDC方法所涉及到的技術(shù)、工作原理、以及它們各自的優(yōu)缺點(diǎn)。
時(shí)間戳或版本號(hào)跟蹤
數(shù)據(jù)庫設(shè)計(jì)者可以在需要跟蹤的數(shù)據(jù)表中,設(shè)定某一列來代表最后被修改的時(shí)間戳或版本號(hào)。例如,我們通常可以將這些列命名為:LAST_UPDATE、DATE_MODIFIED、以及VERSION_NUMBER等。那些在上一次數(shù)據(jù)捕獲之后,增加了時(shí)間戳的任何行,都將被視為發(fā)生了修改。而在基于版本號(hào)的跟蹤方法中,變更一旦發(fā)生,所有具有最新版本號(hào)的數(shù)據(jù),都被視為發(fā)生了修改。
在實(shí)際應(yīng)用中,您可以結(jié)合版本和時(shí)間戳兩個(gè)維度,來跟蹤數(shù)據(jù)庫表中的數(shù)據(jù)。例如,您可以設(shè)定一條邏輯--“捕獲自2021年6月22日以來,相對(duì)于3.4版發(fā)生了變更的所有數(shù)據(jù)”。
優(yōu)點(diǎn):
- 簡單易懂。
- 數(shù)據(jù)庫設(shè)計(jì)者可以自定義應(yīng)用程序的邏輯構(gòu)建。
- 不需要任何外部的工具。
缺點(diǎn):
- 給數(shù)據(jù)庫增加了額外的開銷。
- 需要額外的CPU資源,來掃描表中的數(shù)據(jù)變更,并需要預(yù)留資源,以確保 LAST_UPDATE列能夠可靠地追蹤所有資源表。
- 被刪除的行不會(huì)存在于LAST_UPDATE中。如果沒有其他腳本來跟蹤此類刪除的話,DML語句(例如“DELETE”)將不會(huì)被傳遞到目標(biāo)數(shù)據(jù)庫處。
- 容易出錯(cuò),并可能導(dǎo)致數(shù)據(jù)出現(xiàn)一致性問題。
表的差異與增量
這種CDC方法使用諸如:表增量(table delta)之類的實(shí)用程序,或tablediff,去比較兩個(gè)表中的數(shù)據(jù),以發(fā)現(xiàn)不匹配的行。據(jù)此,您可以使用其他的腳本,將源表的差異同步到目標(biāo)表上。
雖然該方法在管理已刪除行的方面,比時(shí)間戳CDC的效果更好,但是它在發(fā)現(xiàn)差異時(shí),所需要的CPU資源較為顯著。而且此類開銷會(huì)隨著數(shù)據(jù)數(shù)量的增加,而呈線性增加。此外,針對(duì)源數(shù)據(jù)庫或生產(chǎn)環(huán)境的分析查詢,也可能會(huì)降低應(yīng)用本身的性能。對(duì)此,您可以定期將數(shù)據(jù)庫導(dǎo)出至?xí)捍姝h(huán)境中進(jìn)行比較。不過,隨著數(shù)據(jù)量的增加,此類傳輸?shù)某杀疽矔?huì)呈指數(shù)級(jí)增長。
表差異的另一個(gè)問題是,它無法捕獲數(shù)據(jù)的臨時(shí)性變更。例如,假設(shè)有人更新了某個(gè)字段,但隨后又將其變更回了原始值。那么,如果您只是運(yùn)行一個(gè)簡單比較的話,將無法捕獲到這個(gè)變更事件。而由于diff方法本身存在著延遲,因此也無法實(shí)時(shí)執(zhí)行。
優(yōu)點(diǎn):
- 可使用各種原生的SQL腳本,來獲取變更數(shù)據(jù)的準(zhǔn)確視圖。
缺點(diǎn):
- 由于此方法會(huì)用到數(shù)據(jù)源的三個(gè)副本:原始數(shù)據(jù)、先前快照和當(dāng)前快照,因此整體存儲(chǔ)需求會(huì)有所增加。
- 在那些具有繁重事務(wù)負(fù)載的應(yīng)用程序中,無法得到很好的擴(kuò)展。
注意:表差異和時(shí)間戳CDC方法,都不適用于真實(shí)的生產(chǎn)環(huán)境。因此對(duì)于大型數(shù)據(jù)集,我建議您使用如下兩種CDC方法。其實(shí),基于觸發(fā)器和事務(wù)日志的變更數(shù)據(jù)跟蹤方法,只是出于相同目的的兩種不同的服務(wù)方式。
基于觸發(fā)器的CDC
- 我們需要為參與數(shù)據(jù)復(fù)制的每個(gè)表,創(chuàng)建三個(gè)觸發(fā)器,當(dāng)數(shù)據(jù)記錄發(fā)生如下特定事件時(shí),則會(huì)觸發(fā)相應(yīng)的操作:
- 將新的記錄插入數(shù)據(jù)表時(shí),觸發(fā)的是INSERT觸發(fā)器。
- 數(shù)據(jù)記錄發(fā)生變更時(shí),觸發(fā)的是UPDATE觸發(fā)器。
- 數(shù)據(jù)記錄被刪除時(shí),觸發(fā)的是DELETE觸發(fā)器。
- “事件歷史”的影子表被存儲(chǔ)在數(shù)據(jù)庫本身,并由各種狀態(tài)改變事件的序列所組成。
- 每當(dāng)對(duì)象的狀態(tài)發(fā)生變化時(shí),新的事件都會(huì)被附加到該序列中。據(jù)此,有關(guān)變更記錄的信息,也會(huì)被轉(zhuǎn)移到“事件歷史”的影子表中。
- 最后,根據(jù)歷史表中的各個(gè)事件,變更會(huì)被傳輸?shù)侥繕?biāo)數(shù)據(jù)庫中。
下面展示了一個(gè)簡單的歷史表:
由于源數(shù)據(jù)庫中的每個(gè)表都需要一個(gè)觸發(fā)器,因此在有變更發(fā)生時(shí),在操作表上運(yùn)行觸發(fā)器的開銷也會(huì)隨之增加。不過,由于基于觸發(fā)器的CDC是工作在SQL級(jí)別上的,因此許多用戶會(huì)趨向于使用該方法。
優(yōu)點(diǎn):
- 非常可靠且詳盡。
- 影子表可以提供所有事務(wù)的不可變?cè)敿?xì)日志。
缺點(diǎn):
- 每次插入、更新或刪除數(shù)據(jù)行時(shí),都需要對(duì)數(shù)據(jù)庫進(jìn)行多次寫入,此舉降低了數(shù)據(jù)庫的性能。
DBA和數(shù)據(jù)工程師應(yīng)當(dāng)持續(xù)關(guān)注并測試,那些被添加到生產(chǎn)環(huán)境中的各種觸發(fā)器的性能,進(jìn)而決定是否可以容忍此類額外產(chǎn)生的開銷。
事務(wù)日志CDC
眾所周知,數(shù)據(jù)庫雖然主要會(huì)將事務(wù)日志用于備份和恢復(fù)目的,但它們也可被用于將變更復(fù)制到目標(biāo)數(shù)據(jù)庫或數(shù)據(jù)湖中。而在基于事務(wù)日志的CDC系統(tǒng)中,數(shù)據(jù)流不會(huì)被持久性存儲(chǔ)。它們會(huì)使用Kafka去捕獲變更,并將變更推送到目標(biāo)數(shù)據(jù)庫中。
可見,基于事務(wù)日志的CDC和基于觸發(fā)器的CDC之間的主要區(qū)別在于,每個(gè)變更都將進(jìn)入由數(shù)據(jù)庫引擎所生成的事務(wù)日志中。也就是說,數(shù)據(jù)庫引擎會(huì)使用本機(jī)事務(wù)日志(也稱為重做日志),來存儲(chǔ)所有數(shù)據(jù)庫的事件,以便在發(fā)生故障時(shí),可以恢復(fù)數(shù)據(jù)庫。它們無需執(zhí)行任何應(yīng)用程序級(jí)別的變更,或掃描影子表。因此,與基于觸發(fā)器的CDC相比,從事務(wù)日志中恢復(fù)數(shù)據(jù)雖然更為復(fù)雜,但是會(huì)更加可行。
優(yōu)點(diǎn):
- 由于每個(gè)事務(wù)都不需要額外的查詢,因此它對(duì)生產(chǎn)環(huán)境中的數(shù)據(jù)庫系統(tǒng)的影響最小。
- 無需變更生產(chǎn)環(huán)境中數(shù)據(jù)庫系統(tǒng)的架構(gòu),或添加額外的數(shù)據(jù)表。
缺點(diǎn):
- 由于大多數(shù)數(shù)據(jù)庫并不記錄它們的事務(wù)日志格式,也不會(huì)在新的版本中公布對(duì)其實(shí)施的變更,因此DBA解析數(shù)據(jù)庫的內(nèi)部日志格式會(huì)較為困難。DBA有時(shí)需要在數(shù)據(jù)庫的每個(gè)新版本中,去解析變更數(shù)據(jù)庫的日志邏輯。
- 由于日志文件通常會(huì)被數(shù)據(jù)庫引擎予以歸檔,因此CDC軟件必須在此之前讀取日志,或者能夠讀取已歸檔的日志。
- 創(chuàng)建可掃描的事務(wù)日志所需要的額外日志級(jí)別,可能會(huì)增加少量的性能開銷。
- 當(dāng)CDC應(yīng)用程序發(fā)送數(shù)據(jù)時(shí),目標(biāo)數(shù)據(jù)庫可能會(huì)意外地變得不可訪問。它們必須緩沖未發(fā)送的數(shù)據(jù),直到目標(biāo)數(shù)據(jù)庫重新聯(lián)機(jī)上線。當(dāng)然,如果未能完成該步驟,則可能導(dǎo)致數(shù)據(jù)的丟失或重復(fù)。
- 同樣,如果源與目標(biāo)之間的傳輸連接出現(xiàn)中斷,系統(tǒng)也可能會(huì)發(fā)生故障,進(jìn)而導(dǎo)致數(shù)據(jù)的丟失、記錄的重復(fù)、以及需要從初始數(shù)據(jù)處重新啟動(dòng)加載。
基于觸發(fā)器與事務(wù)日志的比較
總的說來,基于觸發(fā)器的CDC和事務(wù)日志CDC,都是可用于構(gòu)建反應(yīng)式分布式系統(tǒng)的數(shù)據(jù)庫設(shè)計(jì)模型。其中,基于觸發(fā)器的CDC使用自己的事件日志,作為真實(shí)的數(shù)據(jù)來源,而事務(wù)日志CDC則依賴底層數(shù)據(jù)庫的事務(wù)日志作為真實(shí)來源。
觸發(fā)器可作為每個(gè)數(shù)據(jù)庫事務(wù)的一部分,以捕獲實(shí)時(shí)發(fā)生的事件。對(duì)于每次插入、更新或刪除,都會(huì)由某個(gè)觸發(fā)器去觸發(fā)記錄的變更。另一方面,事務(wù)日志CDC則可以獨(dú)立于事務(wù)運(yùn)行。它使用重做日志文件來記錄的變更。由于CDC操作在發(fā)生時(shí)不會(huì)直接與數(shù)據(jù)庫中的每個(gè)事務(wù)相關(guān)聯(lián),因此其性能會(huì)有所提升。
在實(shí)際應(yīng)用中,各種常見的DBSync產(chǎn)品和DBConvert Studio都會(huì)使用基于觸發(fā)器的數(shù)據(jù)庫同步CDC方法。不過,對(duì)于集群數(shù)據(jù)庫而言,基于觸發(fā)器的方法可能會(huì)比使用MySQL的二進(jìn)制日志、或PostgreSQL的事務(wù)日志,要相差許多。畢竟,MySQL在其官網(wǎng)上已聲稱:“在啟用二進(jìn)制日志的情況下,服務(wù)器的運(yùn)行性能可能會(huì)被略微拖慢。但是,二進(jìn)制日志在方便復(fù)制與恢復(fù)操作等方面的好處,通常超過性能上的微降。”(https://dev.mysql.com/doc/refman/8.0/en/binary-log.html)
小結(jié)
綜上所述,CDC是現(xiàn)代數(shù)據(jù)架構(gòu)的重要組成部分,可被用于將事務(wù)數(shù)據(jù)從源系統(tǒng),傳輸?shù)綌?shù)據(jù)流中。我們需要它支持實(shí)時(shí)的事務(wù)數(shù)據(jù),且不會(huì)對(duì)源系統(tǒng)造成重大的負(fù)載。它既不需要改變?cè)磻?yīng)用程序,又要保證僅傳輸最少量的數(shù)據(jù)。因此,CDC更適合大體量的數(shù)據(jù)集。將來,我們會(huì)在那些強(qiáng)調(diào)數(shù)據(jù)分析和歷史數(shù)據(jù)比較的企業(yè)級(jí)數(shù)據(jù)倉庫中,看到CDC的廣泛使用。
原文標(biāo)題:Change Data Capture (CDC): What Is It and How Does It Work?,作者: Dmitry Narizhnykh
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】





































