Clickhouse Engine kafka 將kafka資料同步clickhouse

to.to發表於2020-12-03

本篇文章轉自:https://blog.csdn.net/weixin_41461992/article/details/106790507

起因

由於需要做各種資料庫擺渡到kafka的元件研究。
其中clickhouse和kafka間的資料擺渡,根據官方給出的kafka引擎文件,便有了我這篇實踐記錄。
相應的,該配置也非常簡單。

官方傳送門: kafka engine clickhouse

這邊對資料庫和kafka環境不再累述。

一、開發環境

kafka 2.4
zookeeper 3.4.5
clickhouse 20.4.5.36
centos7

二、 介紹

clickhouse支援kafka的表雙向同步,其中提供的為Kafka引擎。

其大致情況為如下情況:Kafka主題中存在對應的資料格式,Clickhouse建立一個Kafka引擎表(即相當於一個消費者),當主題有訊息進入時,獲取該訊息,將其進行消費,然後物化檢視同步插入到MergeTree表中。
在這裡插入圖片描述
該引擎還支援反向寫入到Kafka中,即往Kafka引擎表中插入資料,可以同步到Kafka中(同樣可以使用物化檢視將不同引擎需要的表資料同步插入到Kafka引擎表中)。
在這裡插入圖片描述
下面為Kafka Engine的一些配置:
老版本格式為:

Kafka(kafka_broker_list, kafka_topic_list, kafka_group_name, kafka_format
      [, kafka_row_delimiter, kafka_schema, kafka_num_consumers])

新版本格式為:

Kafka SETTINGS
  kafka_broker_list = 'localhost:9092',
  kafka_topic_list = 'topic1,topic2',
  kafka_group_name = 'group1',
  kafka_format = 'JSONEachRow',
  kafka_row_delimiter = '\n',
  kafka_schema = '',
  kafka_num_consumers = 2

必填引數(例如topic、kafka叢集、消費者組等):

  1. kafka_broker_list – 以逗號分隔的 brokers 列表 (例如kafka1:9092,kafka2:9092,kafka3:9092)。
  2. kafka_topic_list – topic 列表 (你的topic名字,也可以多個)。
  3. kafka_group_name – Kafka 消費組名稱 (group1)。如果不希望訊息在叢集中重複,請在每個分片中使用相同的組名。
  4. kafka_format – 訊息體格式。使用與 SQL 部分的 FORMAT 函式相同表示方法,例如 JSONEachRow、CSV、XML等。Formats格式傳送門

非必填的引數:

  1. kafka_row_delimiter - 每個訊息體(記錄)之間的分隔符。
  2. kafka_schema – 如果解析格式需要一個 schema 時,此引數必填。
  3. kafka_num_consumers – 單個表的消費者數量。預設值是:1,如果一個消費者的吞吐量不足,則指定更多的消費者。眾所周知消費者的總數不應該超過 topic 中分割槽的數量,因為每個分割槽只能分配一個消費者。

三、實踐

  1. 建立,使用引擎建立一個Kafka消費者並作為一條資料流。
CREATE TABLE queue (
    q_date Date,
    level String,
    message String
  ) ENGINE = Kafka SETTINGS kafka_broker_list = 'k1:9092,k2:9092,k3:9092',
                            kafka_topic_list = 'my_topic',
                            kafka_group_name = 'kafka_group_test',
                            kafka_format = 'CSV',
                            kafka_num_consumers = 4;

消費的訊息會被自動追蹤,因此每個訊息在不同的消費組裡只會記錄一次。如果希望獲得兩次資料,則使用另一個組名建立副本。

消費組可以靈活配置並且在叢集之間同步。例如,如果叢集中有10個主題和5個表副本,則每個副本將獲得2個主題。如果副本數量發生變化,主題將自動在副本中重新分配。

  1. 建立一個結構表
CREATE TABLE daily (
    day Date,
    level String,
    message String
) ENGINE = MergeTree(day, (day, level), 8192);
  1. 建立物化檢視,該檢視會在後臺轉換引擎中的資料並將其放入之前建立的表中。
CREATE MATERIALIZED VIEW consumer TO daily
    AS SELECT q_date AS day, level, message
    FROM queue;

其中AS後面的語句是自己根據實際需求進行調整的。
為了提高效能,接受的訊息被分組為max_insert_block_size大小的塊。如果未在stream_flush_interval_ms毫秒內形成塊,則不關心塊的完整性,都會將資料重新整理到表中。

  1. 停止或者修改轉換邏輯
    detach物化檢視
DETACH TABLE consumer;
ATTACH TABLE consumer;
  1. 在建立表前,需要在kafka建立一個topic用於測試。
./bin/kafka-topic.sh --create --topic my_topic --partitions 3 --replication-factor 3

此處的topic需要與之前的kafka_topic_list對應,既然該引數為list,則可以配置多個topic

  1. 生產者往topic中生產資料
./bin/kafka-console-prodcer --topic my_topic --broker-list k1:9092

按照CSV格式,生產資料輸入

2020-06-28 level1 message
2020-06-28 level2 message
2020-06-28 level3 message

此時檢視錶daily,資料已同步

select * from daily
|--- day --- level --- message ---|
|--- 2020-06-28 --- level1 --- message ---|
|--- 2020-06-28 --- level2 --- message ---|
|--- 2020-06-28 --- level3 --- message ---|

同理,向kafka引擎表中插入資料,也可以在my_topic中可以消費到插入資料。

  1. 資料量測試
    在該版本,我在kafka生產者客戶端進行for迴圈2000w資料進行測試,延遲不高,基本在10秒內同步完成,不知道在表欄位數量和複雜sql語句時情況如何。還需要進一步進行實際使用

所遇問題

  1. 表結構變更
    對於資料同步問題,其中一個就是表同步之間的結構對應問題。
    由於表建立的時候,已經固定,所以ck的kafka引擎在遇到欄位改變的時候,依然需要刪表重建,或者修改物化檢視進行不同的sql操作。

  2. 延遲問題
    在之前的版本中,社群有人提出該同步延遲太高,特別是資料量大的時候,但是在我實際測試中,大約2000w簡單單表同步延遲可以接受。具體效能需要進一步測試。

  3. format格式
    對於自己規定的格式,一定要正確,比如csv就是csv,json就是json格式,不然會報錯。

  4. 消費問題
    前面說過,kafka引擎其實是一個或者多個消費者進行topic的消費,那必然就涉及到消費問題,如何重新消費,如何在需要修改業務的時候重新連線。重置偏移量。
    場景:丟失資料,重新消費

首先,我們可以將daily中的訊息幹掉,手動導致訊息丟失(自己整一個訊息丟失)

TRUNCATE TABLE daily

此時,daily資料被刪除了,同步的資料丟失。
接下來,我們停止kafka引擎表,在clickhouse中執行

DETACH TABLE queue

最後在kafka中,執行重置偏移量的命令

./bin/kafka-consumer-groups --bootstrap-server k1:9092 --topic my_topic --group kafka_group_test --reset-offsets --to-earliest --excute

然後,重連queue表

ATTACH TABLE queue

這樣,就開始重新消費啦

  1. 錯誤日誌
    clickhouse日誌檢視為ck目錄下的log資料夾的clickhouse-server.log中。

相關文章