Broker是 RocketMQ 的核心,大部分‘重量级”工作都是由 Broker完成的, 包括接收 Producer 发过来的消息、处理 Consumer 的消费消息请求、消息的持 久化存储、消息的 HA 机制以及服务端过滤功能等 。
消息存储和发送
保证消息的可靠性就必须要对消息通过磁盘进行持久化存储,磁盘对读写速度并没有我们想象的那么慢,目前的高性能磁盘,顺序写速度可以达到 600MB/s,超过了一般网卡的传输速 度,这是磁盘比想象的快的地方 。 但是磁盘随机写的速度只有大概 l00KB/s, 和顺序写的性能相差 6000倍。
一台服务器把本机磁 盘文件的内容发送到客户端 一般分为两个步骤:
tmp_buf是预先申请的内存,这两个看似简单的操作,实际进行了 4次数据复制,分别是:从磁盘复制数据到内核态内存,从内核态内存复制到用户 态内存(完成了 read(file, tmp_b叫 len));然后从用户态内存复制到网络驱动 的内核态内存,最后是从网络驱动的内核态内存复制到网卡中进行传输(完成 write(socket, tmp_buf, len))。通过使用 mmap (将一个文件或者其它对象映射进内存)的方式,可以省去向用户态的内存复制,提高速度 。RocketMQ 充分利用了上述特性,也就是所谓的“零拷贝”技术,提高消息存 盘和网络发送的速度 。
消息存储结构
RocketMQ消息的存储是由ConsumeQueue和CommitLog配合完成的, 消息真正的物理存储文件是 CommitLog, ConsumeQueue 是消息的逻辑队 列,类似数据库的索引文件,存储的是指向物理存储的地址 。 每个 Topic 下 的每个 Message Queue都有一个对应的 ConsumeQueue 文件 。 文件地址在 ${$storeRoot}\consumequeue${topicName}${queueld}${fileName}。
CommitLog 以物理文件的方式存放,每台 Broker上的 CommitLog被本 机器所有 ConsumeQueue 共 享,文 件地址:$ {user.home} \store${commitlog}\ ${白leName}。 在 CommitLog 中,一个消息的存储长度是不固定的, RocketMQ 采取一些机制,尽量 向 CommitLog 中顺序写 ,但是随机读 。 ConsumeQueue 的 内容也会被写到磁盘里作持久存储 。
存储机制这样设计有以下几个好处:
同步刷盘和异步刷盘
之前我们介绍Broker 配置文件里的 flushDiskType 参数 设置的,这个参数被配置成 SYNC_FLUSH、 ASYNC_FLUSH 中的一个。
异步刷盘方式:在返回写成功状态时 ,消息可 能只是被写人了内存的 PAGECACHE ,写操作的返回快,吞吐 量大 ;当内存里的消息 量 积累到 一定程度时 ,统一触发 写磁盘动 作,快速 写入 。
同步刷盘方式:在返回写成功状态时,消息已经被写人磁盘 。 具体流程 是,消息、写入内存的 PAGECACHE 后,立刻通知刷盘线程刷盘,然后 等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功 的状态 。
同步复制和异步复制
Broker 配置文件里的 brokerRole 参数进行设置 的,这个参数可以被设置成 ASYNC_MASTER、 SYNC_MASTER、 SLAVE 三 个值中的一个 。
消息需要从 Master复制到 Slav巳 上,有同步和异步两种复制方式 。
同步复制方式是: 等 Master 和 Slave 均写成功 后才反馈给客户端写成功状态;
异步复制方式是:只要 Master 写成功即可反馈给 客户端写成功状态 。
实际应用中要结合业务场景,合理设置刷盘方式和主从复制方式,尤其是 SYNC_FLUSH 方式,由于频 繁 地触发磁盘 写动 作, 会明显 降低性能 。 通常情 况下,应该把 Master和 Save配置成 ASYNC_FLUSH 的刷盘方式,主从之间配 置成 SYNC_MASTER 的 复制方式,这 样即使有 一台机器出故障, 仍然能保证 数据不丢,是个不错的选择 。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_38003389/article/details/86678209
内容来源于网络,如有侵权,请联系作者删除!