Synchronize data from Kafka

Updated at:

You can synchronize data in real time from ApsaraMQ for Kafka to ApsaraDB for ClickHouse by using the built-in Kafka table engine and a materialized view.

Limitations

You can synchronize data only from ApsaraMQ for Kafka instances and self-managed Kafka clusters that are deployed on ECS instances.

Prerequisites

Usage notes

  • The topic that the ApsaraDB for ClickHouse Kafka external table subscribes to must not have other consumers.

  • When you create the Kafka external table, materialized view, and local table, the field types of the three tables must match.

Procedure

The following example synchronizes data from ApsaraMQ for Kafka to the kafka_table_distributed distributed table in the default database of a Community-compatible Edition cluster of ApsaraDB for ClickHouse.

Step 1: Understand how synchronization works

ApsaraDB for ClickHouse uses the Kafka table engine and a materialized view to consume and store data from Kafka in real time. The data flow is as follows.

image
  • Kafka topic: The source data to be synchronized.

  • ApsaraDB for ClickHouse Kafka external table (a table that uses the Kafka table engine): pulls source data from a specified Kafka topic.

  • Materialized view: reads source data from the external table for Kafka and inserts the data into a local table in ApsaraDB for ClickHouse.

  • Local table: stores the synchronized data.

Step 2: Connect to the ApsaraDB for ClickHouse cluster

For more information, see Connect to an ApsaraDB for ClickHouse cluster by using DMS.

Step 3: Create a Kafka external table

The Kafka external table uses the Kafka table engine to pull data from a specified Kafka topic. This table has the following characteristics:

  • By default, you cannot directly query the Kafka external table.

  • The Kafka external table is used only to consume Kafka data and does not store data. You must use a materialized view to process and insert the data into a destination table.

The syntax for creating the table is as follows.

Important

The field types of the Kafka external table must be consistent with the data types of the messages in Kafka.

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = Kafka()
SETTINGS
    kafka_broker_list = 'host:port1,host:port2,host:port3',
    kafka_topic_list = 'topic_name1,topic_name2,...',
    kafka_group_name = 'group_name',
    kafka_format = 'data_format'[,]
    [kafka_row_delimiter = 'delimiter_symbol',]
    [kafka_num_consumers = N,]
    [kafka_thread_per_consumer = 1,]
    [kafka_max_block_size = 0,]
    [kafka_skip_broken_messages = N,]
    [kafka_commit_every_batch = 0,]
    [kafka_auto_offset_reset = N]

The following table describes the common parameters.

Parameter

Required

Description

kafka_broker_list

Yes

A comma-separated list of broker endpoints for the Kafka cluster. For more information about how to view endpoints, see View Endpoints.

  • If you use ApsaraMQ for Kafka, ApsaraDB for ClickHouse can parse the domain names of the ApsaraMQ for Kafka instances by default.

  • If you use a self-managed Kafka cluster, ApsaraDB for ClickHouse supports connections to the Kafka cluster using IP addresses or custom domain names in a fixed format. The following custom domain name rules are supported:

    1. Domain names that end with .com.

    2. Domain names that end with .local and contain kafka, mysql, or rabbitmq.

kafka_topic_list

Yes

A comma-separated list of topic names. For more information about how to view topic names, see Create a topic.

kafka_group_name

Yes

The name of the Kafka consumer group. For more information, see Create a group.

kafka_format

Yes

The format of the message body that ApsaraDB for ClickHouse can process.

Note

For more information about the message body formats supported by ApsaraDB for ClickHouse, see Formats for Input and Output Data.

kafka_row_delimiter

No

The delimiter used to separate rows. The default value is \n. You can also set this parameter to match the actual delimiter used in your data.

kafka_num_consumers

No

The number of consumers for a single table. The default value is 1.

Note
  1. If the throughput of a single consumer is insufficient, you must specify more consumers.

  2. The total number of consumers cannot exceed the number of partitions in the topic because only one consumer can be assigned to each partition.

kafka_thread_per_consumer

No

Specifies whether to enable a dedicated thread for each consumer. The default value is 0. Valid values:

  1. 0: All consumers share one thread to consume data.

  2. 1: A dedicated thread is enabled for each consumer to consume data.

For more information about how to improve the consumption speed, see Kafka performance tuning.

kafka_max_block_size

No

The maximum size, in bytes, of a batch of Kafka messages. The default value is 65536.

kafka_skip_broken_messages

No

The number of parsing errors to ignore. The default value is 0. If you set kafka_skip_broken_messages=N, the engine skips N unparsable Kafka messages. A message is equivalent to a row of data.

