kafka 精准一次性
重要性
在很多的流处理框架的介绍中, 都会说 kafka 是一个可靠的数据源, 并且推荐使用 kafka 当作数据源来进行使用. 这是因为与其他消息引擎系统相比, kafka 提供了可靠的数据保存及备份机制. 并且通过消费者 offset 这一概念, 可以让消费者在因某些原因宕机而重启后, 可以轻易得回到宕机前的位置.
而 kafka 作为分布式 MQ, 大量用于分布式系统中, 如消息推送系统, 业务平台系统 (如结算平台), 就拿结算来说, 业务方作为上游把数据传输到结算平台, 如果一份数据被计算, 处理了多次, 产生的后果将会特别严重. 消息队列确保写和读的准确是非常重要的, 但 kafka 的多分区的特性使之变得困难.
哪些因素影响幂等性
在写入一端: 要知道在分布式系统中, 出现网络分区是不可避免的, 如果 kafka broker 在回复 ack 时, 出现网络故障, kafka 挂掉, 节点宕机等情况, producer 将会重发, 如何保证 producer 重试时不造成重复或乱序? 或者 producer 挂了, 新的 producer 并没有旧 producer 的状态数据, 这个时候如何保证 exactly-once?
在读取一端: 即使 kafka 写入的消息满足了幂等性, consumer 拉取到消息后, 把消息交给线程池 workers, workers 线程对 message 的处理可能包含异步操作, 又会出现以下情况:
先 commit, 再执行业务逻辑: 提交成功, 处理失败 . 造成丢失.
先执行业务逻辑, 再 commit: 提交失败, 执行成功. 造成重复执行
先执行业务逻辑, 再 commit: 提交成功, 异步执行fail. 造成丢失
针对以上的问题, kafka 在 0.11 版新增了幂等型 producer 和事务型 producer. 前者解决了单会话单分区幂等性等问题, 后者解决了多会话多分区幂等性.
总结
总的来讲, 对于写入消息来说, kafka 可以通过设定 ack 为 0 来保证 at most once, 即至多一次写入, 也就是不重复, 但这样可能因为写入失败而丢失数据. 当然也可以通过设定 ack 为 -1 来保证 at leat once, 即至少一次写入, 也就是不丢失数据, 但这样可能因为副本同步成功后 leader 分区挂掉而无法向 producer 返回 ack 而导致 producer 重复生产数据. kafka 在 0.11 版本引入了幂等性和事务, 幂等性和 ack = -1 可以保证单会话单分区的写入的精准一次性, 再加上 kafka 写入事务可以保证跨会话跨分区的精准一次性. 而消费端的幂等性需要结合下游处理消息系统的机制去考虑, 比如是否有事务机制, 是否天然去重或幂等性.
1230

被折叠的 条评论
为什么被折叠?



