我们正在通过CDC将数据从DB2(表1)发送到Kafka主题(主题1)。 我们需要在DB2数据和Kafka主题之间进行协调。 我们有两个选择-
a)将所有kafka主题数据放入DB2(如表1副本),然后进行左外部联接(在表1和表1副本之间)以查看不匹配的记录,创建增量并将其推回kafka。 问题:可伸缩性-我们的数据集大约有十亿条记录,我不确定DB2 DBA是否会让我们运行如此庞大的联接操作(可能会持续15-20分钟)。
b)再次将DB2推回并行的kafka主题(topic-1-copy),然后执行一些基于kafka流的解决方案,以在kafka topic-1和topic-1-copy之间进行左外部联接。我仍然把头缠在卡夫卡河和左外连接上。 我不确定(使用kafka流中的窗口系统)我是否能够比较主题1和主题1复制的整个内容。
更糟糕的是,kafka中的topic-1是一个紧凑的主题, 因此,当我们将数据从DB2推回到Kafka topic-1-copy时,我们无法确定地启动kafka topic-compaction周期以确保在运行任何类型的比较之前,topic-1和topic-1-copy都已完全压缩对它们进行操作。
c)我们还有其他可以考虑的框架选项吗?
理想的解决方案必须针对任何大小的数据进行缩放。
答案 0 :(得分:0)
我认为您在Kafka Streams或KSQL中都无法做到这一点。两者都支持表-表联接。假设支持数据格式。
键压缩不会影响结果,因为Streams和KSQL都将建立连接两个表的正确最终状态。如果运行压缩,则需要处理的数据量可能会减少,但结果将相同。
例如,在ksqlDB中,您可以将两个主题都作为表导入并执行联接,然后按topic-1
表作为null
进行筛选,以找到丢失的行的列表。
-- example using 0.9 ksqlDB, assuming a INT primary key:
-- create table from main topic:
CREATE TABLE_1
(ROWKEY INT PRIMARY KEY, <other column defs>)
WITH (kafka_topic='topic-1', value_format='?');
-- create table from second topic:
CREATE TABLE_2
(ROWKEY INT PRIMARY KEY, <other column defs>)
WITH (kafka_topic='topic-1-copy', value_format='?');
-- create a table containing only the missing keys:
CREATE MISSING AS
SELECT T2.* FROM TABLE_2 T2 LEFT JOIN TABLE_1 T1
WHERE T1.ROWKEY = null;
此方法的好处是丢失行的MISSING
表将自动更新:当您从源DB2实例中提取丢失行并将它们生成到topic-1
时,然后“ MISSING”表将被删除,也就是说,您会看到针对MISSING
主题的墓碑。
您甚至可以扩展此方法以查找topic-1
中存在的行,这些行不再在源数据库中:
-- using the same DDL statements for TABLE_1 and TABLE_2 from above
-- perform the join:
CREATE JOINED AS
SELECT * FROM TABLE_2 T2 FULL OUTER JOIN TABLE_1 T1;
-- detect rows in the DB that aren't in the topic:
CREATE MISSING AS
SELECT * FROM JOINED
WHERE T1_ROWKEY = null;
-- detect rows in the topic that aren't in the DB:
CREATE EXTRA AS
SELECT * FROM JOINED
WHERE T2_ROWKEY = null;
当然,您需要相应地调整集群的大小。 ksqlDB集群越大,则处理数据的速度就越快。它还需要磁盘容量才能实现该表。
通过主题上的分区数可以设置的最大并行化数量。如果只有1个分区,则将按顺序处理数据。如果运行100个分区,则假设您运行了足够的ksqlDB实例,则可以使用100个CPU内核来处理数据。 (默认情况下,每个ksqlDB节点将为每个查询创建4个流处理线程(尽管如果服务器具有更多内核,则可以增加此数量!)。