我正尝试在Kafka Streams的帮助下实现以下逻辑:
听一些来自主题的参考数据,例如ref-data-topic
并从中创建一个全局StateStore
。
收听来自另一个主题data-topic
的消息,该消息必须根据参考数据进行验证,并且发送到success
或errors
主题。。 p>
这是示例伪代码:
class SomeProcessor implements Processor<String, String> {
private KeyValueStore<String, String> refDataStore;
@Override
public void init(final ProcessorContext context) {
refDataStore = (KeyValueStore) context.getStateStore("ref-data-store");
}
@Override
public void process(String key String value) {
Object refData = refDataStore.get("some_key");
// business logic here
if(ok) {
sendValueToTopic("success");
} else {
sendValueToTopic("errors");
}
}
}
或者实现这种期望行为的规范方法是什么?
就像我现在想到的一种替代方法一样,是使用验证信息来丰富Processor中的数据,然后将所有内容发送到一个主题中,从而使客户端可以处理诸如validationStatus
在收到的消息中。
尽管如此,我确实希望有一个包含两个主题的解决方案,因为例如在这种情况下,我可以使用Kafka Connect将success topic
直接链接到某些数据存储区,并以某种方式处理error topic
。同样,在仅涉及一个主题的方法中,我不知道如何实现此“ store_only_successfully_validated_entities”用例。
有什么想法和建议吗?
答案 0 :(得分:1)
如果使用处理器API,则可以按名称将数据转发到其他处理器:
class SomeProcessor implements Processor<String, String> {
private KeyValueStore<String, String> refDataStore;
private ProcessorContext processorContext;
@Override
public void init(final ProcessorContext context) {
refDataStore = (KeyValueStore) context.getStateStore("ref-data-store");
processorContext = context;
}
@Override
public void process(String key String value) {
Object refData = refDataStore.get("some_key");
// business logic here
if(ok) {
processorContext.forward(key, value, To.child("success"));
} else {
processorContext.forward(key, value, To.child("error"));
}
}
}
插入拓扑时,将添加两个宿节点,名称分别为"success"
和"error"
,分别写入成功和错误主题。
或者您将forward
数据存储到单个接收器节点,并使用TopicNameExtractor
而不是硬编码的主题名称添加接收器。 (需要版本2.0。)
如果使用DSL,则可以使用KStream#branch()
来拆分流,并通过KStream#to(...)
将不同的数据堆积到不同的主题中(或者通过KStream#to(TopicNameExtractor)
使用动态路由-必需的版本2.0)