kafka_commit_every_batch

No

The frequency of Kafka commits. The default value is 0. Valid values:

  1. 0: A commit is performed only after a complete block of data is written.

  2. 1: A commit is performed after each batch of data is written.

kafka_auto_offset_reset

No

The offset from which to start reading Kafka data. Valid values:

  1. earliest: reads Kafka data from the earliest offset. This is the default value.

  2. latest: reads Kafka data from the latest offset.

Note

This parameter is not supported for ApsaraDB for ClickHouse clusters that run kernel version 21.8.

For more information about the parameters, see Kafka.

The following code provides an example:

CREATE TABLE default.kafka_src_table ON CLUSTER `default`
(
    -- Define the fields of the table schema.
    id Int32,
    name String               
) ENGINE = Kafka()
SETTINGS
    kafka_broker_list = 'alikafka-post-cn-****-1-vpc.alikafka.aliyuncs.com:9092,alikafka-post-cn-****1-2-vpc.alikafka.aliyuncs.com:9092,alikafka-post-cn-****-3-vpc.alikafka.aliyuncs.com:9092',
    kafka_topic_list = 'testforCK',
    kafka_group_name = 'GroupForTestCK',
    kafka_format = 'CSV';

Step 4: Create a destination table

Choose the table creation statement that corresponds to your cluster edition.

For an Enterprise Edition cluster, you need to create only a local table. For a Community-compatible Edition cluster, you may need to create a distributed table based on your environment and requirements. The following code provides example statements. For more information about the syntax for creating a table, see CREATE TABLE.

Enterprise edition

CREATE TABLE default.kafka_table_local ON CLUSTER default (
  id Int32,
  name String
) ENGINE = MergeTree()
ORDER BY (id);

If you receive the ON CLUSTER is not allowed for Replicated database error when you run this statement, you can upgrade the kernel version to resolve the issue. For more information about how to upgrade the kernel version, see Upgrade the minor engine version.

Community-compatible edition

The table engines for single-replica and double-replica clusters are different. Select the appropriate engine based on your cluster replica type.

Important

When you create a table in a dual-replica cluster, you must use a Replicated engine from the MergeTree engine family. If you create a table with a non-Replicated engine in a dual-replica cluster, data cannot be replicated between replicas, which may cause data inconsistency.

Single-replica

  1. Create a local table.

    CREATE TABLE default.kafka_table_local ON CLUSTER default (
      id Int32,
      name String
    ) ENGINE = MergeTree()
    ORDER BY (id);
  2. (Optional) Create a distributed table.

    If you only need to import data into the local table, skip this step.

    If you have a multi-node cluster, we recommend that you create a distributed table.

    CREATE TABLE kafka_table_distributed ON CLUSTER default AS default.kafka_table_local
    ENGINE = Distributed(default, default, kafka_table_local, id);

Double-replica

  1. Create a local table.

    CREATE TABLE default.kafka_table_local ON CLUSTER default (
      id Int32,
      name String
    ) ENGINE = ReplicatedMergeTree()
    ORDER BY (id);
  2. (Optional) Create a distributed table.

    If you only need to import data into the local table, skip this step.

    If you have a multi-node cluster, we recommend that you create a distributed table.

    CREATE TABLE kafka_table_distributed ON CLUSTER default AS default.kafka_table_local
    ENGINE = Distributed(default, default, kafka_table_local, id);

Step 5: Create a materialized view

ApsaraDB for ClickHouse relies on a materialized view to read source data from the Kafka external table and insert the data into a local table in ApsaraDB for ClickHouse.

The syntax for creating a materialized view is as follows.

Important

Ensure that the SELECT fields are consistent with the destination table structure, or use conversion functions to match the data format with the destination table structure.

CREATE MATERIALIZED VIEW <view_name> ON CLUSTER default TO <dest_table> AS SELECT * FROM <src_table>;

The following table describes the parameters.

Parameter

Required

Description

Example

view_name

Yes

The name of the view.

consumer

dest_table

Yes

The destination table for storing Kafka data.

  • Community-compatible Edition cluster:

    • For a multi-node cluster, we recommend that you import data to a distributed table.

    • If synchronizing to a local table, specify the local table name.

  • Enterprise Edition cluster: Since Enterprise Edition clusters do not have distributed tables, you must specify the local table.

  • Community-compatible Edition example: kafka_table_distributed

  • Enterprise Edition example: kafka_table_local

src_table

Yes

The Kafka external table.

kafka_src_table

The following code provides example statements.

Enterprise edition

CREATE MATERIALIZED VIEW consumer ON CLUSTER default TO kafka_table_local AS SELECT * FROM kafka_src_table;

