史上最全RocketMq面试大全之RocketMq高级功能01 骑猪看日落 2022-09-03 00:25 165阅读 0赞 ### 文章目录 ### * 1. RocketMq消息存储 * * 1.1 存储介质 * 1.2 消息的存储和发送 * * 1.2.1 消息存储 * 1.2.2 消息发送 * 1.3 消息存储结构 * 1.4 刷盘机制 * * 1) 同步刷盘 * 2) 异步刷盘 * 3) 配置 * 2. 高可用性机制 * * 2.1 消息消费高可用 * 2.2 消息发送高可用 * 2.3 消息主从复制 * * 1) 同步复制 * 2) 异步复制 * 3) 配置 * 4) 总结 -------------------- # 1. RocketMq消息存储 # 分布式队列因为有高可靠性的要求 所以数据要进行持久化存储. ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70] 1. 消息生产者发送消息 2. MQ收到消息, 将消息进行持久化, 在存储中新增一条记录. 3. MQ的Broker集群反馈ACK给生产者 4. MQ push消息给对应的消费者, 然后等待消费者返回ACK. 5. 如果消息消费者在指定时间内成功返回ACK, 那么MQ认为消息消费成功, 在存储中删除消息, 即执行第6步; 如果MQ在指定时间内没有收到ACK, 则认为消息消费失败, 会尝试重新push消息, 重复执行4,5,6步骤. 6. MQ删除消息 ## 1.1 存储介质 ## * 关系型数据库DB Apache下开源的另外一款MQ—ActiveMQ(默认采用的KahaDB做消息存储)可选用JDBC的方式来做消息持久化,通过简单的xml配置信息即可实现JDBC消息存储。由于,普通关系型数据库(如Mysql)在单表数据量达到千万级别的情况下,其IO读写性能往往会出现瓶颈。在可靠性方面,该种方案非常依赖DB,如果一旦DB出现故障,则MQ的消息就无法落盘存储会导致线上故障 * 文件系统 目前业界较为常用的几款产品(RocketMQ/Kafka/RabbitMQ)均采用的是消息刷盘至所部署虚拟机/物理机的文件系统来做持久化(刷盘一般可以分为异步刷盘和同步刷盘两种模式)。消息刷盘为消息存储提供了一种高效率、高可靠性和高性能的数据持久化方式。除非部署MQ机器本身或是本地磁盘挂了,否则一般是不会出现无法持久化的故障问题。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 1] 性能方面, 文件磁盘系统的性能>关系型数据库DB ## 1.2 消息的存储和发送 ## ### 1.2.1 消息存储 ### 磁盘如果使用得当,磁盘的速度完全可以匹配上网络的数据传输速度。 * 目前的高性能磁盘,顺序写速度可以达到600MB/s, 超过了一般网卡的传输速度。 * 但是磁盘随机写的速度只有大概100KB/s,和顺序写的性能相差6000倍!因为有如此巨大的速度差别. * 好的消息队列系统会比普通的消息队列系统速度快多个数量级, **RocketMQ的消息用顺序写,保证了消息存储的速度**。 ### 1.2.2 消息发送 ### Linux操作系统分为**用户态**和**内核态**, 文件操作, 网络操作需要涉及这两种形态的切换, 免不了进行数据复制. 一台服务器 把本机磁盘文件的内容发送到客户端,一般分为两个步骤: 1)read;读取本地文件内容; 2)write;将读取的内容通过网络发送出去。 这两个看似简单的操作,实际进行了4 次数据复制,分别是: 1. 从磁盘复制数据到内核态内存; 2. 从内核态内存复 制到用户态内存; 3. 然后从用户态内存复制到网络驱动的内核态内存; 4. 最后是从网络驱动的内核态内存复制到网卡中进行传输。 ![在这里插入图片描述][3be8e75c14434b6cbbe2c83d075797eb.png] 上述方式也叫mmap的方式, 可以省去向用户态的内存复制,提高速度。这种机制在Java中是通过MappedByteBuffer实现的. RocketMQ充分利用了上述特性,也就是所谓的“零拷贝”技术,提高消息存盘和网络发送的速度。 这里需要注意的是,采用MappedByteBuffer这种内存映射的方式有几个限制,其中之一是一次只能映射1.5~2G 的文件至用户态的虚拟内存,这也是为何RocketMQ默认设置单个CommitLog日志数据文件为1G的原因了 ## 1.3 消息存储结构 ## RocketMQ消息的存储是由ConsumeQueue和CommitLog配合完成 的,消息真正的物理存储文件是CommitLog,ConsumeQueue是消息的逻辑队列,类似数据库的索引文件,存储的是指向物理存储的地址。每 个Topic下的每个Message Queue都有一个对应的ConsumeQueue文件。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 2] * CommitLog:存储消息的元数据 * ConsumerQueue:存储消息在CommitLog的索引 * IndexFile:为了消息查询提供了一种通过key或时间区间来查询消息的方法,这种通过IndexFile来查找消息的方法不影响发送与消费消息的主流程 ## 1.4 刷盘机制 ## RocketMQ的消息是存储到磁盘上的,这样既能保证断电后恢复, 又可以让存储的消息量超出内存的限制。RocketMQ为了提高性能,会尽可能地保证磁盘的顺序写。消息在通过Producer写入RocketMQ的时 候,有两种写磁盘方式,分布式同步刷盘和异步刷盘。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 3] ### 1) 同步刷盘 ### 在返回写成功状态时,消息已经被写入磁盘。具体流程是,消息写入内存的PAGECACHE后,立刻通知刷盘线程刷盘, 然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写 成功的状态。 ### 2) 异步刷盘 ### 在返回写成功状态时,消息可能只是被写入了内存的PAGECACHE,写操作的返回快,吞吐量大;当内存里的消息量积累到一定程度时,统一触发写磁盘动作,快速写入。 ### 3) 配置 ### **同步刷盘还是异步刷盘,都是通过Broker配置文件里的flushDiskType 参数设置的,这个参数被配置成SYNC\_FLUSH、ASYNC\_FLUSH中的 一个。** # 2. 高可用性机制 # ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 4] RocketMQ分布式集群是通过Master和Slave的配合达到高可用性的。 Master和Slave的区别:在Broker的配置文件中,参数 brokerId的值为0表明这个Broker是Master,大于0表明这个Broker是 Slave,同时brokerRole参数也会说明这个Broker是Master还是Slave。 Master角色的Broker支持读和写,Slave角色的Broker仅支持读,也就是 Producer只能和Master角色的Broker连接写入消息;Consumer可以连接 Master角色的Broker,也可以连接Slave角色的Broker来读取消息。 ## 2.1 消息消费高可用 ## 在Consumer的配置文件中,并不需要设置是从Master读还是从Slave 读,当Master不可用或者繁忙的时候,Consumer会被自动切换到从Slave 读。有了自动切换Consumer这种机制,当一个Master角色的机器出现故障后,Consumer仍然可以从Slave读取消息,不影响Consumer程序。这就达到了消费端的高可用性。 ## 2.2 消息发送高可用 ## 在创建Topic的时候,把Topic的多个Message Queue创建在多个Broker组上(相同Broker名称,不同 brokerId的机器组成一个Broker组),这样当一个Broker组的Master不可 用后,其他组的Master仍然可用,Producer仍然可以发送消息。 RocketMQ目前还不支持把Slave自动转成Master,如果机器资源不足, 需要把Slave转成Master,则要手动停止Slave角色的Broker,更改配置文 件,用新的配置文件启动Broker。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 5] ## 2.3 消息主从复制 ## 如果一个Broker组有Master和Slave,消息需要从Master复制到Slave 上,有同步和异步两种复制方式。 ### 1) 同步复制 ### 同步复制方式是等Master和Slave均写 成功后才反馈给客户端写成功状态; 在同步复制方式下,如果Master出故障, Slave上有全部的备份数据,容易恢复,但是同步复制会增大数据写入 延迟,降低系统吞吐量。 ### 2) 异步复制 ### 异步复制方式是只要Master写成功 即可反馈给客户端写成功状态。 在异步复制方式下,系统拥有较低的延迟和较高的吞吐量,但是如果Master出了故障,有些数据因为没有被写 入Slave,有可能会丢失; ### 3) 配置 ### 同步复制和异步复制是通过Broker配置文件里的brokerRole参数进行设置的,这个参数可以被设置成ASYNC\_MASTER、 SYNC\_MASTER、SLAVE三个值中的一个。 ### 4) 总结 ### ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 6] 实际应用中要结合业务场景,合理设置刷盘方式和主从复制方式, 尤其是SYNC\_FLUSH方式,由于频繁地触发磁盘写动作,会明显降低 性能。通常情况下,应该把Master和Save配置成ASYNC\_FLUSH的刷盘 方式,主从之间配置成SYNC\_MASTER的复制方式,这样即使有一台 机器出故障,仍然能保证数据不丢,是个不错的选择。 [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70]: /images/20220829/82c1c9454fbe4ad8b1d863968fb099f5.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 1]: /images/20220829/cf9e354e23a0421aaebb4db983cd9d68.png [3be8e75c14434b6cbbe2c83d075797eb.png]: /images/20220829/71e3440c487e4cf1b511286d4e13bde7.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 2]: /images/20220829/f76700f3f0154139b6ae8b79464b0430.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 3]: /images/20220829/533c17d5118d4943818042c8290cfea3.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 4]: /images/20220829/f05da4fead13461097e4b87fb5a3ea2d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 5]: /images/20220829/0052a672190849c6a469489e45f1d674.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjY0MTkwOQ_size_16_color_FFFFFF_t_70 6]: /images/20220829/7f7fd247e0bb4b4dadbec4b63baa4b01.png
还没有评论,来说两句吧...