Kafka Stream DSL非密钥加入当前解决方法

时间:2019-07-08 16:44:43

标签: apache-kafka apache-kafka-streams

我试图了解以下解决方法:

https://issues.apache.org/jira/browse/KAFKA-3705

  

如今,在Kafka Streams DSL中,KTable连接仅基于密钥。如果   用户希望通过键a将一个KTable A与另一个通过键b的KTable B连接起来   但带有“外键” a,并假设它们是从两个主题中读取的   它们分别在a和b上划分,它们需要执行   如下模式:

tableB' = tableB.groupBy(/* select on field "a" */).agg(...); // now tableB' is partitioned on "a"

tableA.join(tableB', joiner);

我很难理解到底发生了什么。

尤其是该句子令人困惑:“如果用户希望通过键a将一个KTable A与另一个通过键b但又带有“外键” a的KTable B连接起来,则。我也不明白上面的代码。

有人可以澄清一下这里发生了什么吗?

这里也提到了这一点:

弥合流中的KTables语义与关系数据库中的表之间的鸿沟。将对RDBMS中的表所做的更改捕获到Kafka主题(JDBC连接,Debezium,Maxwell)中是一种常见的做法。这些实体通常具有多个一对多关系。通常,RDBMS提供良好的支持来解决通过联接的这种关系。这里的流不足,解决方法(按分组-连接-横向视图)也没有得到很好的支持,也不符合基于记录的处理的想法。 https://cwiki.apache.org/confluence/display/KAFKA/KIP-213+Support+non-key+joining+in+KTable

(按-联接-横向视图分组)是什么意思?我怀疑它与上面的代码有关,但又很难遵循。任何人都可以对此有所了解吗?

1 个答案:

答案 0 :(得分:1)

好吧,下面的代码是使用非键联接来联接两个KTable的伪代码:

tableB' = tableB.groupBy(/* select on field "a" */).agg(...); // now tableB' is partitioned on "a"

tableA.join(tableB', joiner);

说明

比方说, tableA 具有一个关键字段“ a ”。为了将另一个ktable与 tableA 连接在一起,应该对其进行共分区。它应该具有相同的键。因此,我们将使用字段“ a

为ktable tableB 输入密钥
tableB' = tableB.groupBy(/* select on field "a" */).agg(...); // now tableB' is partitioned on "a"

groupBy()selectKey()+ groupByKey()操作的简写。

groupBy(/* select on field "a" */)将在“ a” 字段上重新键入 tableB 并按该键分组。因此,现在您有了一个以字段“ a ”作为键的KGroupedTable。为了获取KTable,您需要对此调用.aggregate()。上面的代码就是这种情况。

P.S。 .agg()应该用.aggregate()

重命名

tableB'准备就绪后,您可以使用以下代码加入 tableA

tableA.join(tableB', joiner);

这里的joiner指的是ValueJoiner的实现。

示例

// Java 8+ example, using lambda expressions
KTable<String, String> joined = left.join(right, 
     /* Below line is ValueJoiner */
    (leftValue, rightValue) -> "left=" + leftValue + ", right=" + rightValue 
  );

目前,这是在KTables上进行非键连接的方法 您可以在文档中找到很好的解释:https://docs.confluent.io/current/streams/developer-guide/dsl-api.html#ktable-ktable-join