Ald*_*nio 9 apache-kafka apache-kafka-streams
我想完全理解 kafka-streams 处理器必须遵守的关于处理器输入及其状态分区的规则。具体我想了解:
我一直在对此进行一些研究,我发现的答案似乎不是很清楚,有时还相互矛盾:例如,这个似乎表明商店是完全独立的,您可以使用任何键,而这个则说您永远不应该使用具有与输入主题中的键不同的键的商店。
感谢您的澄清。
您必须区分输入分区和存储分片/更改日志主题分区以获得完整的图片。此外,这取决于您是使用 DSL 还是处理器 API,因为 DSL 会进行一些自动重新分区,而处理器 API 不会。因为 DSL 会编译为处理器 API,所以我将从这个开始。
如果您的主题有 4 个分区,并且您创建了一个使用该主题的有状态处理器,您将获得 4 个任务,每个任务运行一个处理器实例,该处理器实例维护存储的一个分片。请注意,整体状态分为 4 个分片,每个分片基本上与其他分片隔离。
从处理器 API 运行时的角度来看,输入主题分区和状态存储分片(包括它们对应的更改日志主题分区)是一个并行单元。因此,存储的变更日志主题是用 4 个分区创建的,并且变更日志主题分区-X 映射到输入主题分区-X。请注意,Kafka Streams在写入变更日志主题时不使用基于哈希的分区,而是明确提供分区编号,以确保处理输入主题分区 X 的“处理器实例 X”仅从以下位置读取/写入/进入变更日志主题分区-X。
因此,如果您愿意,运行时与键无关。
如果您的输入主题未按键进行分区,则具有相同键的消息将被不同的任务处理。根据程序的不同,这可能可以(例如过滤),也可以不可以(例如,每个键计数)。
类似于状态:您可以将任何键放入状态存储中,但此键对于相应的分片是“本地的”。其他任务,永远不会看到这个键。因此,如果您在不同任务的商店中使用相同的密钥,它们将完全相互独立(就像它们是两个密钥一样)。
使用 Processor API,您有责任根据您需要的运算符语义正确划分输入数据并正确使用存储。
在 DSL 级别,Kafka Streams 将确保数据正确分区,以确保正确的运算符语义。首先,假设输入主题按键分区。如果键被修改,例如通过,selectKey()
并且下游操作符是一个聚合,Kafka Streams 首先对数据进行重新分区,以确保具有相同键的记录在同一主题分区中。这确保了每个密钥都将在单个存储分片中使用。因此,DSL 将始终对数据进行分区,以便永远不会在不同的分片上处理一个键。
归档时间: |
|
查看次数: |
1211 次 |
最近记录: |