Apache Kafka® integration reference
Use these options and properties to configure the Kafka integration, including message format, Avro schema mapping, index options, examples, and configuration settings. For setup instructions, see Integrate Apache Kafka® with Hyper-Converged Database (HCD).
Supported versions
The HCD Kafka integration is tested and verified with the following versions:
| Component | Supported version | Notes |
|---|---|---|
Confluent Platform |
7.9 or later |
Maps to Apache Kafka® 3.9.x. |
Confluent Schema Registry |
7.9 or later |
Required when using |
Message format
Every HCD mutation produces one Kafka message.
The format index option (json or avro) controls the serialization format.
Both formats share the same structure for key, value, and headers.
The message key contains all primary key columns (partition key and clustering columns).
-
JSON: A JSON object. For example,
{"id": 42}or{"tenant": "acme", "id": 42}. -
Avro: A
GenericRecordwhose schema covers the same primary-key columns.
The message value contains the non-primary-key column values for an INSERT or UPDATE, or null (a Kafka tombstone) for a DELETE.
-
JSON: A JSON object. For example,
{"name": "Widget", "price": 9.99}, ornullforDELETE. -
Avro: A
GenericRecord(all value fields are nullable unions with defaultnull), ornullforDELETE.
When you configure a column projection, only the projected columns appear in the value. Primary-key columns are always included in the key regardless of projection.
Headers are UTF-8 string values attached to every record regardless of format:
-
rowVersion: The row write-timestamp as a decimal string (microseconds since Unix epoch). For example,"1718000000000000". Present on most live writes. Corresponds toWRITETIME(). Use it for last-write-wins semantics or reordering detection. -
late: Set to"true"when the mutation arrived out of order (for example, a late or compensating write). Normal, in-order inserts and updates do not carry this header.
If your application cannot handle the rowVersion and late headers, enable deduplication.
Avro format and Schema Registry
When format=avro is set on the index, HCD does the following:
-
Derives schemas automatically from the HCD table metadata at index-creation time.
-
Registers schemas in the Confluent Schema Registry under the standard Confluent subjects:
<topic>-keyand<topic>-value. -
Serializes both key and value using
KafkaAvroSerializer. -
For a
DELETE, sends an Avro-encoded key with anullvalue (tombstone).
|
|
CQL to Avro type mapping
The schema builder maps every HCD CQL type to a semantically equivalent Avro type, as shown in the following table:
| CQL type | Avro base type | Avro logical type | Notes |
|---|---|---|---|
|
|
N/A |
|
|
|
N/A |
|
|
|
N/A |
|
|
|
N/A |
|
|
|
N/A |
|
|
|
N/A |
|
|
|
N/A |
|
|
|
|
RFC-4122 UUID string. |
|
|
|
Milliseconds since Unix epoch. |
|
|
|
Days since Unix epoch. |
|
|
|
Microseconds since midnight. |
|
|
|
Big-endian two’s-complement bytes. |
|
|
|
Unscaled value and scale. |
|
|
|
Three-component CQL duration. |
|
|
N/A |
Element type mapped recursively.
Frozen and non-frozen both produce |
|
|
N/A |
Keys always stringified to |
|
|
N/A |
Positional fields named |
UDT |
|
N/A |
Record name = UDT name. Namespace = UDT keyspace. Each field is a nullable union. |
|
|
N/A |
HCD only. Fixed-length array of N elements. |
|
|
N/A |
HCD-only geospatial types.
No Avro equivalent.
Logs |
|
|
N/A |
HCD-only type.
No Avro equivalent.
Logs |
All non-primary-key value fields are wrapped as nullable unions ["null", <type>] with default null to accommodate HCD’s sparse row model and partial updates.
Index options
Pass all options as string values inside WITH OPTIONS = { … }.
The fully qualified class name for the KafkaReplicator custom index is com.datastax.kafka.KafkaReplicator.
When the implementation is registered as a trusted secondary index, use the short form KafkaReplicator directly.
Topic and lifecycle
The options that control the Kafka topic and initial build behavior of the index:
| Option | Default | Description |
|---|---|---|
|
|
The Kafka topic to produce messages to. Must be non-blank if supplied. |
|
|
When |
|
|
Number of partitions when auto-creating the topic.
Also the default for |
|
|
Replication factor when auto-creating the topic.
Also the default for |
|
|
When |
Deduplication
These options control the optional deduplication pipeline. For more information, see Deduplication.
The deduplication options:
| Option | Default | Description |
|---|---|---|
|
|
When |
|
|
Name of the intermediate events topic used when |
|
Value of |
Number of partitions for the events topic when HCD auto-creates it. |
|
Value of |
Replication factor for the events topic when HCD auto-creates it. |
|
|
Kafka consumer group ID shared by all |
Serialization format
The option that controls the serialization format of Kafka messages:
| Option | Default | Description |
|---|---|---|
|
|
Serialization format for Kafka messages.
Accepted values: |
Column projection
These options control which columns are replicated in the message value. Primary-key columns are always included in the message key.
The column projection options:
| Option | Default | Description |
|---|---|---|
|
(none) |
Columns specified between the parentheses in |
|
(all non-PK columns) |
Comma-separated list of non-primary-key columns to include in the message value. Omit to include every column. |
Non-primary replica processing
The option that controls whether non-primary HCD replicas participate in replication:
| Option | Default | Description |
|---|---|---|
|
|
When |
Tables that cannot be indexed
CREATE CUSTOM INDEX raises InvalidRequestException for the following table types:
-
Tables with static columns.
-
Tables with counter columns.
Index examples
The following examples show common CREATE CUSTOM INDEX configurations for different deployment scenarios.
Minimal JSON setup
Create a basic index with an explicit topic name. This example assumes that you enabled the Kafka integration and configured the broker connection as described in Integrate Apache Kafka® with Hyper-Converged Database (HCD):
CREATE TABLE ks.products (
id int PRIMARY KEY,
name text,
price float
);
CREATE CUSTOM INDEX products_kafka
ON ks.products (name, price)
USING 'KafkaReplicator'
WITH OPTIONS = {'topicName': 'ks.products'};
-- INSERT: key: {"id":42} value: {"name":"Widget","price":9.99}
INSERT INTO ks.products (id, name, price) VALUES (42, 'Widget', 9.99);
-- DELETE: key: {"id":42} value: null (tombstone)
DELETE FROM ks.products WHERE id = 42;
Avro format with Schema Registry
Use Avro serialization to automatically derive and register schemas in the Confluent Schema Registry:
-- Additional system property required:
-- -Dcassandra.kafka.schema.registry.url=http://localhost:8081
CREATE CUSTOM INDEX products_avro
ON ks.products (name, price)
USING 'KafkaReplicator'
WITH OPTIONS = {
'topicName': 'ks.products',
'format': 'avro'
};
-- Schemas are automatically registered as subjects
-- "ks.products-key" and "ks.products-value".
Auto-create topic with multiple partitions
Create the Kafka topic automatically at index-creation time with custom partition and replication settings:
CREATE CUSTOM INDEX products_kafka
ON ks.products (name, price)
USING 'KafkaReplicator'
WITH OPTIONS = {
'topicName': 'ks.products',
'createTopicIfNotExists': 'true',
'partitions': '6',
'replicationFactor': '3'
};
Index only selected columns (projection)
Replicate only a subset of non-primary-key columns to reduce message size:
CREATE CUSTOM INDEX products_kafka
ON ks.products (name, price)
USING 'KafkaReplicator'
WITH OPTIONS = {
'topicName': 'ks.products',
'columnsToIndex': 'name,price'
};
Deduplication mode with an intermediate events topic
Enable deduplication so that HCD publishes only the latest version of each row to the destination topic. HCD creates both the destination topic and the events topic if they do not exist:
CREATE CUSTOM INDEX products_dedup
ON ks.products (name, price)
USING 'KafkaReplicator'
WITH OPTIONS = {
'topicName': 'ks.products',
'deduplicationEnabled': 'true',
'eventsTopic': 'ks.products-events',
'eventsTopicPartitions': '6',
'eventsConsumerGroupId': 'hcd-dedup-ks-products',
'createTopicIfNotExists': 'true'
};
Skip initial backfill
Index only writes made after CREATE INDEX, leaving pre-existing rows out of Kafka until a separate backfill is performed:
CREATE CUSTOM INDEX events_kafka
ON analytics.events ()
USING 'KafkaReplicator'
WITH OPTIONS = {
'topicName': 'analytics.events',
'skipBuildIfTableNotEmpty': 'true'
};
Configuration
You can provide settings as JVM system properties, environment variables, or cassandra.yaml keys.
When HCD is started with HCDConfigurationLoader (the default), you can place all Kafka settings in the hcd: top-level section of cassandra.yaml.
For an annotated cassandra.yaml example covering every available setting, see Kafka settings in cassandra.yaml.
System properties take precedence over environment variables, which take precedence over cassandra.yaml values, which take precedence over built-in defaults.
Kafka broker connection
The settings that configure the connection to the Kafka broker:
| Property | Environment variable | Default | Description |
|---|---|---|---|
|
|
|
Comma-separated list of Kafka broker addresses. |
|
|
(none) |
Confluent Schema Registry URL.
Required when any index uses |
Producer configuration
HCD creates the producer with sensible batching defaults that you can override through the three-level hierarchy.
The built-in producer defaults:
| Producer property | Default | Purpose |
|---|---|---|
|
|
Increased from the Kafka default of 16 KB. |
|
|
Wait up to 1 ms for more messages to accumulate. |
|
|
Compression to maximize batch efficiency. |
|
|
Total in-memory buffer for the producer. |
The mandatory producer properties, which you cannot override:
| Producer property | JSON mode | Avro mode |
|---|---|---|
|
Configured value |
Configured value |
|
|
|
|
|
|
|
Not set |
Configured Schema Registry URL |
To supply extra producer properties, use one of the following methods:
-
cassandra.yaml:hcd.kafka.producermap (flat key-value pairs) -
Environment variable:
CASSANDRA_KAFKA_PRODUCER_<UPPER_SNAKE>, lowercased with dots -
System property:
cassandra.kafka.producer.<property.name>
The following is an example cassandra.yaml with producer configuration:
hcd:
kafka:
bootstrap:
servers: broker1:9092,broker2:9092
schema:
registry:
url: http://registry:8081
producer:
acks: "all"
retries: 3
max.block.ms: 5000
Values must be strings, booleans, or numbers. HCD rejects lists and maps at startup.
Consumer configuration
HCD creates a Kafka consumer and a background EventsConsumerWorker only when an index has deduplicationEnabled: true.
In standard mode, no Kafka consumer is started.
The consumer uses the following built-in defaults:
| Consumer property | Default | Purpose |
|---|---|---|
|
|
Mandatory. HCD commits offsets explicitly and asynchronously after each batch is processed. |
|
|
Ensures no events are skipped when a worker joins a consumer group for the first time. |
|
|
Binary deserializer for the serialized primary key. |
|
|
Binary deserializer for the events topic message value. |
|
|
Overridden per table by the |
The properties that tune consumer threading and polling:
| Property | Environment variable | Default | Description |
|---|---|---|---|
|
|
|
Number of consumer threads in the shared consumer pool for Kafka event polling. |
|
|
|
Number of worker threads per table pool for concurrent HCD reads. |
|
|
|
Timeout in milliseconds for |
To set extra consumer properties, use one of the following methods:
-
cassandra.yaml:hcd.kafka.consumermap (flat key-value pairs) -
Environment variable:
CASSANDRA_KAFKA_CONSUMER_<UPPER_SNAKE>, lowercased with dots -
System property:
cassandra.kafka.consumer.<property.name>
Values must be strings, booleans, or numbers. HCD rejects lists and maps at startup.
Admin client configuration
HCD creates an Admin client only when createTopicIfNotExists: true is set on an index.
To set admin client configuration, use one of the following methods:
-
cassandra.yaml:hcd.kafka.adminmap (flat key-value pairs) -
Environment variable:
CASSANDRA_KAFKA_ADMIN_<UPPER_SNAKE>, lowercased with dots -
System property:
cassandra.kafka.admin.<property.name>
Mutation processing
The properties that tune the internal mutation processing pipeline:
| Property | Environment variable | Default | Description |
|---|---|---|---|
|
|
|
Timeout for mutation processing. |
|
|
|
Number of threads for mutation processing. |
|
|
|
Number of threads for HCD read-back queries. |
|
|
|
Timeout for remediation operations, which are retries that attempt to recover a mutation that failed initial processing. |
|
|
|
When |
|
|
unbounded |
Maximum retry attempts for general processing operations. |
|
|
|
Initial retry delay for general processing operations. |
|
|
|
Maximum retry delay for general processing operations (exponential backoff cap). |
Storage
The replicator writes pending mutations to a durable write-ahead log on disk, surviving crashes and node restarts.
The storage properties:
| Property | Environment variable | Default | Description |
|---|---|---|---|
|
|
(auto-discovered) |
Directory for persistent storage.
When empty, HCD auto-discovers the directory from Cassandra’s data directory configuration.
Typically |
|
|
|
Maximum number of pending mutations before HCD applies backpressure and slows incoming writes. |
The disk storage properties:
| Property | Environment variable | Default | Description |
|---|---|---|---|
|
|
|
Per-table memtable size limit. |
|
|
|
Maximum commit log file size. |
|
|
|
Commit-log size that triggers a checkpoint, after which the replicator compacts and truncates the log. |
|
|
|
Maximum time in nanoseconds the replicator waits to batch multiple fsyncs into a single |
|
|
|
Flush immediately when the queue is empty (low-latency mode). |
|
|
|
Shared memory budget across all tables. |
|
|
|
Complete |
|
|
|
Flush interval in milliseconds for completed mutations. |
The replicator maintains persistent state in the following directory structure, where <storage.directory> is the configured storage directory, <keyspace> and <table> identify the HCD table being replicated, and <id> is a file identifier the replicator assigns automatically:
<storage.directory>/
├── <keyspace>/
│ └── <table>/
│ ├── manifest.json # Current checkpoint state
│ ├── cl-<id>.log # Commit log files (write-ahead log)
│ └── seg-<id>.dat # Data segment files (flushed memtables)
-
Commit log: Rolling log files (
cl-*.log) that record all pending mutations for crash recovery. -
Segments: Immutable data files (
seg-*.dat) containing data written from memory to disk. -
Manifest: JSON file tracking current checkpoint state and active files.