1.Broker高可用架构原理
producer写入消息到broker之后,broker会将消息写入本地CommitLog磁盘文件里去,然后还有一些ConsumeQueue会存储Topic下各个MessageQueue的消息的物理位置。
高可用架构中,必须有一个Broker组,里面有一个是Leader Broker可以写入数据,然后让Leader Broker可以写入数据,然后让Leader Broker接收到数据之后,直接把数据同步给其他的Follower Broker。
这样的话,一条数据就会在三个Broker中有三个副本,如果Leader Broker宕机了,那么就让其中一个Follower Broker切换为Leader Broker,继续接收客户端的数据写入就可以了。
2.基于DLedger技术实现CommitLog持久化
基于DLedger技术实现CommitLog机制。
基于DLedger技术来实现Broker高可用架构,实际上就是用DLedger先替换掉原来Broker自己管理的CommitLog,由DLedger来管理CommitLog。
实现原来:
该机制,首先使用DLedger来管理CommitLog,然后Broker还是可以基于DLedger管理的CommitLog去构建出来机器上的各个ConsumeQueue磁盘文件。
3.DLedger基于Raft协议选举Leader Broker的原理
Leader Broker选举
简单来说,DLedger是基于Raft协议来进行Leader Broker选举的。
Raft协议选举场景说明原理
当前场景中,有3台机器进行选举,这一选举过程,三台Broker机器启动的时候,他们都会投票自己作为Leader,然后把这个投票发送给其他Broker。
第一轮选举:
此时,Broker01是投票给自己的,Broker02是投票给自己的,Broker03是投票给自己的,他们都把自己的投票发送给了别人。
在这第一轮选举中,Broker01会受到别人的投票,他发现自己是投票给自己,但是Broker02投票给Broker02自己,Broker03投票给Broker03自己,此时各自持有一票,第一轮选举失败。
随机休眠:
接着每个人会进入一个随机事件的休眠,比如说Broker01休眠3秒,Broker02休眠5秒,Broker03休眠4秒。
第二轮选举:
Broker01先苏醒过来,它苏醒过来后,会先尝试投票给自己,并且发送自己的选票给别人。
接着Broker03休眠4秒后苏醒过来,他发现Broker01已经发送来了一个选票是投给Broker01自己的,此时他自己因为没有投票,所以就直接把票投给Broker01了,同时把自己的投票发送给别人。
接着Broker02苏醒了,他收到了Broker01投票给Broker01自己,收到了Broker03也投票给了Broker01,那么他此时自己是没投票的,直接就会尊重别人的选择,直接就投票给Broker01,并且把自己的投票发送给别人。
票数汇总出结果:
最后,所有人都会收到三张选票,都是投给Broker01的,那么Broker01就会当选为Leader。
多数通过选票条件
在选举中,只要有(3台机器 / 2)+ 1个人投票给某个人,就会选举它当Leader,这个(机器数量/2)+1 就是大多数的意思。
简单来说,就是票数过半的那台机器被成功选举为Leader Broker。
总结:Raft协议中选举leader算法的核心机制是,一轮选举不出来Leader的话,就让大家随机休眠一下,先苏醒过来的人会投票给自己,其他人苏醒后发现自己收到选票了,就会直接投票给那个人。依靠这个随机休眠的机制,基本上几轮投票过后,一般都是可以快速选举出来一个Leader。
4. DLedger基于Raft协议进行多副本同步的原理
Raft协议中的多副本同步机制
该机制中,数据同步分为两个阶段,一个是uncommited阶段,一个是commited阶段。
两阶段同步原理
首先Leader Broker上的DLedger收到一条数据之后,会标记为uncommited状态,然后他会通过自己的DLedgerServer组件把这个uncommited数据发送给Follower Broker的DLedgerServer。
接着Follower Broker的DLedgerServer收到uncommitted消息之后,必须返回一个ack给Leader Broker的DLedgerServer,然后如果Leader Broker收到超过半数的Follower Broker返回ack之后,就会将消息标记为commited状态。
然后Leader Broker上的DLedgerServer就会发送committed消息给Follower Broker机器的DLedgerServer,让他们也把消息标记为committed状态。
返回生产者commit
必须要超过一半的Follower Broker的DLedger对uncommitted消息返回ack,此时Leader Broker才能返回ACK给生产者,说明这次写入成功了。
以上,就是基于Raft协议实现的两阶段完成的数据同步机制。
5.基于Raft协议的数据同步场景对Leader Broker的写入性能的影响?以及各个场景是否适用?
答1:原来是写broker的commitLog就会返回,现在是还要通知followers进行存储,等到过半返回ack才会返回给生产者写入成功。这样的操作严重影响了TPS。
答2:日志之类的统计信息可以容忍消息的丢失,不需要过半才成功。但,如果是支付业务这种场景,就需要保证消息的0丢失。
6.如果Leader Broker崩溃了怎么办?
如果Leader Broker挂了,此时剩下的两个Follower Broker就会重新发起选举,他们会基于DLedger机制采用Raft协议的算法,去选举出来一个新的Leader Broker继续对外提供服务,而且会对没有完成的数据同步进行一些恢复性的操作,保证数据不会丢失。
7. 扩展:
(1)DLedger管理的那个commitLog就是Broker的commitLog;
(2)多个Slave Broker进行选举时,committed index靠后的优先选举为Leader Broker,因为数据最完整;
(3)如果leader消息标记为committed状态,没来得及通知follower就挂了。那么,新选举的时候,检查到多数节点都有这个uncommitted消息,就会把这个消息编程已提交状态,这样选举出来leader,下次同步时候就会把这条数据同步给新加入集群的broker。