如何比较两个kafka流或数据库表之间的数据(十亿条记录)

时间:2018-09-01 15:32:06

标签: database apache-kafka apache-kafka-streams ksql

我们正在通过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)我们还有其他可以考虑的框架选项吗?

理想的解决方案必须针对任何大小的数据进行缩放。

1 个答案:

答案 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个流处理线程(尽管如果服务器具有更多内核,则可以增加此数量!)。