CDC(Change data capture)是Cassandra提供的一種用于捕獲和歸檔資料寫入操作的機制,這個功能在3.8以上版本支援。當對一個表設定了“cdc=true”屬性之後,包含有這個表的資料的CommitLog在丢棄時會被移動到指定的目錄中,使用者可以自己編寫程式消費(解析并删除)這些日志,實作諸如增量資料導出、備份等功能。本文介紹CDC功能的使用并分析其特點。
配置參數
cassandra.yaml中,如下參數和CDC功能有關:
cdc_enabled (預設: false)
true表示節點上開啟cdc功能。
cdc_raw_directory (預設: $CASSANDRA_HOME/data/cdc_raw)
當一個Commitlog檔案不再需要保留(相關的改動已經全部從memtable持久化到sstable)時,會把日志檔案移動到這個目錄下。
cdc_free_space_in_mb: (預設: min(4096,磁盤空間的1/8))
當cdc_raw_directory目錄下的日志和目前正在寫入的日志占用空間超過這個值時,會停止開啟了cdc的表的寫入。
cdc_free_space_check_interval_ms (預設: 250)
計算日志占用空間的周期。
開啟表的CDC
通過如下語句可以在一個表上開啟CDC:
CREATE TABLE foo (a int, b text, PRIMARY KEY(a)) WITH cdc=true;
ALTER TABLE foo WITH cdc=true;
消費日志
CDC日志的格式和Commitlog是一緻的,在Cassandra中提供了解析Commitlog的類CommitLogReader,借助這個類,我們隻需要實作自己的CommitLogReadHandler類來處理捕獲的寫入操作就可以實作對CDC日志的消費。下面的示例代碼實作了一個簡單的功能:解析日志并把日志中的寫操作輸出到螢幕上。
pom檔案中增加如下依賴:
<dependency>
<groupId>org.apache.cassandra</groupId>
<artifactId>cassandra-all</artifactId>
<version>${cassandra.version}</version>
</dependency>
消費日志的代碼如下:
DatabaseDescriptor.toolInitialization();
CommitLogReader reader = new CommitLogReader();
CommitLogReadHandler handler = new CommitLogReadHandler() {
@Override public boolean shouldSkipSegmentOnError(CommitLogReadException e)
throws IOException {
return false;
}
@Override public void handleUnrecoverableError(CommitLogReadException e) throws IOException {
}
@Override public void handleMutation(Mutation mutation, int i, int i1,
CommitLogDescriptor commitLogDescriptor) {
for (PartitionUpdate partition : mutation.getPartitionUpdates()) {
System.out.println(partition.toString());
}
}
};
File dir = new File($CDC日志目錄);
while (true) {
String[] paths = dir.list();
if( paths.length == 0 ) {
Thread.sleep(1000);
}
for (String path : paths) {
File f = new File(dir, path);
reader.readAllFiles(handler, ArrayUtils.toArray(f));
f.delete();
}
}
運作時需要将Cassandra需要的路徑加入到classpath裡面(可以通過在腳本中調用bin/cassandra.in.sh實作),或者至少指定-Dcassandra.config和-Dcassandra.storagedir這兩個路徑作為啟動參數。這是因為在解析日志時需要表的meta資訊。
總結
CDC功能主要起到兩個作用:
(1)能夠将增量資料可靠的歸檔到CDC日志目錄下面。在CDC出現之前,我們隻能通過commitlog_archiving這樣的功能歸檔增量日志,但是commitlog_archiving的機制是調用指令行,在一些異常情況下可能會出現歸檔失敗。而CDC則可以保證日志在成功歸檔到CDC日志目錄中之前絕對不會被删除。
(2)可以起到反壓的作用,避免日志占用過多的磁盤空間。當日志量超過cdc_free_space_in_mb的配置後,開啟CDC的表會拒絕寫請求(抛出WriteTimeoutException)。
一些限制:
(1)通過CDC不能實時讀取到增量資料。根據我們前面分析的機制,隻有一個日志檔案寫滿并且不需要保留時才會移動到CDC目錄下面。
(2)CDC日志中不僅包含開啟了cdc功能的表,如果業務場景隻需要某個表的資料,需要自己過濾。
(3)在多副本的情況下,同一個(邏輯上的)寫入會在多個節點都寫入日志,是以如果業務上要求避免重複,需要自己做去重。
入群邀約
為了營造一個開放的 Cassandra 技術交流,我們建立了微信群公衆号和釘釘群,為廣大使用者提供專業的技術分享及問答,定期開展專家技術直播,歡迎大家加入。另外阿裡雲提供免費Cassandra試用:
https://www.aliyun.com/product/cds
釘釘群入群連結:
https://c.tb.cn/F3.ZRTY0o微信群公衆号: