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