0%

消息丢失问题

消息丢失问题

消息丢失主要有三种可能

  • 生产者丢失数据
  • 消息队列丢失数据
  • 消费者丢失数据

下面来分别说明这三种情况

生产者丢失数据

在生产者发送数据时,为了减少IO,其实是将多个请求进行合并发送的,被合并的数据存在本地buffer中,这里可以先在事务中进行数据库存储,然后在进行消息发送,这样就算发送失败也可以使用定时来进行消息发送。然后使用callback来确认消息是否发送到消息队列,如果没有发送成功可以来进行重试操作

还有就是在进行kafka配置时,设置acks=all

消息队列丢失数据

消息队列丢失数据,看看消息队列是否支持持久化操作,这样就算是消息系统挂了,重启之后也可以恢复数据,而对于kafka来说,本身就是写入log的(是属于异步刷盘),那么数据丢失的原因可能就是数据还没有同步,但是leader挂掉了,此时follower切换为leader,导致数据丢失

这里就要看一下acks的确认机制了

acks确认机制,用于配置代理接收到消息后向生产者发送确认信号,以便生产者根据acks进行相应的处理,该机制通过属性request.required.acks设置,0、-1、1三种,默认1

  • acks=0时,生产者不需要等待代理返回确认消息,而连续发送消息。消息投递速度加快,broker接手之后直接回复ack,但是此时leader没有落盘,如果broker故障就可能丢失数据

  • acks=1时,生产者需要等待leader副本已成功将消息写入日志文件。降低了数据丢失的可能性,但还是存在,如果在leader成功存储数据后,follower没有来得及同步,此时leader挂掉了,而follower没有进行同步,从ISR中选举出来新的leader也就没有这条数据,数据就会丢失

  • acks=-1时,leader副本和所有ISR列表中的副本都完成数据存储之后才会向生产者发送确认消息,这种策略保证只要leader副本和follower副本中至少有一个节点存活,数据就不会丢失

此时依然还是采用配置acks为all,保证leader和follower只要有一个节点存活,数据就不会丢失,当然还需要配置一下副本,保证数据不会只有一份

消费者丢失数据

消费者丢失数据一般是因为开启了自动确认的模式,使得消费者自动确认收到消息,消息队列将消息进行删除,但是没有进行业务操作,此时系统出现问题,导致业务处理异常,并没有进行入库操作,解决方案就是采用手动确认方式,在处理完业务入库之后在进行确认操作

欢迎关注我的其它发布渠道