写点什么

笔记 20240615

作者:Geek_d01095
  • 2024-10-25
    辽宁
  • 本文字数:2947 字

    阅读完需:约 10 分钟

记一次 RocketMQ 故障演练过程,同时解开了对 RcoketMQ 高可用的一些误解,RocketMQ 版本 4.x


  • 集群配置:2 个 namesrv,3 个 broker(1 个 master-slave、1 个 master)


  • | clusterName | brokerName | brokerId | brokerRole | IP |

  • | :------------- | -------------------- | -------- | ------------ | ------------|

  • | test1-rocketmq | broker-172.16.73.210 | 0 | ASYNC_MASTER | 172.16.73.210 |

  • | test1-rocketmq | broker-172.16.73.210 | 1 | SLAVE | 172.16.73.184 |

    | qa-rocketmq | broker-172.16.73.211 | 0 | ASYNC_MASTER | 172.16.73.211 |


  • namesrv 也部署在 172.16.73.210、172.16.73.211 两台机器上。broker、namesrv 都使用的 docker 部署。rocketmq1-qa.yzw.cn、rocketmq2-qa.yzw.cn 解析到 172.16.73.210,rocketmq3-qa.yzw.cn:9876 解析到 172.16.73.211。

  • 172.16.73.210 - broker.conf 部分内容如下:


  brokerClusterName=test1-rocketmq  brokerId=0  brokerName=broker-172.16.73.210  namesrvAddr=rocketmq1-qa.yzw.cn:9876;rocketmq2-qa.yzw.cn:9876;rocketmq3-qa.yzw.cn:9876;172.16.73.210:9876;172.16.73.211:9876;  brokerIP1=172.16.73.210  brokerIP2=172.16.73.210  brokerPermission=6  brokerRole=ASYNC_MASTER  flushDiskType=SYNC_FLUSH  listenPort=10911  haListenPort=10912  defaultTopicQueueNums=4  fetchNamesrvAddrByAddressServer=true  autoCreateSubscriptionGroup=true  autoCreateTopicEnable=true  flushCommitLogTimed=false  fileReservedTime=168  sendThreadPoolQueueCapacity=40000
复制代码


72.16.73.184 - broker.conf 部分内容如下:


  brokerClusterName=test1-rocketmq  brokerId=1  brokerName=broker-172.16.73.210  namesrvAddr=rocketmq1-qa.yzw.cn:9876;rocketmq2-qa.yzw.cn:9876;rocketmq3-qa.yzw.cn:9876;172.16.73.210:9876;172.16.73.211:9876;  brokerIP1=172.16.73.184  brokerPermission=6  brokerRole=SLAVE  flushDiskType=SYNC_FLUSH  listenPort=10911  haListenPort=10912  defaultTopicQueueNums=4  fetchNamesrvAddrByAddressServer=true  autoCreateSubscriptionGroup=true  autoCreateTopicEnable=true  flushCommitLogTimed=false  fileReservedTime=168  sendThreadPoolQueueCapacity=40000
复制代码


72.16.73.211 - broker.conf 部分内容如下:


  brokerClusterName=qa-rocketmq  brokerId=0  brokerName=broker-172.16.73.211  namesrvAddr=rocketmq1-qa.yzw.cn:9876;rocketmq2-qa.yzw.cn:9876;rocketmq3-qa.yzw.cn:9876;172.16.73.210:9876;172.16.73.211:9876;  brokerIP2=172.16.73.211  brokerIP1=172.16.73.211  brokerPermission=6  brokerRole=ASYNC_MASTER  flushDiskType=SYNC_FLUSH  listenPort=10911  haListenPort=10912  defaultTopicQueueNums=4  useEpollNativeSelector=true  fetchNamesrvAddrByAddressServer=true  autoCreateSubscriptionGroup=true  autoCreateTopicEnable=true  flushCommitLogTimed=false  fileReservedTime=168  sendThreadPoolQueueCapacity=40000
复制代码


  • 故障演练步骤如下:

  • 查看集群状态


./mqadmin clusterList -n rocketmq1-qa.yzw.cn:9876
复制代码


集群状态正常,日志正常


  1. 卸载数据盘

  2. 运维通过控制台卸载 172.16.73.210 的数据盘模拟磁盘故障,172.16.73.211、172.16.73.184 不做任何操作。

  3. 查看集群状态


./mqadmin clusterList -n rocketmq1-qa.yzw.cn:9876
复制代码


