我目前正在尝试为kafka设计一个可伸缩的消费体系结构,并且在偏移协调方面遇到了一些问题。对于我的用例来说,kafka所使用的每条消息只处理一次是很重要的。
以下面的例子来说明这个问题:
消费者从Kafka检索消息
使用者处理消息(业务逻辑,耶!)
耗电元件完成处理,增加本地偏移量
消费者试图将补偿提交回Kafka
此网络呼叫因x原因失败
上述错误或其他任何错误都会导致使用者在重试偏移提交之前崩溃
系统orchestrator调出另一个使用者,然后该使用者获取过期的偏移量
将检索并重新处理相同的消息(错误!)
对于那些比我有更多分布式系统经验的人,您可能已经认识到这是(或多或少)应用于kafka补偿/工作结果协调的两个一般问题。
我曾考虑过在一个(可能是sql)db事务中提交偏移量和工作结果,但这会将这些实现联系在一起,并限制我的数据存储选项(还有,如果我将数据存储移动到没有事务的地方,我该怎么办?)。另一种可能的解决方案是对每条消息进行散列,并使用bloom过滤器来防止重复处理,但现在我们开始增加我希望避免的复杂性。
1条答案
按热度按时间iq0todco1#
这类问题在系统之间的边界上很常见,kafka的faq建议使用事务来实现一次交付保证。
您提出了一个问题,即对事务的需求将限制对sql解决方案的存储选择。这是不正确的,因为许多NoSQL解决方案如RiAK、Casand、ReTykDB或CyoRoCdDB都有诸如单文档原子或比较和设置操作之类的机制,这些操作可以作为对酸性事务的替代或作为客户端酸交易的基础。
有关更多信息,请参阅“如何管理多个数据库上的事务”问题,因为多分片事务的算法在多密钥级别上也可以正常工作。