元数据办理

1.1 topic、订阅组group、消费进度consumerOffset
1.2 多个装备文件config,毛病康复的存储Checkpoint和Filelock
1.3 记载主备备份Epoch/SN

元数据办理与优化

topic对应多个逻辑分区(Partition),称为行列(MessageQueue)

RocketMQ存储层原理
其间ConsumeOffset用于办理订阅组消费进度(如Map<String/* topicName@groupId */, Map<Integer /QueueId/, Long /Offset/>>)
RocketMQ选用守时任务对上面Map做checkPoint查看(查看周期5秒 – 所以当服务端主备切换或许正常发布时,都会有秒级的音讯重复)

音讯数据办理

存储中心是极致优化次序写盘(append only将新音讯追加文件末尾)。完成如下

  1. RocketMQ经过MappedByteBuffer完成 mmap 映射虚拟地址相关削减 数据区在缓存区来回仿制
    1.1 约束:mmap 文件不能太大(RocketMQ 1G,经过链表串联成逻辑行列 MappedFileQueue)
    RocketMQ存储层原理

单挑音讯存储格式

RocketMQ选用杂乱存储编码将目标序列化,并写入文件(存储格式包含索引行列编号、方位)

  1. 单音讯一般占用巨细 = 音讯元数据(91B+部分属性) + 音讯payload(>2k) > 2k
    RocketMQ存储层原理

多条音讯接连写

特性:次序写+写快点

RocketMQ存储层原理

独占锁完成次序写

怎样保证单机存储写commitLog次序性

  1. 加独占锁(目前选用ReentrantLock 或 SpinLock)
    1.1 ReentrantLock 或 SpinLock使用机遇
1. ReentrantLock底层AQS抢不到会休眠,而SpinLock抢不到会CPU忙等候
2. ReentrantLock适合**同步耐久化**,等候较久的。而SpinLock由于会一直抢占,适合等候加锁时刻段的**异步耐久化**
  1. 获取锁之后处理
    2.1 预核算索引的方位ConsumeQueueOffset(需保证严厉递加)
    2.2 核算commitLog存储方位,physicalOffset 物理偏移量,找到文件方位
    2.3 记载存储时刻戳,保证音讯投递时刻次序性
成组提交与可见性

大部分系统将操作日志缓存在内存中,然后满意 超越必定巨细或超越一守时刻 就会自动刷盘耐久化。但反常重启会丢掉部分数据
但音讯系统比较特别,针对金融场景下要求数据反常丢掉少、推迟低。RocketMQ可装备为单主异步耐久化(单master,并将数据同步到slave节点)

1. RoekctMQ单主异步耐久化存在的问题:宕机master会丢掉部分音讯,而且消费者或许已经收到音讯数据,
当这种形式宕机康复时会重放到某个节点,但只能读取新写入的音讯,读取不到之前消费过的音讯
2. 对应1处理方案:过半slave副本确认后RocketMQ音讯才可被消费者可见,但这样吞吐量会下降

耐久化机制

耐久化主要看机遇、同步仍是异步。RocketMQ供给三种形式

1. 同步耐久化(GroupCommitService)
2. 异步耐久化(FlushRealTimeService)
- 是否敞开TransientStorePool缓存
  1. 同步耐久化
    1.1 处理进程:写入线程将音讯转给存储线程,10ms查看一次将page cache数据刷入磁盘
    1.2 宕机或断电处理:未落盘数据不影响生产者(非oneway调用),发送者未收到成功呼应会重试
  2. 异步耐久化
    有两种形式 固定频率、非固定频率
    1.1 固定频率-处理进程:500ms(可装备)flush一次(不足16k则本次不处理,下次处理,超越10s直接履行flush)
    1.2 非固定频率-处理进程:新音讯过滤都会换新刷盘(数据量大的时候性能不好,适合数据量小)
    RocketMQ存储层原理
读写别离

RocketMQ可装备异步耐久化并敞开缓冲池(默许初始化 5 块(参数 transientStorePoolSize 决议)堆外内存(DirectByteBuffer)循环利用)
具体是敞开了缓存后。写入经过DirectByteBuffer,然后再异步批量写入page cache;读取经过page cache直接获取数据
缺点:数据可靠性下降,重启进程就或许会丢数据

RocketMQ存储层原理

宕机与毛病康复

磁盘没问题的话,MQ重启即可从commitLog、consumeQueue加到数据到内存,然后HA协商,再初始化netty server供给服务

避免存储颤动

快速失利

  1. 为什么要快速失利:音讯被服务端IO线程读取后进入堵塞行列中,但Broker节点会受GC、IO颤动等形成存储写失利,从而导致请求排队堆积,从而OOM
  2. 怎样处理:线程查看行列,剔除超越200ms音讯并立即给客户端返回失利呼应,然后客户端会重试在其他副本组
  3. 其他快速失利机制:写入超越一秒快速失利
    RocketMQ存储层原理

预分配与文件预热

RocketMQ需求保证commitLog写满之后快速切换到新的,所以会敞开线程异步创建新文件并内存确定(还有一个额定文件预热开关)
优点:文件预热生成,下降写IO。别的RocketMQ定位于事务级音讯这种小数据块/高频率的 IO 传输,选用更低的推迟 mmap 更适宜

冷数据读取

冷数据读取触及两种

  1. 副本数据转存仿制(第一种):在RocketMQ低版本,需求很多仿制commitLog情况下(备磁盘宕机或上线), 主用DMA仿制经过网络仿制给备机会形成很多缺页中止堵塞io线程,从而影响Netty处理新情求。 在完成上可以用第二个端口处理,但本质上没处理堵塞问题(只能从其他备仿制 或 madvice建议os读取避免影响主的音讯写入)
  2. 消费者消费几小时前数据(第二种):让备机分摊压力 或 从转存后的二级介质读取

索引数据办理

以下重温一下几个概念:

- MessageQueue: 音讯逻辑行列
-- MessageQueue = 多个接连 ConsumeQueue 索引 + CommitLog 文件
-- 仅保存一个topic分区索引(物理偏移量+音讯长度+tag hashcode    共20B巨细)
- ConsumeQueue: 音讯对应的物理索引文件
-- 多种存储策略可选并可混合存储

客户端pull请求拉取音讯流程

1. 依据 Tag 的 Hash 值查询 ConsumeQueue 文件(由 physicOffset + size + Tag HashCode 组成)
2. 依据 ConsumeQueue 拿到 physicOffset + size
3. 依据 physicOffset 查询 CommitLog 文件(上文的 MappedFileQueue ) 获得音讯

RocketMQ存储层原理

参阅链接:mp.weixin.qq.com/s/PzDO-UCLz…