持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情
前言
首先我们了解下什么是kafka,如果对这个中间件很熟悉,可以忽略前言部分。 Apache Kafka是一个开源分布式事件流平台,数千家公司使用它来实现高性能数据管道、流分析、数据集成和任务关键型应用程序。在大多数涉及Kafka和ClickHouse的情况下,用户都希望将基于Kafka的数据插入ClickHouse,尽管支持相反的操作。下面我们概述了两种用例的几个选项,确定了每种方法的优缺点。
我们假设你对kafka有一定的了解,如果不了解,请去官网看看,实在不行,可以联系本人。了解程序如下:
- 熟悉Kafka基本原理,如生产者、消费者和主题。
- 准备了一个主题(Topic)。我们假设所有数据都以JSON的形式存储在Kafka中,但如果使用Avro,则原理保持不变。
- 使用kcat(以前称为kafkacat)来发布和使用Kafka数据(你也可以直接在终端使用Kafka的客户端)。
- 引用了一些python脚本来加载示例数据,但可以根据您的数据集调整示例。
- 对ClickHouse物化视图非常熟悉。
正文
官网也明确了:要使用Kafka表格引擎,需要广泛熟悉ClickHouse的具体化视图,物化视图后期我们会讲解怎么使用。
原理
使用Kafka表引擎将数据从Kafka插入ClickHouse,是非常常用的手段之一。 Kafka表引擎允许ClickHouse直接读取Kafka主题。虽然对于查看主题消息很有用,但引擎设计上只允许一次性检索,即当向表发出查询时,它会消耗队列中的数据并增加使用者偏移量,然后再将结果返回给调用者。实际上,如果不重置这些偏移量,就无法重新读取数据。 为了从表引擎的读取中持久化这些数据,我们需要一种方法来捕获数据并将其插入另一个表中。基于触发器的物化视图本机提供了此功能。物化视图在表引擎上启动读取,接收成批文档。通常是合并树族的表。此过程如下所示
创建表
这里我们假设我们的clickhouse是可以完整的,是可以正常使用的(不能正常使用,请先安装好,也可以看我之前的博客,还是不行的话,私信我吧)。 准备目标表。在下面的示例中,为使用简化的模式。请注意,尽管我们使用了MergeTree表引擎,但这个示例可以适用于MergeTre家族的任何成员。
CREATE TABLE github
(
file_time DateTime,
event_type Enum('CommitCommentEvent' = 1, 'CreateEvent' = 2, 'DeleteEvent' = 3, 'ForkEvent' = 4, 'GollumEvent' = 5, 'IssueCommentEvent' = 6, 'IssuesEvent' = 7, 'MemberEvent' = 8, 'PublicEvent' = 9, 'PullRequestEvent' = 10, 'PullRequestReviewCommentEvent' = 11, 'PushEvent' = 12, 'ReleaseEvent' = 13, 'SponsorshipEvent' = 14, 'WatchEvent' = 15, 'GistEvent' = 16, 'FollowEvent' = 17, 'DownloadEvent' = 18, 'PullRequestReviewEvent' = 19, 'ForkApplyEvent' = 20, 'Event' = 21, 'TeamAddEvent' = 22),
actor_login LowCardinality(String),
repo_name LowCardinality(String),
created_at DateTime,
updated_at DateTime,
action Enum('none' = 0, 'created' = 1, 'added' = 2, 'edited' = 3, 'deleted' = 4, 'opened' = 5, 'closed' = 6, 'reopened' = 7, 'assigned' = 8, 'unassigned' = 9, 'labeled' = 10, 'unlabeled' = 11, 'review_requested' = 12, 'review_request_removed' = 13, 'synchronize' = 14, 'started' = 15, 'published' = 16, 'update' = 17, 'create' = 18, 'fork' = 19, 'merged' = 20),
comment_id UInt64,
path String,
ref LowCardinality(String),
ref_type Enum('none' = 0, 'branch' = 1, 'tag' = 2, 'repository' = 3, 'unknown' = 4),
creator_user_login LowCardinality(String),
number UInt32,
title String,
labels Array(LowCardinality(String)),
state Enum('none' = 0, 'open' = 1, 'closed' = 2),
assignee LowCardinality(String),
assignees Array(LowCardinality(String)),
closed_at DateTime,
merged_at DateTime,
merge_commit_sha String,
requested_reviewers Array(LowCardinality(String)),
merged_by LowCardinality(String),
review_comments UInt32,
member_login LowCardinality(String)
) ENGINE = MergeTree ORDER BY (event_type, repo_name, created_at)
创建一个主题并推送数据
建议将Kcat作为向主题发布数据的简单方法,已经创建了主题github。数据地址在:datasets-documentation.s3.eu-west-3.amazonaws.com/kafka/githu…
cat github_all_columns.ndjson | kafkacat -b <host>:<port> -t github
创建Kafka表引擎
下面的示例创建了一个与合并树表具有相同模式的表引擎。使用JSONEachRow作为数据类型来消费来自Kafka主题的JSON。而“github”和“clickhouse”分别表示主题名称和消费者组名称。
CREATE TABLE default.github_queue
(
file_time DateTime,
event_type Enum('CommitCommentEvent' = 1, 'CreateEvent' = 2, 'DeleteEvent' = 3, 'ForkEvent' = 4, 'GollumEvent' = 5, 'IssueCommentEvent' = 6, 'IssuesEvent' = 7, 'MemberEvent' = 8, 'PublicEvent' = 9, 'PullRequestEvent' = 10, 'PullRequestReviewCommentEvent' = 11, 'PushEvent' = 12, 'ReleaseEvent' = 13, 'SponsorshipEvent' = 14, 'WatchEvent' = 15, 'GistEvent' = 16, 'FollowEvent' = 17, 'DownloadEvent' = 18, 'PullRequestReviewEvent' = 19, 'ForkApplyEvent' = 20, 'Event' = 21, 'TeamAddEvent' = 22),
actor_login LowCardinality(String),
repo_name LowCardinality(String),
created_at DateTime,
updated_at DateTime,
action Enum('none' = 0, 'created' = 1, 'added' = 2, 'edited' = 3, 'deleted' = 4, 'opened' = 5, 'closed' = 6, 'reopened' = 7, 'assigned' = 8, 'unassigned' = 9, 'labeled' = 10, 'unlabeled' = 11, 'review_requested' = 12, 'review_request_removed' = 13, 'synchronize' = 14, 'started' = 15, 'published' = 16, 'update' = 17, 'create' = 18, 'fork' = 19, 'merged' = 20),
comment_id UInt64,
path String,
ref LowCardinality(String),
ref_type Enum('none' = 0, 'branch' = 1, 'tag' = 2, 'repository' = 3, 'unknown' = 4),
creator_user_login LowCardinality(String),
number UInt32,
title String,
labels Array(LowCardinality(String)),
state Enum('none' = 0, 'open' = 1, 'closed' = 2),
assignee LowCardinality(String),
assignees Array(LowCardinality(String)),
closed_at DateTime,
merged_at DateTime,
merge_commit_sha String,
requested_reviewers Array(LowCardinality(String)),
merged_by LowCardinality(String),
review_comments UInt32,
member_login LowCardinality(String)
)
ENGINE = Kafka('kafka_host:9092', 'github', 'clickhouse',
'JSONEachRow') settings kafka_thread_per_consumer = 0, kafka_num_consumers = 1;
下面我们讨论引擎设置和性能调整。此时,表github_queue上的简单选择应该读取一些行。请注意,这将向前移动消耗偏移量,防止在不重置的情况下重新读取这些行。请注意限制和所需参数stream_like_engine_allow_direct_select。
创建物化视图
物化视图将连接之前创建的两个表,从Kafka表引擎读取数据并将其插入目标合并树表。我们可以进行许多数据转换。
CREATE MATERIALIZED VIEW default.github_mv TO default.github AS
SELECT *
FROM default.github_queue;
在创建时,物化视图连接到Kafka引擎并开始读取:将行插入目标表。这一过程将无限期地继续下去。我们随后可以重复将数据插入Kafka中,重新运行插入脚本,向Kafka插入更多消息。可以观察结果。
确认并查看物化表数据
SELECT count() FROM default.github;
如果有数据,并且条数符合你插入的数量,那就ok啦。
总结
本节主要讲解了,需要我们了解kafka,并在已了解kafka的前提下,去消费kafka的数据写入到clickhouse中,具体步骤如下:1、创建本地表;2、创建kafka topic并插入数据;3、创建表引擎;4、创建物化视图。严格按照这几个步骤走,是没有问题的,但是这个过程也会出现一些你意想不到的错误。如:你的row is large or small等等。这些错误都是必备的技能,因此我们需要自己去做一个分析,当然实在解决不了,卡了很久,可以去社区或者留言讨论。