数据从一端到另一端,中途的所有链路和节点都可能丢失数据
假设两端需要传输数据,则数据可能会在中途丢失
P -> C
若增加一台broker来中转数据,则broker前后的链路传输途中可能丢失数据,broker自身也可能丢失数据
P -> B -> C
解决数据丢失问题
1、防止P -> B丢失,使用同步机制,或者异步+回调+本地消息表
2、防止B自身丢失,可使用定时持久化消息,使用分布式节点+冗余数据
3、防止B -> C丢失,可以使用同步机制,或者异步+回调+本地消息表
其中,3的同步机制,即C每次Poll后,直到业务处理完,再commit消息。连接需要等待漫长的业务处理完后才能释放,明显不合理,很少使用
而3的异步+回调+本地消息表,则是C每次Poll完后直接释放连接,等待业务完成消息后,再回调broker commit消息,是大多MQ默认的手段
注意:消费端收到消息,要保证走完全流程处理才Commit消息,且只要走完业务全流程,哪怕处理失败,也应该commit。只有在处理消息过程中宕机这种极端情况,才需要重新消费
提升数据传输过程吞吐量的思路,是减少端到端的网络通信次数
1、P -> B,可以在P设置缓冲区,定时或定量 批量传输消息,从“N条消息N次连接”优化为“N条消息1次连接”(同步机制)
2、B -> C,C端批量Poll消息,定时 批量提交Commit请求,从“N条消息N次连接”优化为“N条消息2次连接”(异步+回调)
MQ产品的特殊情况
Kafka,使用Offset作为B -> C端的同步机制,只有当某个offset之前的所有消息都被消费了,这个offset才能更新到B端。这就导致了如果一个早期的消息一直得不到commit,offset无法被更新,则早期的消息会不断的被重发。这个问题可以通过阈值到期加入死信队列来解决
RocketMQ,为什么不使用Zookeeper作为注册中心,待调研,参考:
- 面试题系列:MQ 夺命连环11问 - 知乎 (zhihu.com)
容错性优化
- B端不可靠的场景,在P端增加一个自消费的topic和机器,增加容错性
- C端不可靠场景,增加一个临时Consumer端,吸收积压消息,转发到一个新的topic机器中做缓冲
总结:针对节点不可靠场景,可以临时增加(或预设)机器模拟该节点,来消化和缓冲临时数据
分布式节点+冗余数据的技术关键
- 需要多台机器能够自治
- 心跳机制,保证节点健康监测的基础
- 选举机制,保证节点健康监测的可靠性
- 需要保证多台机器的数据一致性
- raft协议
- 提供多台Broker的发现机制:使用注册中心处理