Community-compatible edition

In this example, source data is stored in the kafka_table_distributed distributed table.

CREATE MATERIALIZED VIEW consumer ON CLUSTER default TO kafka_table_distributed AS SELECT * FROM kafka_src_table;

Step 6: Verify the synchronization

  1. Send messages to the topic in the ApsaraMQ for Kafka instance.

    1. Log on to the ApsaraMQ for Kafka console.

    2. On the Instance list page, click the name of the destination instance.

    3. On the Topics page, find the destination topic and choose More > Send Message (Demo) in the Actions column.

    4. On the Send and Consume Message with Quick Experience page, enter the Message Content.

      This example sends the messages 1,a and 2,b.

    5. Click OK.

  2. Log on to the ApsaraDB for ClickHouse cluster, query the distributed table, and check whether the data is synchronized.

    For more information about how to log on to an ApsaraDB for ClickHouse cluster, see Connect to an ApsaraDB for ClickHouse cluster by using DMS.

    Use the following statements to query and verify data:

    Enterprise edition

    SELECT * FROM kafka_table_local; 

    Community-compatible edition

    The following code provides an example of how to query a distributed table.

    • If the destination table is a local table, you must replace the distributed table name in the query with the local table name.

    • If you use a Community-compatible Edition cluster that is a multi-node cluster, we strongly recommend that you query the distributed table. If you query a local table directly, it will only return data from a single node, resulting in an incomplete result set.

    SELECT * FROM kafka_table_distributed; 

    If the query returns results, the data synchronization from Kafka to ApsaraDB for ClickHouse is successful.

    The query results are as follows.

    ┌─id─┬─name─┐
    │  1 │  a   │
    │  2 │  b   │
    └────┴──────┘

    If the query results are not as expected, proceed to Step 7 (Optional): Check the consumption status of the Kafka external table to further troubleshoot the issue.

Step 7 (Optional): Check Kafka consumption status

If the synchronized data does not match the data in Kafka, query the system table to check the consumption status of the Kafka external table and troubleshoot exceptions.

Engine v23.8 or later

Run the following statement to query the system.kafka_consumers system table and view the consumption status of the Kafka external table:

select * from system.kafka_consumers;

The following table describes the fields of the system.kafka_consumers table.

Field

Description

database

The database where the Kafka external table is located.

table

The name of the Kafka external table.

consumer_id

The ID of the Kafka consumer.

A table can have multiple consumers. The number of consumers is specified by the kafka_num_consumers parameter when you create a Kafka external table.

assignments.topic

The Kafka topic.

assignments.partition_id

The ID of the Kafka partition.

A partition can be assigned to only one consumer.

assignments.current_offset

The current offset.

exceptions.time

The timestamps of the 10 most recent exceptions.

exceptions.text

The text of the 10 most recent exceptions.

last_poll_time

The timestamp of the last polling.

num_messages_read

The number of messages read by the consumer.

last_commit_time

The timestamp of the last commit.

num_commits

The total number of commits performed by the consumer.

last_rebalance_time

The timestamp of the last Kafka rebalancing.

num_rebalance_revocations

The number of times that partitions were revoked from the consumer.

num_rebalance_assignments

The number of times that the consumer was assigned partitions in the Kafka cluster.

is_currently_used

Indicates whether the consumer is in use.

last_used

The time when the consumer was last used, in Unix time (microseconds).

rdkafka_stat

The internal statistics of the library. For more information, see librdkafka.

The default value is 3000, which indicates that statistics are generated every 3 seconds.

Note

When statistics_interval_ms=0 is configured for ApsaraDB for ClickHouse, statistics collection for the Kafka external table is disabled.

Engine earlier than v23.8

Run the following statement to query the system.kafka system table and view the consumption status of the Kafka external table:

SELECT * FROM system.kafka;

The following table describes the fields of the system.kafka table.

Field

Description

database

The name of the database where the Kafka external table is located.

table

The name of the Kafka external table.

topic

The name of the topic consumed by the Kafka external table.

consumer_group

The name of the consumer group used by the Kafka external table.

last_read_message_count

The number of messages pulled from the Kafka external table.

status

The status of Kafka message consumption by the external table. Valid values:

  • no_view: No view is created for the Kafka external table.

  • attach_view: A view is created for the Kafka external table.

  • normal: The status is normal.

    The normal status indicates that the external table is consuming data as expected.

  • skip_parse: Parsing errors are skipped.

  • error: A consumption exception occurred.

exception

The details about the exception.

Note

If the value of status is error, this parameter returns details about the exception.

FAQ