报错连接异常,因为此时 172.16.73.210 数据盘卸载导致 docker 停止服务已经宕机


  1. 测试发送消息

  2. 172.16.73.210 无法发送消息,172.16.73.211 能够正常发送消息,此时 172.16.73.210 上的 topic 已经发送消息只能从 slave(172.16.73.184)节点消费历史消息,部分 mq 客户端连接已在报错:rocketmq1-qa.yzw.cn:9876 状态异常无法连接。因为 172.16.73.210 的 namesrv 处于故障中不可用。

  3. 手动故障转移

  4. 手动修改配置将 172.16.73.184 升级为 Master,修改后的 broker.conf 配置如下


     brokerClusterName=test1-rocketmq     #修改brokerId为0     brokerId=0     brokerName=broker-172.16.73.210     namesrvAddr=rocketmq1-qa.yzw.cn:9876;rocketmq2-qa.yzw.cn:9876;rocketmq3-qa.yzw.cn:9876;172.16.73.210:9876;172.16.73.211:9876;     brokerIP1=172.16.73.184     brokerPermission=6     #修改角色为master     brokerRole=ASYNC_MASTER     flushDiskType=SYNC_FLUSH     listenPort=10911     haListenPort=10912     defaultTopicQueueNums=4     fetchNamesrvAddrByAddressServer=true     autoCreateSubscriptionGroup=true     autoCreateTopicEnable=true     flushCommitLogTimed=false     fileReservedTime=168     sendThreadPoolQueueCapacity=40000
复制代码


重启服务


docker restart jifgnsgmagm
复制代码


查看集群状态显示两个 master 节点看起来正常,但是查看 172.16.73.184 的 broker.log 日志有很多 WARN 日志:


2024-06-17 13:53:45 WARN PullMessageThread_87 - PULL_OFFSET_MOVED:correction offset. topic=auac_profile_notify_topic, groupId=yzw-user-jicai-qa, requestOffset=703, newOffset=0, suggestBrokerId=0
复制代码


部分 mq 客户端发送消息任然报错,因为 172.16.73.210 的 namesrv 处理故障状态不可用。172.16.73.211 的 namesrv 正常可用。


  1. 恢复磁盘(失败)

  2. 由于第 2 步操作失误导致数据丢失且无法恢复

  3. 重新部署 Master

  4. 挂在新磁盘后重新部署一个 broker(master)和 namesrv,把集群恢复成原来的节点组成。但是由于数据丢失了 172.16.73.210 的数据无法找回等于是一个新 broker。重新部署 master 后日志大量报错:


2024-06-18 09:29:51 ERROR PullMessageThread_77 - the topic jc-contract-esign-push not exist, consumer: 172.16.73.231:57878
复制代码


  • 进一步研究 RocketMQ 高可用

  • 本地故障演练使用的 rocketmq 部署方式是 master-slave,这种方式并不是完全高可用的,只能做到 master 宕机后消费者能从 slave 正常消费消息并且任然可能丢失少部分消息(ASYNC_MASTER 的原因)。master-slave 部署方式无法完成自动故障转移,需要手动运维进行故障转移,修改 slave 的配置重启服务将 slave 升级为 master 提供服务。rocketmq 在 4.5 版本后提供了自动故障转移的 DLedger 部署方式,DLedger 使用了 raft 作为一致性协议(最少需要 3 个节点才具备自动容灾切换能力)。

  • 总结

  • master-slave 模式无法做到完全高可用,或者严谨点说是没有做到高可用,无法自动故障转移必须人工介入。

  • 手动将 slave 升级为 master 后大量警告日志,怀疑升级后的 broker 不可用,只有另一个 broker 是可用的。

  • 将宕机的 master 重新部署后(数据完全丢失),并且日志大量报错。怀疑重新部署后的 master 不可用。

  • 参考链接

  • https://rocketmq.apache.org/zh/docs/4.x/bestPractice/02dledger#dledger%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA

  • https://blog.csdn.net/weixin_42405670/article/details/118072900

  • https://cloud.tencent.com/developer/article/1521583

  • https://blog.csdn.net/jiajiren11/article/details/80528406

发布于: 刚刚阅读数: 6
用户头像

Geek_d01095

关注

还未添加个人签名 2024-03-15 加入

还未添加个人简介

评论

发布
暂无评论
笔记 20240615_RocketMQ_Geek_d01095_InfoQ写作社区