我正在开发一个使用 Kafka Streams 进行组件之间通信的分布式系统。 其中一个组件(为了简单起见,BRAIN)管理发送给其他组件(A、B、C、D、E、F、G)的一系列消息。
流程如下所示:
BRAIN向组件A发送消息并等待其完成反馈。 一旦 A 做出响应,BRAIN 就会向 B、C 和 D 发送消息,因为它们可以并行工作,然后等待三者的反馈。 收到所有响应后,BRAIN 依次向 E、F、G 发送消息(当收到上一个的完成反馈时,向下一个发送消息。
为了跟踪这些组件的完成状态并确定何时发送下一条消息,BRAIN 需要状态存储。
Kafka Streams 通过内部状态存储和变更日志主题自然支持状态处理。 然而,管理和调试 Kafka Streams 是一项挑战,我们经常会遇到错误,99% 与有状态组件相关(可能是因为它没有正确配置/开发),并且我们最终清理了所有主题,因此我们可以从划痕。 如果这在开发环境中“没问题”,那么在生产环境中可能会是一个大问题。 项目经理担心这一点,我理解他。 最后但并非最不重要的一点是,有一个陡峭的学习曲线,特别是对于初级开发人员来说,所以通常当错误发生时,只有高级和架构师知道如何修复它们。
所以我在想,为什么不使用 MongoDB 来存储状态,而不是使用 Kafka Streams 的状态存储呢?
Kafka 将继续用于组件之间的通信,通过生成和消费消息。 BRAIN 将直接向 MongoDB 写入和读取状态信息(例如 A、B、C 等的完成状态)。
与使用 Kafka Streams 的本机状态管理相比,有哪些权衡?在设计 MongoDB 为基于 Kafka 的工作流程处理状态的系统时,我应该牢记哪些注意事项?
我唯一能想到的是在同一时刻从并行组件接收完成反馈的潜在问题。它有可能导致工作流程永久空闲(但看起来相当遥远的选择)。
Kafka Streams 不是状态存储,而是一个处理框架。
默认存储是RocksDB。是的,有一个学习曲线。是的,您需要调整它(默认值不太理想)。是的,您可能会花费数小时进行故障排除...为什么 MongoDB 没有相同的功能(假设从零经验开始)?
无论如何,
StateStoreSupplier
接口都可以实现,你可以把状态写在任何你想要的地方。 GitHub 上有 Solr、Neo4j、Redis 等的示例。然而,您失去的是精确的事务保证。