涉及两个主题:commands
这是一个KStream - 你不会相信! - 命令和 state
,这是KTABLE(只是常规的,不是 GlobalKTable)。
拓扑如下:
commands.leftJoin(state, computeNewState).to(state)
即命令作用于当前状态并生成同一主题的新状态。有点command X state -> state
在函数式编程方面;最终在哪里state
生成到初始状态的同一位置。
在我看来,经典的竞争条件隐藏在那里;因为两个(几乎)同时的命令可能会产生以下不幸的序列:
-
command_1
到达并消耗state_1
; - 重新计算后,
state_2
是通过应用command_1
生成的; -
state_2
reactto
节点并有效地异步 IO 到 Kafka 发生...... - ...但应用速度还不够快;同时
command_2
具有相同的 key ,例如leftJoin
作用于state_1
而不是state_2
仅仅因为state_2
尚未交付给 Kafka,且 Kafka Streams 实例尚未看到; - QED。
我说得对吗?
最佳答案
你的描述是正确的。
也许您可以只使用单个输入主题并使用聚合来修改状态?对于这种情况,状态更新将是同步的。
如果这是不可能的,我建议回退到处理器 API。您将状态主题读入手动添加的状态存储中。您还将状态存储连接到处理评论主题的处理器 - 这样,进程可以在直接处理命令时读取并修改状态 - 将任何内容写回到状态输入主题中被要求。
关于apache-kafka - 这个特定的 Kafka Streams 拓扑是否引入了竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62753824/