Skip to content

Apache Cassandra

TwinCommit captures changes from Apache Cassandra by reading the CDC commit log segments each node writes for CDC-enabled tables. Because every replica records the same mutation, TwinCommit deduplicates mutations across nodes by partition key, clustering key and write timestamp before applying them.

Supported: Apache Cassandra 4.0, 4.1 and 5.0 · DataStax Enterprise 6.8 and 6.9.

cassandra.yaml
cdc_enabled: true
cdc_raw_directory: /var/lib/cassandra/cdc_raw
cdc_total_space: 4096MiB
cdc_on_repair_enabled: true

Restart each node after changing cassandra.yaml.

ALTER TABLE app.orders WITH cdc = true;

Cassandra writes CDC segments to local disk, so TwinCommit runs a lightweight reader on every node (twincommit run -role cassandra-reader). Each reader forwards mutations to the pipeline process, which deduplicates and applies them. Deploy the readers as a DaemonSet on Kubernetes or as a systemd unit on VMs.

CREATE ROLE twincommit WITH LOGIN = true AND PASSWORD = '********';
GRANT SELECT ON KEYSPACE app TO twincommit;
GRANT DESCRIBE ON ALL KEYSPACES TO twincommit;
source:
type: cassandra
contact_points: [cass-1.internal, cass-2.internal, cass-3.internal]
local_dc: dc1
user: twincommit
password: ${CASSANDRA_PASSWORD}
readers: 3 # number of node readers expected
  • Each node reader tails cdc_raw_directory, parses committed segments, and deletes segments after the pipeline acknowledges them.
  • The pipeline merges the streams from every node, keeps the first copy of each mutation and orders them by write timestamp.
  • Cassandra has no multi-partition transactions. Each mutation is applied as its own unit, and a LOGGED BATCH is applied atomically.
  • Counter tables and materialized views are not captured. Capture the base table instead.
  • If cdc_total_space fills because readers are down, Cassandra rejects writes to CDC tables. Alert on twincommit_lag_seconds and on free CDC space.
  • Lightweight transactions are captured as their final committed mutation.