Overview
The DataStax Cassandra Sink Connector consumes records from Kafka topics and maps fields from message keys, values, or headers to target tables in Apache Cassandra or DataStax Enterprise. It sits between Kafka and Cassandra and is suitable for continuously writing business events, entity states, and log data to a storage model organized by keyspaces and tables. Each topic can be configured with one or more target tables. The Connector generates CQL write statements from the mapping, and can also use a custom Prepared Statement; when the same Kafka record is written to multiple tables, writes to each table are independent. Plan the target keyspace, table, columns, and primary keys in advance; the mapping defines the relationship between Kafka fields and Cassandra columns.Prerequisites
- Create the target Keyspace and Table in Cassandra in advance, and ensure that the connection account can read table metadata and perform the required write or delete operations; columns referenced by the mapping must exist, and automatically generated CQL must cover all primary-key columns.
License
Uses the DataStax Apache Kafka Connector License Terms. The release package contains inconsistent license labels. Before using or redistributing it, check the bundled license files and complete your customer-side review.Quick Start
Prepare the Connect Cluster, Kafka, Cassandra Keyspace, and target table in advance, and confirm network connectivity and access permissions. For preparation and management operations, see Manage Connectors. The following example subscribes to theorders topic, writes the message key to order_id, and writes customer_id and status from the message value to the app.orders table. The target table should use order_id as its primary key and include these columns.
<cassandra-host> with a Cassandra contact point and <local-dc> with the name of the data center that contains that node. If the topic, keyspace, table, or field names differ, update topics, the dynamic configuration keys, and mapping accordingly; after startup, send records with a stable key and customer_id and status fields, then check the corresponding row in app.orders.
Configuration
Kafka Connect and Subscription
connector.class
Specifies the Connector implementation class to load.
- Type:
string - Default: None
- Importance: High
- Valid values / Notes: Use
com.datastax.oss.kafka.sink.CassandraSinkConnector. The old class namecom.datastax.kafkaconnector.DseSinkConnectoris retained only as a deprecated compatibility alias. - Required: Yes
tasks.max
Sets the maximum number of Tasks allowed to start.
- Type:
int - Default:
1 - Importance: High
- Valid values / Notes: At least
1. The actual number of Tasks does not exceed the number of Topic Partitions that can be assigned; increasing the number of Tasks does not guarantee linear throughput growth.
topics
Explicitly lists the Kafka Topics to consume.
- Type:
list - Default: Empty list
- Importance: High
- Valid values / Notes: Separate values with commas. Configure exactly one of
topicsandtopics.regex; every explicitly listed Topic must have at least one correspondingtopic.<topic>.<keyspace>.<table>.*table configuration.
topics.regex
Subscribes to Kafka Topics using a Java regular expression.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: Configure exactly one of
topicsandtopics.regex. A Topic newly matched by the regular expression still requires an exactly correspondingtopic.<topic>.*configuration; otherwise mapping fails when records arrive.
Cassandra Connection
contactPoints
Sets the initial Cassandra contact points.
- Type:
list - Default: Empty list
- Importance: High
- Valid values / Notes: Enter comma-separated IP addresses or hostnames; all nodes use the same port specified by
port. When non-empty, the local data center must also be configured, and this setting cannot be used withcloud.secureConnectBundle. To specify different ports for different nodes, use the Java Driver native contact-point configuration instead.
port
Sets the Cassandra native transport port used by contactPoints.
- Type:
int - Default:
9042 - Importance: High
- Valid values / Notes: At least
1; ignored when a secure connect bundle is used.
loadBalancing.localDc
Sets the local data center that contains the contact points.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: Required when
contactPointsis non-empty; must be left empty when a secure connect bundle is used. If the replacement setting is also configured, this setting takes precedence. - Deprecated: Yes
- Replacement:
datastax-java-driver.basic.load-balancing-policy.local-datacenter
cloud.secureConnectBundle
Sets the path to the DataStax Cloud secure connect bundle.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: A non-empty value enables cloud connection mode and cannot be used with
contactPoints,loadBalancing.localDc, or anyssl.*setting. Cloud mode changes theANY,ONE, andLOCAL_ONEwrite consistency levels toLOCAL_QUORUM. If the replacement setting is also configured, this setting takes precedence. - Deprecated: Yes
- Replacement:
datastax-java-driver.basic.cloud.secure-connect-bundle
Authentication
auth.provider
Selects the Cassandra authentication provider.
- Type:
string - Default:
None - Importance: High
- Valid values / Notes: Case-sensitive; choose
None,PLAIN, orGSSAPI. When a username or password is configured,PLAINis used in practice even if this setting isNone.
auth.username
Sets the PLAIN authentication username.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: Used for
PLAINauthentication; when a non-empty password is configured, the username must also be non-empty.
auth.password
Sets the PLAIN authentication password.
- Type:
password - Default: Empty string
- Importance: High
- Valid values / Notes: Used for
PLAINauthentication. Inject it through a secure configuration mechanism; do not expose the plaintext password in logs or shared files.
auth.gssapi.keyTab
Sets the path to the Kerberos keytab file.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: A non-empty path must point to a regular file readable by the Worker. When a keytab is used without a principal, the first principal in the keytab can be inferred; without a keytab, the Driver uses the ticket cache.
auth.gssapi.principal
Sets the Kerberos principal.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: Used only for
GSSAPI. Omitting this setting and explicitly configuring an empty string have different behavior; inference from the keytab is available only when the setting is omitted.
auth.gssapi.service
Sets the GSSAPI SASL service name.
- Type:
string - Default:
dse - Importance: High
- Valid values / Notes: Must be a non-empty string when using
GSSAPIand must match the Cassandra server configuration.
TLS
ssl.provider
Selects the TLS implementation provider.
- Type:
string - Default:
None - Importance: High
- Valid values / Notes: Case-sensitive; choose
None,JDK, orOpenSSL. When a secure connect bundle is used, nossl.*setting may be configured.
ssl.cipherSuites
Sets the TLS cipher suites that may be used.
- Type:
list - Default: Empty list
- Importance: High
- Valid values / Notes: Separate values with commas; an empty list uses the defaults of the selected TLS provider. Cannot be configured with a secure connect bundle.
ssl.hostnameValidation
Controls whether Cassandra node hostnames are validated.
- Type:
boolean - Default:
true - Importance: High
- Valid values / Notes: When
true, JDK SSL resolves contact-point addresses and enables hostname validation. Cannot be configured with a secure connect bundle.
ssl.keystore.password
Sets the JDK SSL keystore password.
- Type:
password - Default: Empty string
- Importance: High
- Valid values / Notes: Used to access the JDK SSL keystore. Inject it securely, and do not configure it with a secure connect bundle.
ssl.keystore.path
Sets the JDK SSL keystore path.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: A non-empty path must point to a regular file readable by the Worker. Cannot be configured with a secure connect bundle.
ssl.openssl.keyCertChain
Sets the path to the OpenSSL client certificate chain.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: A non-empty path must point to a regular file readable by the Worker. When using
OpenSSL, configure this setting andssl.openssl.privateKeytogether or omit both; cannot be configured with a secure connect bundle.
ssl.openssl.privateKey
Sets the path to the OpenSSL client private key.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: A non-empty path must point to a regular file readable by the Worker. When using
OpenSSL, configure this setting andssl.openssl.keyCertChaintogether or omit both; protect the private-key file permissions, and do not configure it with a secure connect bundle.
ssl.truststore.password
Sets the TLS truststore password.
- Type:
password - Default: Empty string
- Importance: High
- Valid values / Notes: Used to load the truststore when initializing JDK or OpenSSL. Inject it securely, and do not configure it with a secure connect bundle.
ssl.truststore.path
Sets the TLS truststore path.
- Type:
string - Default: Empty string
- Importance: High
- Valid values / Notes: A non-empty path must point to a regular file readable by the Worker; OpenSSL mode loads the file as JKS. Cannot be configured with a secure connect bundle.
Write Throughput and Requests
maxConcurrentRequests
Limits the number of in-flight Cassandra requests for this Connector instance within the same Worker JVM.
- Type:
int - Default:
500 - Importance: High
- Valid values / Notes: At least
1. Multiple Tasks of Connectors with the same name in the same Worker JVM share this limit; it is not shared across Workers.
maxNumberOfRecordsInBatch
Sets the maximum number of records in one Cassandra batch request.
- Type:
int - Default:
32 - Importance: High
- Valid values / Notes: At least
1. The Connector buckets records by Topic, target table, and Cassandra Routing Key; multiple statements use an UNLOGGED batch, while a single statement is executed asynchronously.
compression
Sets the Cassandra protocol compression algorithm.
- Type:
string - Default:
None - Importance: High
- Valid values / Notes: Case-insensitive; choose
none,snappy, orlz4. If the replacement setting is also configured, this setting takes precedence. - Deprecated: Yes
- Replacement:
datastax-java-driver.advanced.protocol.compression
queryExecutionTimeout
Sets the CQL request timeout in seconds.
- Type:
int - Default:
30 - Importance: High
- Valid values / Notes: At least
1; the value is passed to the Java Driver in seconds. If the replacement setting is also configured, this setting takes precedence. - Deprecated: Yes
- Replacement:
datastax-java-driver.basic.request.timeout
connectionPoolLocalSize
Sets the connection-pool size for each local Cassandra node.
- Type:
int - Default:
4 - Importance: High
- Valid values / Notes: At least
1. If the replacement setting is also configured, this setting takes precedence. - Deprecated: Yes
- Replacement:
datastax-java-driver.advanced.connection.pool.local.size
Error Handling and Metrics
ignoreErrors
Controls whether the Connector ignores record-mapping or Cassandra Driver write errors.
- Type:
string - Default:
None - Importance: High
- Valid values / Notes: Case-insensitive; choose
None,Driver, orAll.Driverignores only database Driver write failures;Allalso ignores mapping failures. Ignoring errors can allow the Offset to pass failed records, and the Connector does not automatically write those records again. This policy is independent of Kafka Connect’serrors.tolerance.
jmx
Controls whether the default Java Driver JMX session metrics are enabled.
- Type:
boolean - Default:
true - Importance: High
- Valid values / Notes: When
trueand no Driver metric list is explicitly configured, enablescql-requestsandcql-client-timeouts; the default sampling interval forcql-requestsis 30 seconds.
metricsHighestLatency
Sets the highest latency range in seconds for CQL request metrics.
- Type:
int - Default:
35 - Importance: High
- Valid values / Notes: At least
1; should normally be greater than the request timeout. This relationship is not enforced by validation. If the replacement setting is also configured, this setting takes precedence. - Deprecated: Yes
- Replacement:
datastax-java-driver.advanced.metrics.session.cql-requests.highest-latency
Topic Data Conversion
topic.<topic>.codec.locale
Sets the text-conversion locale for the specified Topic.
- Type:
string - Default:
en_US - Importance: High
- Valid values / Notes:
<topic>may contain only letters, digits, periods, underscores, and hyphens; the locale value must be parseable by the DSBulk Codec.
topic.<topic>.codec.timeZone
Sets the time-conversion time zone for the specified Topic.
- Type:
string - Default:
UTC - Importance: High
- Valid values / Notes: Must be a time zone recognized by
java.time.ZoneId, such asAsia/Shanghai.
topic.<topic>.codec.timestamp
Sets the format used when converting strings to CQL timestamp values.
- Type:
string - Default:
CQL_TIMESTAMP - Importance: High
- Valid values / Notes: May use time patterns supported by the DSBulk Codec,
DateTimeFormatterconstants, orCQL_TIMESTAMP.
topic.<topic>.codec.date
Sets the format used when converting strings to CQL date values.
- Type:
string - Default:
ISO_LOCAL_DATE - Importance: High
- Valid values / Notes: May use date patterns supported by the DSBulk Codec or
DateTimeFormatterconstants.
topic.<topic>.codec.time
Sets the format used when converting strings to CQL time values.
- Type:
string - Default:
ISO_LOCAL_TIME - Importance: High
- Valid values / Notes: May use time patterns supported by the DSBulk Codec or
DateTimeFormatterconstants.
topic.<topic>.codec.unit
Sets the time unit for numeric-only time inputs.
- Type:
string - Default:
MILLISECONDS - Importance: High
- Valid values / Notes: Must be exactly
NANOSECONDS,MICROSECONDS,MILLISECONDS,SECONDS,MINUTES,HOURS, orDAYS.
Table Mapping and Write Semantics
topic.<topic>.<keyspace>.<table>.mapping
Defines the mapping from Kafka fields to Cassandra columns or custom-query bind variables.
- Type:
string - Default: None
- Importance: High
- Valid values / Notes: Every target table must have a non-empty mapping in the comma-separated form
column=field expression. Field expressions supportkey,value,key.*,value.*,header.*,now(), and the reserved pseudo-columns__ttland__timestamp. With automatically generated CQL, ordinary columns must exist and all primary-key columns must be mapped. - Required: Yes
topic.<topic>.<keyspace>.<table>.deletesEnabled
Controls whether a full mapping record generates a full-row delete.
- Type:
boolean - Default:
true - Importance: High
- Valid values / Notes: Only when no custom query is used and the mapping covers all columns in the target table, a record whose mapped values other than the primary key are all
nulldeletes the full row. Must be set tofalsewhen a customqueryis configured.
topic.<topic>.<keyspace>.<table>.consistencyLevel
Sets the consistency level for writes to the target table.
- Type:
string - Default:
LOCAL_ONE - Importance: High
- Valid values / Notes: Use a consistency-level name supported by the DataStax Driver; the value is case-insensitive. Cloud mode changes
ANY,ONE, andLOCAL_ONEtoLOCAL_QUORUM.
topic.<topic>.<keyspace>.<table>.ttl
Sets a fixed TTL for writes to the target table.
- Type:
int - Default:
-1 - Importance: High
- Valid values / Notes: At least
-1;-1disables a fixed TTL. The value is converted to seconds according tottlTimeUnit; a dynamic__ttlvalue in the mapping takes precedence. Counter tables cannot use TTL, and custom queries determine their own TTL semantics.
topic.<topic>.<keyspace>.<table>.nullToUnset
Controls whether non-primary-key null values are treated as Cassandra UNSET.
- Type:
boolean - Default:
true - Importance: High
- Valid values / Notes: When
true, a non-primary-keynulldoes not overwrite the existing column value; whenfalse,nullis explicitly bound. Anullprimary key always fails.
topic.<topic>.<keyspace>.<table>.ttlTimeUnit
Sets the input unit for the fixed TTL and mapping __ttl values.
- Type:
string - Default:
SECONDS - Importance: High
- Valid values / Notes: Must be exactly
NANOSECONDS,MICROSECONDS,MILLISECONDS,SECONDS,MINUTES,HOURS, orDAYS.
topic.<topic>.<keyspace>.<table>.timestampTimeUnit
Sets the input unit for the mapping __timestamp values.
- Type:
string - Default:
MICROSECONDS - Importance: High
- Valid values / Notes: Must use a
TimeUnitenum value. When__timestampis not mapped and no custom query is used, the Connector converts the Kafka record timestamp from milliseconds to microseconds for the CQL write timestamp.
topic.<topic>.<keyspace>.<table>.query
Sets a custom Prepared Statement CQL query for the target table.
- Type:
string - Default:
null - Importance: High
- Valid values / Notes: A non-
nullvalue replaces the automatically generated INSERT or Counter UPDATE and requiresdeletesEnabled=false. Bind variables must be provided bymapping; the Connector no longer automatically validates table columns, primary keys, TTL, timestamps, or delete semantics. An empty string is also treated as configured and fails during database preparation.
Java Driver Passthrough
datastax-java-driver.<driver-path>
Passes native DataStax Java Driver configuration to the Driver.
- Type:
string - Default: No ConfigDef default
- Importance: Not declared
- Valid values / Notes: Use the
datastax-java-driver.<driver-path>form; the path, value, default, and validation rules are determined by the Java Driver supplied with the Connector. List paths for contact points, keyspace refresh, node metrics, session metrics, and TLS cipher suites are split on commas; when an old Connector alias and the corresponding Driver path are both configured, the old alias takes precedence.
Best Practices
Synchronize Business Deletes to Cassandra
Applicable business scenario: Basic writes are already stable, and the upstream system represents entity deletion with a record that retains the primary key while setting all other business fields tonull. The target table has a stable column structure, and the mapping can cover every column in the table.
Configuration example: Change the delete switch in the Quick Start configuration to true. The complete Connector configuration is shown below so that the write before deletion and the subsequent deletion result can be verified independently.
customer_id and status are null, the Connector deletes the full row by order_id. If only some columns are mapped, the record still follows the write path. Custom query and automatic deletion are mutually exclusive; do not enable both.
Scale Write Throughput by Topic Partition
Applicable business scenario: A single Task writes correctly, but Kafka consumer lag continues to grow; theorders Topic has multiple Partitions, and the Cassandra cluster and Worker still have available capacity. You want to gradually increase parallel consumption and the number of in-flight requests.
Configuration example: The following configuration raises the Task limit to 4 on the safe-write baseline from Quick Start and uses explicit initial values for requests and batches. Validate it in a load-test environment before production, then adjust each value according to actual latency and Cassandra load.
tasks.max=4 is only the Task limit; actual parallelism does not exceed the number of Topic Partitions. maxConcurrentRequests is shared by all Tasks of Connectors with the same name within the same Worker JVM; adding Workers also adds independent Sessions and total concurrency. Batches are bucketed by target table and Cassandra Routing Key, and 64 is not a universally optimal value. Compare Kafka Lag, write throughput, request latency, timeouts, and Cassandra load before and after changes, and do not rely on global ordering across Partitions, Tasks, or batches.
Monitoring
What to Monitor
Monitor Kafka Connect health, Connector and Task status, throughput, latency, Offset commits, errors, retries, and Worker JVM signals; monitor DLQ activity only when the corresponding error handling is enabled.Import the Grafana Dashboard
Confirm that Connect metrics are connected to a Grafana data source and that collection labels meet the dashboard’s filtering requirements; download the Kafka Connect Dashboard, import the JSON in Grafana, and select the corresponding data source.Limitations
- The Connector does not create Keyspaces, Tables, or columns automatically, nor does it automatically adapt to incompatible table-schema changes; after changing the target Schema or mapping, restart the Task so that it rereads metadata and prepares CQL again.
- Cassandra writes and Kafka Offset commits are not atomic transactions; failure recovery may replay records that were written successfully but whose Offset had not been committed, so exactly-once or duplicate-free guarantees are not provided.
- When the same record is written to multiple target tables, no cross-table transaction is provided; if a failure occurs after some tables have been written successfully, replay may write those tables again.
- Counter,
now(), TTL, custom CQL, and deletes each have their own replay side effects; do not assume that the idempotency characteristics of ordinary Upserts apply to these write modes.
FAQ
The Task reports an invalid mapping or target column at startup
The target Keyspace, Table, or column may not exist, the mapping may omit a primary-key column, or the Topic, Keyspace, or Table in a dynamic configuration key may not match the actual resource. First verify the target table Schema, then check every target column and field expression intopic.<topic>.<keyspace>.<table>.mapping; when CQL is generated automatically, ensure that every primary-key column is mapped, then restart the Connector after making changes.
The Connector is running, but some records are not written to Cassandra
Writes may fail when a record lacks a required mapped field, a primary-key value isnull, a type cannot be converted, or a Cassandra request fails; enabling ignoreErrors=Driver or All may also allow the Offset to pass failed records. Check Task logs, error counts, and consumer Offsets, confirm that the mapped fields match the message structure, and prefer ignoreErrors=None while investigating and fixing the root cause; records that were ignored must be compensated for separately according to the business process.