Java Kafka流和KGlobalTable连接问题
我在加入KStream和GlobalKTable时遇到了一个问题,非常感谢您的帮助 鉴于卡夫卡的两个主题Java Kafka流和KGlobalTable连接问题,java,apache-kafka,apache-kafka-streams,Java,Apache Kafka,Apache Kafka Streams,我在加入KStream和GlobalKTable时遇到了一个问题,非常感谢您的帮助 鉴于卡夫卡的两个主题订单和客户: 订单 "1" {"ID":"1","Name":"Myorder1","CustID":"100"} "2" {"ID":"2","Name":"MyOrder2","CustID":"200"} 客户 "100" {"CustID":"100","CustName":"Customer1"} "200" {"CustID":"200","CustN
订单
和客户
:
订单
"1" {"ID":"1","Name":"Myorder1","CustID":"100"}
"2" {"ID":"2","Name":"MyOrder2","CustID":"200"}
客户
"100" {"CustID":"100","CustName":"Customer1"}
"200" {"CustID":"200","CustName":"Customer2"}
要求是用客户名称丰富订单流
"1" {"ID":"1","Name":"Myorder1","CustID":"100","CustName":"Customer1"}
"2" {"ID":"2","Name":"MyOrder2","CustID":"200","CustName":"Customer2"}}
我正在尝试以下方法:
orders
主题构建一个KStream客户
主题构建一个GlobalKTableKStream enrichedstreams=orders.join(
客户,
新的KeyValueMapper(){
@凌驾
公共字符串应用(字符串键、顺序值){
返回值.CustID;
}
},
新估价师(){
@凌驾
公共EnrichedOrder应用(订单、客户){
EnrichedOrder eorder=新的EnrichedOrder();
eorder.CustID=order.CustID;
eorder.CustName=customer.CustName;
eorder.ID=order.ID;
eorder.Name=order.Name;
返回订单;
}
}
);
但它不会给出任何结果,也不会抛出任何异常
当使用leftJoin
时,我得到了一个客户的空指针异常
如果您遇到类似问题,请告诉我,并建议如何解决此问题。@deepak您可能需要实现您的KTable
builder.table(customers, Materialized.as(customerStore));
然后流式处理订单并构建您的加入。让我们仔细查看复制粘贴的内容: 在
客户
主题中:
"100" {"CustID":"100","CustName":"Customer1"}
您可以注意到键是一个字符串,此字符串包含双引号:“100”
。通常,打印字符串键时不带双引号。我宁愿看到:
100 {"CustID":"100","CustName":"Customer1"}
换句话说,键的Java字符串表示形式是“100”
(或“100\”
),而不是我们预期的“100”
另一方面,orders
主题中的值是一个Json{“ID”:“1”,“Name”:“Myorder1”,“CustID”:“100”}
,属性CustID
是一个字符串,这次用Java“100”
表示
当您加入
订单
和客户
时,您会尝试将订单CustID100
与客户密钥“100”
匹配。这将失败,因为CustID中缺少键中的双引号。请确保在流处理开始时完全填充GlobalKTable
。可能是订单已经在处理,而客户表仍在填充。要避免这种情况,请启动streams应用程序,然后生成新订单事件。此外,在多次运行测试时,您可能需要重置偏移量。是否有任何方法可以检查GlobalKtable是否已完全填充?就像kstream中的foreach循环一样。@deepak,你能提供创建GlobalKTable的代码吗?@deepak,确保你的消息(订单和客户)有密钥。顺便问一下,您真的需要一个GlobalKTable(而不是KTable)吗?@user152468——您最初关心的“加载”表的问题不应该适用——在启动时,GlobalKTable
会在任何处理开始之前引导到主题的末尾(这与提供时间同步加入/处理的KTable
s不同,而GlobalKTable
s不进行时间同步)。我正在使用.GlobalKTable customers=builder.globalTable(Customer),consumered.with(Serdes.String(),customerSerde),物化.as(“我的状态存储”))。如果我们需要以不同的方式使用它,请提出建议。请确保您确实需要一个GlobalKTable,如果您要将Orders主题中使用的键切换为“CustID”,则可以切换为使用KTable(这会提供更好的性能)。如果两个主题具有相同的分区策略和相同的键(在您的情况下,您可以使用)然后你可以使用Ktable和GlobalKTable。请参考Matthias J.Sax的回答,