Kafka(0.9.0.X版本)的消息传输担保机制

在分布式消息系统中,消息的传输担保有两个层面的含义,一是对消息发送与接收的担保,二是对消息成功处理的担保。我们常说的at most once, at least onceexactly once在这两层中意义是不同的。

  • at most once
    如果只论消息的收发,那么消息只会被投递一次而不管能否被consumer收到。如果考虑消息的处理,那么这条消息可能会因为没有收到而未处理,也可能因为收到以后崩溃而未处理。

  • at least once
    只论消息收发的情况下,消息可能会被重复投递。考虑消息处理时,则消息可能会被成功处理一次后,因为其它 consumer 再次收到消息而被重复处理。

  • exactly once
    只论消息接收时,消息只会被成功收发一次。考虑消息处理时,则保证消息只会被成功处理一次。

对于kafka来说,它默认保证的是消息收发层面 at least once,即如果consumerA没有收到消息,则kafka会重发消息。但是对于开发者而言,只收到消息是毫无意义的,必须对消息进行处理。因此考虑消息处理的成功与否才是开发者最关心的问题。 下面只讨论这种情况下的消息传输担保。

由于kafka在客户端保存offset的机制,开发者可以自己实现对at most onceexactly once的保证,这取决于 consumer 提交 offset 的时机

consumer对消息的处理可以分成三步:读取消息、处理消息和提交offset。如果consumer读取消息后,先提交offset,再处理消息,那么如果提交offset后崩溃没有来得及处理消息,这时因为offset已经提交所以其它consumer不会再次收到消息,这就是at most once的实现。如果读取消息后,先处理消息,再提交 offset , 此时若处理完消息后崩溃,那么由于offset还没提交,其它consumer会再次收到此消息进行处理,这就是at least once的实现。实际上开发者最想要的是exactly once, 我们有两种方式来实现只有一次的保证。

第一种是使用两阶段提交。即消息处理与提交offset看作一个事务,通过引入协调者实现两阶段提交协议。

第二种比较简单,是将consumer处理的结果与offset值输出到同一存储结构中。举个例子,consumer A收到扣钱的消息,那么它对消息的处理结果就是 update 数据库将余额减少。在 update 余额的同时再在当前表中写入offset值。这种方式最关键的一点是,要让Kafka在你指定的数据库中保存offset值(Kafka提供的 low level API可以做到这一点,而 Hight level API只能将offset存放到zookeepr中)。这样一来,当kafka检查offset时会读你的库,而你在处理消息时已经更新了offset, 这样消息处理跟提交offset就相当于是一件事了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值