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
-
ApsaraDB for ClickHouse:
-
A destination cluster has been created in the same region and VPC as the ApsaraMQ for Kafka instance. For more information, see Create a cluster.
-
A database account with the required permissions has been created for the destination cluster. For more information, see Account Management.
-
-
ApsaraMQ for Kafka:
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.
-
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.
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.
|
|
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
|
|
kafka_thread_per_consumer |
No |
Specifies whether to enable a dedicated thread for each consumer. The default value is 0. Valid values:
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_commit_every_batch |
No |
The frequency of Kafka commits. The default value is 0. Valid values:
|
|
kafka_auto_offset_reset |
No |
The offset from which to start reading Kafka data. Valid values:
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.
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
-
Create a local table.
CREATE TABLE default.kafka_table_local ON CLUSTER default ( id Int32, name String ) ENGINE = MergeTree() ORDER BY (id); -
(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
-
Create a local table.
CREATE TABLE default.kafka_table_local ON CLUSTER default ( id Int32, name String ) ENGINE = ReplicatedMergeTree() ORDER BY (id); -
(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.
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.
|
|
|
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
-
Send messages to the topic in the ApsaraMQ for Kafka instance.
-
Log on to the ApsaraMQ for Kafka console.
-
On the Instance list page, click the name of the destination instance.
-
On the Topics page, find the destination topic and choose in the Actions column.
-
On the Send and Consume Message with Quick Experience page, enter the Message Content.
This example sends the messages
1,aand2,b. -
Click OK.
-
-
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 |
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:
|
|
exception |
The details about the exception. Note
If the value of status is error, this parameter returns details about the exception. |