eth*_*nny 4 java apache-kafka apache-kafka-streams
假设我有一个包含大量分区的主题.我在那里写K/V数据,并希望通过键在Tumbling Windows中聚合所述数据.
假设我启动了尽可能多的工作实例,因为我有分区,每个工作器实例都在一台单独的机器上运行.
我如何确保结果聚合包含每个键的所有值?IE我不希望每个工作者实例都有一些值的子集.
这是StateStore会用于什么的东西吗?Kafka是自己管理这个还是我需要提出一种方法?
我如何确保结果聚合包含每个键的所有值?IE我不希望每个工作者实例都有一些值的子集.
通常,Kafka Streams确保同一个键的所有值都将由同一个(并且只有一个)流任务处理,这也意味着只有一个应用程序实例(您描述为"工作者实例")将处理该值的值键.请注意,应用程序实例可能会运行1个以上的流任务,但这些任务是隔离的.
此行为是通过对数据进行分区来实现的,而Kafka Streams确保分区始终由相同且仅一个流任务处理.键/值的逻辑链接是,在Kafka和Kafka Streams中,键总是被发送到同一个分区(这里有一个问题,但我不确定是否有必要详细讨论范围这个问题),因此一个特定的分区 - 在可能的许多分区中 - 包含相同密钥的所有值.
在某些情况下,这种连接两个流时为A
和B
,你必须确保虽然对于聚合将同一个按键上操作,以确保这两个流共存于同一个流任务的数据-这又是怎么一回事确保相关的输入流分区并因此匹配密钥(分别来自A
和B
分别)在同一流任务中可用.您在这里使用的典型方法是selectKey()
.完成后,Kafka Streams确保,为了加入两个流A和B以及创建连接的输出流,同一个键的所有值将由同一个流任务处理,因此也是同一个应用程序实例.
例:
A
关键.userId
{ georegion }
B
关键.georegion
{ continent, description }
当两个流使用相同的密钥时,仅连接两个流(从Kafka 0.10.0开始).在此示例中,这意味着您必须重新键入(并因此重新分区)流,A
以便将生成的密钥从更改userId
为georegion
.否则,从Kafka 0.10开始,您无法加入A
,B
因为数据不在共同负责实际执行连接的流任务中.
在此示例中,您可以通过以下方式重新键入/重新分区流A
:
// Kafka 0.10.0.x (latest stable release as of Sep 2016)
A.map((userId, georegion) -> KeyValue.pair(georegion, userId)).through("rekeyed-topic")
// Upcoming versions of Kafka (not released yet)
A.map((userId, georegion) -> KeyValue.pair(georegion, userId))
Run Code Online (Sandbox Code Playgroud)
该through()
调用仅在Kafka 0.10.0中需要实际触发重新分区,而后续版本的Kafka将自动为您执行这些操作(即将推出的功能已在Kafka中完成并可用trunk
).
这是StateStore会用于什么的东西吗?Kafka是自己管理这个还是我需要提出一种方法?
一般来说,没有.上述行为是通过分区而不是通过状态存储来实现的.
有时因为您为流定义的操作而涉及状态存储,这可能解释了您提出此问题的原因.例如,窗口操作将需要管理状态,因此将在幕后创建状态存储.但是你的实际问题 - "确保结果聚合包括每个键的所有值" - 与状态存储无关,而是与分区行为无关.
归档时间: |
|
查看次数: |
711 次 |
最近记录: |