天天看點

Cassandra CDC初體驗配置參數開啟表的CDC消費日志總結入群邀約

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
Cassandra CDC初體驗配置參數開啟表的CDC消費日志總結入群邀約

釘釘群入群連結:

https://c.tb.cn/F3.ZRTY0o

微信群公衆号:

Cassandra CDC初體驗配置參數開啟表的CDC消費日志總結入群邀約