-
RocketMQ
一、RocketMQ集群
RocketMQ集群由于无法选主,所以当Master挂了以后,slave需要手动切换master。这一点不好
二、RocketMQ为什采用NameSr,而不是zk
ZK是CP,NameSr是AP。RocketMQ选择了高可用。
RocketMQ的集群思想与Kafka有很大区别,在Kafka中borker这个概念分为Master和slave,可以通过zk选主进行切换和高可用。RocketMQ中Master对应的Borker 和 slave对应的borker是搭建环境的时候指定好的,他不需要选举。从这里可以看出Kafka的核心思想是通过主从切换保证集群的高可用。而RocketMQ是通过故障转移保证集群的高可用。例如:当RocketMQ中某个masterBorker挂了,那本来该发送到这个borker中对应队列的消息,此时将会被发送到其他Master上(对于普通消息)。
三、RocketMQ的顺序消息
全局顺序:就是我希望所有的消息你都给我按序消费,对应这样的消息我们可以创建topic时只分配一个队列。这样就失去了高可用的,高吞吐量的效果。
局部顺序:这类顺序消息很常见,我们就是根据一定的算法将同类型的消息路由到同一个队列中。发送消息,要实现 MessageQueueSelector 该接口,重写select()方法,按照自己的算法将相同类别的消息发送大同一个Queue中。
消费端处理:
Producer
Consumer:
- 普通消息:该类型消息的重试,会触发故障转移,就是当第一次发送消息失败,重试发送会换一个borker。
- 顺序消息:该类型消息重试,不会触发故障转移,就是一直往同一个borker上发送。
生产者:
Conusmer:
brocker存储消息:
六、如何保证消息的最终一致性
事务消息
Producer Group:
七、Broker是怎么保存数据的
RocketMQ主要的存储文件包括commitlog文件、consumequeue文件、indexfile文件。
Broker在收到消息之后,会把消息保存到commitlog的文件当中,而同时在分布式的存储当中,每个broker都会保存一部分topic的数据,同时,每个topic对应的messagequeue下都会生成consumequeue文件用于保存commitlog的物理位置偏移量offset,indexfile中会保存key和offset的对应关系。
ommitLog文件保存于${Rocket_Home}/store/commitlog目录中,从图中我们可以明显看出来文件名的偏移量,每个文件默认1G,写满后自动生成一个新的文件。
由于同一个topic的消息并不是连续的存储在commitlog中,消费者如果直接从commitlog获取消息效率非常低,所以通过consumequeue保存commitlog中消息的偏移量的物理地址,这样消费者在消费的时候先从consumequeue中根据偏移量定位到具体的commitlog物理文件,然后根据一定的规则(offset和文件大小取模)在commitlog中快速定位。
八、Master和Slave之间是怎么同步数据的呢?
而消息在master和slave之间的同步是根据raft协议来进行的:
- 在broker收到消息后,会被标记为uncommitted状态
- 然后会把消息发送给所有的slave
- slave在收到消息之后返回ack响应给master
- master在收到超过半数的ack之后,把消息标记为committed
- 发送committed消息给所有slave,slave也修改状态为committed
九、RocketMQ为什么速度快
是因为使用了顺序存储、Page Cache和异步刷盘。
我们在写入commitlog的时候是顺序写入的,这样比随机写入的性能就会提高很多
写入commitlog的时候并不是直接写入磁盘,而是先写入操作系统的PageCache
最后由操作系统异步将缓存中的数据刷到磁盘