Broker 其主要是负责存储消息和转发消息。是RocketMQ的核心,现在让我们介绍一下其核心功能部分。
消息存储在生产发送消息到Broker上面时,首先其会把消息按找顺序写入到磁盘的一个日志文件,叫做 CommintLog 。这个 CommintLog 由很多磁盘文件组成,每个文件限定1GB,如果一个写满了则会创建一个新的 CommintLog 文件。然后其就会把消息在 CommintLog 中的 offset 偏移量,消息长度、hashCode等数据存入到ConsumerQueue中(每个ConsumerQueue大概可以保存30w条数据,一条数据20个字节,文件大小大概为5.72M)。
但对于直接把消息顺序写入磁盘文件CommintLog中这显然会影响性能的,所以Broker是基于OS操作系统的 PageCache 、顺序写、OS异步刷盘策略机制来优化的。其接收到消息后会顺序写入到OS PageCache中,然后后续由OS的的一个后台线程间数据刷入到磁盘文件。
- 同步刷盘:生产者发送一条消息出去之后,Broker收到消息,必须强制把消息刷入到底层的物理磁盘中,才会返回 ack 给生产者。这时生产者才知道消息写入成功。这样可以避免数据的丢失,除非磁盘坏了。
- 异步刷盘:生产者发送一条消息出去之后,Broker收到消息,当其将消息写入到 OS PageCache 中就返回 ack 给生产者。这时生产者认为消息写入成功,但这时如果Broker宕机则会导致OS PageCache 中的数据丢失。
- 优缺点:同步刷盘(写入吞吐量下降 、数据不丢失),异步刷盘(高吞吐写入,有丢失数据的风险) 刷盘方式可以通过Broker配置文件里的flushDiskType参数设置,这个参数有两种值:SYNC_FLUSH (同步刷盘)。ASYNC_FLUSH (异步刷盘)。
为了保证Broker的高可用行,我们可用通过搭建其主从模式,Broke主从主要是基于DLedge来实现的其主要思想如下:
DLedger 实际上是他自己有一个ComminLog机制,你把数据给他他会写入CommintLog磁盘文件里面去。基于DLedger技术来实现Broker的高可用架构,实际上就是用DLedger替换掉Broker管理的CommintLog由DLedger来管理。
- DLedger 基于Raft协议选举Leader Broker 流程
Leader Broker 选举流程在 Broker 启动的时候会发起投票只有当票数大于(机器数 + 1)/ 2时,这个Broker才会被选举为Leader Broker节点。 如果每个人的票数都相同,或者都没超过(机器数 + 1)/ 2时这时会认为选举失败,这时每个Broker 都会随机休眠一段时间,先醒来的人会投票给自己,其他人苏醒的人发现自己收到选举票这时就会直接提交给那个人
- DLedger 基于 Raft 协议进行多副本数据同步
Leader Broker 数据同步分为两阶段:uncomintted 阶段、comintted 阶段。首先Leader Broker 上的DLedger收到一条数据之后,其会标记为 uncominttd 状态,任何通过DLedger Server 组件把uncomintted 发送给Follower Broker 的DLedger Server,但其接收到消息之后会返回一个ack给Leader Server,当Leader Server 接收到超过半数的Follower Broker 返回的ack之后,将会把消息标致为comintted 状态,同时也通知 Follower Broker 把消息状态改为comitted状态



