尝试访问已定义状态存储区中的所有键值,但是在.transform()方法中,我只能使用一个键(即源键)进行访问
KeyValueStore<String, String> SS=context.getStateStore("macs");
SS无法在状态存储区中获取所有键值
SS.get("key1");
SS.get("key2");
SS.get("key3");
SS.get("key4");
4个返回值中只有1个返回值,其余所有返回null
答案 0 :(得分:1)
SS无法在状态存储区中获取所有键值
这是预期的行为。实际上,在分布式Kafka Streams应用程序的运行实例中,跨状态存储的实际实例对Kafka Streams中“逻辑”状态存储中的数据进行了分区(分片)(即使您仅运行1个应用程序实例,例如1个Docker容器)为您的应用程序)。让我在下面解释。
一个简化的示例来说明分区状态存储的性质:如果您的应用程序从具有5个分区的输入主题中读取,则此应用程序的处理拓扑将使用5个流任务,并且每个流任务将获得一个分区的一个分区。 “逻辑”状态存储(请参见Kafka Streams Architecture)。如果仅为您的应用程序运行1个应用程序实例(例如1个Docker容器),则此单个实例将执行所有5个流任务,但这些流任务是无共享设置–这意味着数据仍在分区。 Kafka Streams中的KTable
也是如此,它们也以这种方式进行分区。
另请参阅:Is Kafka Stream StateStore global over all instances or just local?
您的上述示例仅在输入主题仅具有1个分区的特殊情况下才有效,因为那时只有1个流任务,因此只有1个状态存储(可以访问输入数据中的所有可用键) )。
尝试访问已定义状态存储中的所有键值[...]
现在,如果您确实想访问输入数据中的所有可用键,则有两个选择(除非您想沿用只有一个分区的输入主题的特殊情况):>
GlobalKTable
),而不是常规的分区状态存储。可以通过StreamsBuilder#addGlobalStore(...)
定义/创建全局状态存储,但是IIRC不需要显式地将全局存储添加(“附加”)到Processor中,而对于正常状态存储则必须这样做。相反,所有处理器都可以自动访问全局存储。请注意,在这两个选项中,您只能访问状态存储中的数据 。在这两种情况下,您不能直接写入状态存储。如果需要修改数据,则必须通过用于填充商店的输入主题间接更新它们。