加入包含Java Hash Map Objects的Kafka Streams

时间:2017-08-30 13:50:00

标签: join stream apache-kafka apache-kafka-streams

目前我正致力于构建数据管道。我正在从sql数据库中读取2个表,并且我必须在使用Kafka流在流中加入它们之后将它们以非规范化格式存储在OLAP数据仓库中。

我没有为每个表创建单独的主题,而是将两个表插入到单个主题中。

我正在将行转换为hashmap,然后使用bytes serializer将此信息转换为bytes数组并推送到主题,因此一行中的所有信息都存储在单个对象中。代码是:

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
byte[] yourBytes = null;
try {
     out = new ObjectOutputStream(bos);
     out.writeObject(record);
     // here record is the row hashmap
     out.flush();
     yourBytes = bos.toByteArray();
}
catch (IOException ex) {
    // ignore close exception
}

在流处理应用程序中,我将字节数组反序列化为hashmap,并将记录过滤为两个单独的流,每个流用于一个表。

所以我在将字节数组反序列化回hashmap对象后的处理阶段的记录,记录如下所示,其中每个表的每个流的一条记录如下所示:

(key,{meta = "PRODUCTS",PRODUCTNAME=ONE, ISACTIVE=1, METATABLENAME=PRODUCT, PRODUCTSUBCATEGORYID=16, PRODUCTID=57})

(key,{meta = "BRAND", BRANDNAME="ABC", BRANDID=16, PRODUCTID=57, BRANDCATEGORY = "Electronics"})

现在我必须将数据连接到两个流中,其中每个值都是一个哈希映射,并加入键 PRODUCTID ,这是两个表的公共字段,最后生成一个哈希映射每一行并将该流推送到主题。

因此,联合记录将如下所示:

(key,{meta = "JOINEDTABLE",PRODUCTNAME=ONE, ISACTIVE=1, METATABLENAME=PRODUCT, PRODUCTSUBCATEGORYID=16, BRANDNAME="ABC", BRANDID=16, PRODUCTID=57,BRANDCATEGORY = "Electronics"})

是否可以使用Kafka流进行此操作,如果是,那么如何?

1 个答案:

答案 0 :(得分:2)

如果您想加入Kafka Streams,您需要提取join属性并将其设置为消息的键:

KStream streamOfTable1 = ...
streamOfTable1.selectKey(/*extract productId and set as key*/).to("newTopic1");

KStream streamOfTable2 = ...
streamOfTable2.selectKey(/*extract productId and set as key*/).to("newTopic2");

KTable table1 = builder.table("newTopic1");
KTable table2 = builder.table("newTopic2");

table1.join(table2, ...).to("resultTopic");

有关详细信息,请参阅文档:http://docs.confluent.io/current/streams/developer-guide.html#joining

我确实假设你需要一个KTable-KTable连接。注意,你需要创建" newTopic1"和" newTopic2"手动并且两者都需要具有相同数量的分区。 (参见http://docs.confluent.io/current/streams/developer-guide.html#user-topics

同时查看其他可用的联接类型,以防KTable-KTable联接不是您想要的。