ROCKETMQ 主从切换机制
来源:互联网 发布:金贵软件怎么样 编辑:程序博客网 时间:2024/06/05 13:12
之前看rocketmq,然后在想一个问题,就是一主一从的集群结构中,如果master宕机了,consumer这边是怎么选择的,按照官方说明中,master挂了,但是slave中的消息仍然可以被consume消费到,然后master恢复后,master的消息又可以被消费到。
那么问题来了,consumer是怎么从master上面切换到slave上继续消费消息呢?首先明确一点,master宕机,就意味着这个broker不再写入,但是因为slave还在,所以还可以继续读。所以我们看一下consumer是怎么选择的?其实还有个疑问,就是master宕机后,会体现到负载均衡服务的重新分配吗?
先说第一个问题,跟代码进去:
PullConsumer:
PullResult pullResult = consumer.pullBlockIfNotFound(mq, null, getMessageQueueOffset(mq), 32);
一路next 到pullAPIWrapper.pullKernelImpl
然后发现,消费者消费从哪个服务器上面拉信息是通过这样确定的:public FindBrokerResult findBrokerAddressInSubscribe( final String brokerName, final long brokerId, final boolean onlyThisBroker) { String brokerAddr = null; boolean slave = false; boolean found = false; HashMap<Long/* brokerId */, String/* address */> map = this.brokerAddrTable.get(brokerName); if (map != null && !map.isEmpty()) { brokerAddr = map.get(brokerId); slave = brokerId != MixAll.MASTER_ID; found = brokerAddr != null; if (!found && !onlyThisBroker) { Entry<Long, String> entry = map.entrySet().iterator().next(); brokerAddr = entry.getValue(); slave = entry.getKey() != MixAll.MASTER_ID; found = true; } } if (found) { return new FindBrokerResult(brokerAddr, slave, findBrokerVersion(brokerName, brokerAddr)); } return null;}这里稍微解释下rocketmq的broker机制 :broker-amaster ip1 0slave1 ip2 1slave2 ip3 2一个broker—name 下面拥有若干个服务实例(一主二从),他们角色可能不同(master和slave),但是他们对于同一个brokername拥有唯一的id(0,1,2)。所以我们上面想讲的是对于broker-a这个拓扑结构而言,如果从上面拉消息,会选哪个ip的服务器去真实拉取。上面代码显示,选择的时候需要传入名字和id,这样其实已经在拓扑结构中唯一确定一台机器了。但是凡事有意外,比如,你选的这台机器刚好宕机了,怎么办?宕机后,因为consumer是发心跳的,所以本地服务会清除掉原来机器的信息,于是找不到了。代码中的做法是,从剩下的选一个,考虑到map无序,所以当做随机好了。这样子,只要这个拓扑结构还有一台存活,就一定能够返回一个ip地址供consumer连接。所以这个传入的brokerid很重要,正常情况下应该都是0,即master。到从的时候应该都是大于0的值,这样就是slave了。ok,我们看下这个传入的brokerid怎么确定的?public long recalculatePullFromWhichNode(final MessageQueue mq) { if (this.isConnectBrokerByUser()) { return this.defaultBrokerId; } AtomicLong suggest = this.pullFromWhichNodeTable.get(mq); if (suggest != null) { return suggest.get(); } return MixAll.MASTER_ID;}1.是否设置ConnectBrokerByUser,默认是false,对应的defaultBrokerId是0,即master2.本地缓存中是否存有suggest,有就直接返回3.直接返回master,即0演练一下:consumer启动,发现没有设置,缓存也没有,于是返回master的brokerid,然后从地址缓存中找到了ip,顺利拉到了消息,再更新本地的suggest缓存。然后下一次,再步骤2中返回上一次设置的suggest值作为brokerid,继续流程。master开始宕机,然后consumer的地址缓存更新后,清除了master的地址信息。这时候触发了consumer从slave上面拉的效果,这就是消费从master切换到slave的过程。那什么时候master恢复后,slave怎么切回去呢?一开始我是有疑问的,因为我以为切到slave后,salve的brokerid会写入到suggest里面,然而并没有。slave的borkerid写入到suggest缓存的话,即使master恢复后,因为slave并没有消失,所以不会触发重选过程,自然切不到master上面。重点来了,这个suggest其实是broker端返回的。什么意思呢?我即使是从slave中拉取数据,但是slave 的broker端在返回值中携带了一个suggest的值,这个值是0.这就是说slave还是建议你下次拉去优先从master中拉取,即使master已经宕机了,还是从优先选master,这个suggest是由服务器决定的,不是consumer客户端。所以最后的问题是,broker代码逻辑中,什么时候返回0(master),什么时候返回非0(slave).大部分时候,是返回0的,即master。几个过程会返回非0 :1.master消息堆积太严重,会返回一个预先设置好的slave brokerid,默认值是1,所以brokerid不要乱设置,容易出事。2.问题二:master宕机会引发负载均衡服务的变化吗?猜测:首先生产者肯定是受影响的,因为不能写了。消费者应该是不受影响的,因为slave能读。未完待续~
阅读全文
0 0
- ROCKETMQ 主从切换机制
- rocketMQ主从问题
- redis主从同步配置和哨兵机制监控master主从切换配置
- redis主从同步配置和哨兵机制监控master主从切换配置
- mysql主从备份切换
- Mysql+keepalived主从切换
- mysql主从数据库切换
- mysql主从切换步骤
- mysql主从切换
- mysql主从切换
- MYSQL主从切换
- mysql 主从服务器 切换
- mysql 主从切换
- mysql 主从切换
- MySQL主从切换步骤。
- redis主从切换
- Jedis主从切换实现
- redis 主从切换
- 鱼眼图像校正(球面等距投影模型)_||
- 一些关于javascript闭包和this的理解
- HTTP 接口设计指北
- sql查重复语句
- C与C++的区别(上)
- ROCKETMQ 主从切换机制
- 逻辑查询处理阶段简介
- ACM-ICPC 2017 Asia QingDao:喜,抑或是悲?幸运,抑或是倒霉?退役!!!
- spring in action笔记(三)——配置bean
- C和指针之函数之实现阶乘和斐波那契数(递归和非递归)
- 初识Spring_03
- C# Field笔记
- VMware 虚拟机安装 Ubuntu 简单教程
- 用户的访问权限过滤器,防止用户直接输入URL直接访问资源。