mq消息丢失

kafka消息不丢
acks = all Partition Leader接收到消息之后,还必须要求ISR列表里跟Leader保持同步的那些Follower都要把消息同步过去,才能认为这条消息是写入成功了
acks = 1 默认 表我们的消息被leader接收之后就算被成功发送
acks =0 完全不关心消息是否发送成功


ack确认机制设置为0,表示不等待响应,不等待borker的确认信息,最小延迟,producer无法知道消息是否发生成功,消息可能丢失,但具有最大吞吐量。

ack确认机制设置为-1,也就是让消息写入leader和所有的副本,ISR列表中的所有replica都返回确认消息。

ack确认机制设置为1,leader已经接收了数据的确认信息,replica异步拉取消息,比较折中。

ack确认机制设置为2,表示producer写partition leader和其他一个follower成功的时候,broker就返回成功,无论其他的partition follower是否写成功。
replication.factor >=3 消息分区的副本数
min.insync.replicas >1 消息写入多少副本才算提交



rocketmq 消息不丢
send 方法是一个同步操作,只要这个方法不抛出任何异常,就代表消息已经发送成功。

消息发送成功仅代表消息已经到了 Broker 端,Broker 在不同配置下,可能会返回不同响应状态:

SendStatus.SEND_OK
SendStatus.FLUSH_DISK_TIMEOUT
SendStatus.FLUSH_SLAVE_TIMEOUT
SendStatus.SLAVE_NOT_AVAILABLE


若想保证 Broker 端不丢消息,保证消息的可靠性,我们需要将消息保存机制修改为同步刷盘方式,即消息存储磁盘成功,才会返回响应。

修改 Broker 端配置如下:

## 默认情况为 ASYNC_FLUSH
flushDiskType = SYNC_FLUSH
若 Broker 未在同步刷盘时间内(默认为 5s)完成刷盘,将会返回 SendStatus.FLUSH_DISK_TIMEOUT 状态给生产者。

 

此时若 master 突然宕机且不可恢复,那么还未复制到 slave 的消息将会丢失。

为了进一步提高消息的可靠性,我们可以采用同步的复制方式,master 节点将会同步等待 slave 节点复制完成,才会返回确认响应。

Broker master 节点 同步复制配置如下:

## 默认为 ASYNC_MASTER
brokerRole=SYNC_MASTER
如果 slave 节点未在指定时间内同步返回响应,生产者将会收到 SendStatus.FLUSH_SLAVE_TIMEOUT 返回状态。

结合生产阶段与存储阶段,若需要严格保证消息不丢失,broker 需要采用如下配置:

## master 节点配置
flushDiskType = SYNC_FLUSH
brokerRole=SYNC_MASTER

## slave 节点配置
brokerRole=slave
flushDiskType = SYNC_FLUSH
同时这个过程我们还需要生产者配合,判断返回状态是否是 SendStatus.SEND_OK。若是其他状态,就需要考虑补偿重试。


消费阶段
消费者从 broker 拉取消息,然后执行相应的业务逻辑。一旦执行成功,将会返回 ConsumeConcurrentlyStatus.CONSUME_SUCCESS 状态给 Broker。

如果 Broker 未收到消费确认响应或收到其他状态,消费者下次还会再次拉取到该条消息,进行重试。这样的方式有效避免了消费者消费过程发生异常,或者消息在网络传输中丢失的情况。

posted @ 2020-08-03 18:17  沙漠里的小鱼  阅读(281)  评论(0编辑  收藏  举报