文章目录
  1. 1. 方案介绍
  2. 2. 优缺点分析
  3. 3. 方案缺点
  • 小结
  • 在企业级生产环境,我们处于高可用的考虑,常常会部署多套MQ集群,提供集群高可用,保证高SLA。

    具体到RoceketMQ,在生产环境下我们也需要考虑高可用部署,尤其是跨机房(跨DC)情况下的高可用。

    方案介绍

    我们提供两组RocketMQ集群,假设他们分布在北京电信与联通两处机房。

    生产端生产时默认发往电信机房,在电信RocketMQ集群不可用时,切换到联通RocketMQ集群上,从而保证消息生产过程不被打断。

    而在消费端,同时启用两个消费者分别消费电信RocketMQ集群与联通RocketMQ集群,保证一定能消费到全量的消息。

    整个部署方式的示意图如下
    部署方式

    正常场景下数据流向是 1 -> 2 -> 4

    发生切换后数据流向是 1 -> 3 -> 5

    优缺点分析

    该方案存在几个关键点:

    1. 生产者何时切换,换言之如何判定RocketMQ集群状态为不可用?
    2. 发生切换后,是否需要切换回来,以及何时需要切换回来?
    3. 切换后是否会造成消息丢失,如何解决?
    4. 切换后是否会造成消息顺序错乱,如何解决?
    5. 该高可用方案可以Cover哪些场景,以及无法Cover哪些场景?

    我们在下文中具体分析以上问题:

    1. 生产者何时发生切换,换言之,如何判定北京电信RocketMQ集群状态为不可用?

    策略:生产端由生产者自行根据本地发送状况决定,例如连续发送失败N次,则在本地标记该集群A为不可用状态。切换到集群B进行生产。

    2. 发生切换后,是否需要以及何时切换回来?

    生产端的健康检查线程会周期性的检查两个集群的状态,集群A故障后,必定会通过运维操作恢复,然后健康检查后将集群A的状态恢复为可用状态。此时是否需要切换有业务自行决定。

    生产端为RocketMQ集群A和RocketMQ集群B配置分别一个优先级,如果两个集群优先级相同,在RocketMQ集群A恢复后不需要切换回去。如果RocketMQ集群A的优先级高于RocketMQ集群B,则在RocketMQ集群A恢复后切换会A。这样可以提供足够的灵活性。

    建议在两个RocketMQ集群的性能与质量没有显著差异时,故障集群恢复后,不要切换回去。减少一次切换的开销。

    3. 切换后是否会造成消息丢失如何解决?

    生产端一旦认定集群A不可用会立即不再往集群A进行生产,而转向B进行生产。此时的消费端的两个消费者则会被动的发现消费者A不再接收到消息,而消费者B转而开始接收消息。消费端并不关注集群究竟发生了什么。

    如果集群A是真的宕机或者断网,那么在集群A内积压的消息,故障期间无法再被消费者获取。如果消息具有强时效性,这部分数据应当被认为丢失,如果不具有强时效性,那么切换回去后,能被继续消费掉,可以认为不会丢失消息。如果集群A并非真的宕机或者断网,其实能提供消费,只是生产端认为其不可用,那么集群A内的消息会被消费者消费完,不会丢失消息。

    综上,对于具有强时效性的业务场景,可以认为切换时存在消息丢失。因此业务需要有额外补偿机制,保证在某些消息一直未被消费时,通知到生产端,并触发重新生产。

    同时,消费端做好消息去重的准备,因为切换回去后,可能会产生重复消费。

    4. 切换后是否会造成消息乱序如何解决?

    对于有序消息,生产端一般会根据Hash把同Key的消息发送到同一个Partition,然后消费者顺序消费Partition,从而保证消息的有序性。

    切换之前以及切换之后,消息生产和消费仍然满足上述规律,因此消息仍旧是有序的。

    切换的那一刻,会出现部分消息在故障集群A中,后续消息在集群B中,此时消费端可能会出现两种情况:

    情况1:消费者A无法再取得故障集群A中的消息,消费者B开始获取集群B中的消息。会出现部分消息丢失,但是没有出现消息乱序。

    情况2:消费者A仍然能够取得故障集群A中的消息,且消费者B开始获取集群B中的消息。此时会出现消费者A和消费者B两者之间部分消息乱序。

    对于情况2,业务可以根据需要对消息添加一些版本信息,也就是发送方对消息进行全局的排序,作为消息顺序依据。

    5. 该高可用方案可以Cover哪些场景,无法Cover哪些场景?

    可以Cover的场景:

    • 电信/联通一处的RocketMQ集群所在机房宕机
    • 电信/联通一处的RocketMQ集群所在机房断网
    • 电信/联通一处的RocketMQ集群本身不可用

    不能Cover的场景:

    • 电信/联通两处RocketMQ集群同时宕机、断网、不可用
    • 消费者所在机房与正在服务的RocketMQ集群之间网络不通

    方案缺点

    1. 需要生产端实现状态判断与切换逻辑,存在一定的工作量。
    2. 正常情况下只有一个集群在提供服务,资源存在浪费。

    小结

    到此我们对跨机房的高可用RocketMQ集群的部署就有了一定的了解,可以看到还是有很多额外的工作要做。

    如果业务量不需要,则不需要建设如此复杂的架构,毕竟架构是演进出来的而不仅仅是设计出来的。



    版权声明:

    原创不易,洗文可耻。除非注明,本博文章均为原创,转载请以链接形式标明本文地址。

    文章目录
    1. 1. 方案介绍
    2. 2. 优缺点分析
    3. 3. 方案缺点
  • 小结
  • Fork me on GitHub