[英]Kafka stream join
我有2个kafka主题 - recommendations
和clicks
。 第一个主题具有由唯一ID(称为recommendationsId
)键入的建议对象。 每个产品都有一个用户可以单击的URL。
clicks
主题获取通过向用户推荐的那些产品URL的点击生成的消息。 它已设置为这些点击消息也由recommendationId
键入。
注意
建议和点击之间的关系是一对多的。 建议可能会导致多次点击,但点击始终与单个推荐相关联。
每个click对象都有一个相应的推荐对象。
点击对象的时间戳晚于推荐对象。
推荐和相应点击之间的差距可能是几秒到几天(比如最多7天)。
我的目标是使用Kafka stream join加入这两个主题。 我不清楚的是我是否应该使用KStream x KStream连接或KStream x KTable连接。
我通过按recommendations
表加入clicks
流来实现KStream x KTable
加入。 但是,如果建议是在加入者启动之前生成的,并且在加入者启动后点击到达,则无法看到任何加入的点击建议对。
我使用正确的加入吗? 我应该使用KStream x KStream
加入吗? 如果是这样,为了能够在过去7天内加入带有推荐的点击,我应该将窗口大小设置为7天吗? 在这种情况下,我还需要设置“保留”期吗?
我执行KStream x KTable
连接的代码如下。 请注意,我已经定义了类别Recommendations
和Click
以及它们对应的serde。 点击消息只是普通的String
(url)。 此URL字符串与Recommendations
对象连接,以创建一个发送到jointTopic
的Click
对象。
public static void main(String[] args){
if(args.length!=4){
throw new RuntimeException("Expected 3 params: bootstraplist clickTopic recsTopic jointTopic");
}
final String booststrapList = args[0];
final String clicksTopic = args[1];
final String recsTopic = args[2];
final String jointTopic = args[3];
Properties config = new Properties();
config.put(StreamsConfig.APPLICATION_ID_CONFIG, "my_joiner_id");
config.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, booststrapList);
config.put(StreamsConfig.KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
config.put(StreamsConfig.VALUE_SERDE_CLASS_CONFIG, JoinSerdes.CLICK_SERDE.getClass().getName());
KStreamBuilder builder = new KStreamBuilder();
// load clicks as KStream
KStream<String, String> clicksStream = builder.stream(Serdes.String(), Serdes.String(), clicksTopic);
// load recommendations as KTable
KTable<String, Recommendations> recsTable = builder.table(Serdes.String(), JoinSerdes.RECS_SERDE, recsTopic);
// join the two
KStream<String, Click> join = clicksStream.leftJoin(recsTable, (click, recs) -> new Click(click, recs));
// emit the join to the jointTopic
join.to(Serdes.String(), JoinSerdes.CLICK_SERDE, jointTopic);
// let the action begin
KafkaStreams streams = new KafkaStreams(builder, config);
streams.start();
}
这只要木匠(以上程序)运行后已产生两个建议,并点击工作正常。 但是,如果在网站运行之前生成推荐的点击到达,我看不到任何连接发生。 我该如何解决?
如果解决方案是使用KStream x KSTream
连接,那么请帮助我了解我应该选择哪个窗口大小以及选择的保留期限。
你的整体观察是正确的。 从概念上讲,您可以通过两种方式获得正确的结果。 如果使用流表连接,则有两个缺点(可能会在将来的Kafka版本中重新访问和改进)
null
,则将click事件写回输入主题(即,您获得了重试逻辑) - 当然,单个推荐的连续点击可能会出现故障,您可能需要在应用程序代码中考虑到这一点。 KTable
的第二个缺点是,随着时间的推移它会永远增长并且无限制,因为你会为它添加越来越多的独特建议。 因此,您需要通过将<recommendationsId, null>
形式的逻辑删除记录发送到推荐主题来实现一些“过期逻辑”,以删除您不再关心的旧建议。 如果您使用流 - 流联接,并且在推荐后7天可能发生单击,则您的窗口大小必须为7天 - 否则,点击将不会与推荐一起加入。
对于流 - 流加入,保留时间的答案略有不同。 它必须至少7天,因为窗口大小是7天。 否则,您将删除“运行窗口”的记录。 您还可以将保留期设置得更长,以便能够处理“延迟数据”。 假设用户在窗口时间范围结束时(推荐的7天时间跨度前5分钟)点击,但点击仅在1小时后报告给您的应用程序。 如果您的保留期限为7天作为您的窗口大小,则此迟到的记录将无法再处理(因为建议已被删除)。 如果您设置较长的保留期,例如8天,您仍然可以处理延迟记录。 这取决于您的应用程序/语义需要您想要使用的保留时间。
简介 :从实现的角度来看,使用流 - 流连接比使用流表连接更简单。 但是,预计可以节省内存/磁盘,并且可能会很大,具体取决于您的点击流数据速率。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.