Java Kafka流和KGlobalTable连接问题

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

我在加入KStream和GlobalKTable时遇到了一个问题,非常感谢您的帮助

鉴于卡夫卡的两个主题
订单
客户

订单

"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
  • 客户
    主题构建一个GlobalKTable
  • 构建另一个连接订单和客户的流(在Customer表中查找Order.CustID)
  • KStream 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”
    表示


    当您加入
    订单
    客户
    时,您会尝试将订单CustID
    100
    与客户密钥
    “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的回答,