【深入浅出 RocketMQ原理及实战】「底层源码挖掘系列」透彻剖析贯穿一下RocketMQ和Kafka索引设计原理和方案

简介: 【深入浅出 RocketMQ原理及实战】「底层源码挖掘系列」透彻剖析贯穿一下RocketMQ和Kafka索引设计原理和方案

背景介绍

文件索引,是存储设计的关键,一个好的索引,应该能够在最短的时间里,找到你想要的数据,同时,还能尽量少的使用内存或磁盘空间。

但是这里说的索引并不是指MySQL或者NoSQL这些数据库索引,而是MQ中间件的索引。相对而言较为简单的MQ索引。我们可以通过研究MQ的索引,看看他们为何如此设计,我们又有哪些借鉴之处,并且也可以根据他们索引文件的设计模式,进行分析他们的性能问题,接下来我们借来分别说说RocketMQ和Kafka的索引设计原理,重点我们会介绍RocketMQ的设计。

RocketMQ

相比较Kafka的分区索引文件的设计方案,RocketMQ的数据文件属于混合存储,即,所有的topic数据都放在一个文件里,因此,读数据的时候,就无法做到连续读了,只能随机读。

所以,RocketMQ推荐使用大内存,利用PageCache 预读机制把commitlog数据缓存起来,混合存储的好处则是能够承受万级别的队列数量

kafka 64分区有些夸张,单机单磁盘1000分区还是没啥问题的,经验之谈最好别超过 2000,

RocketMQ 提供基于MsgID搜索消息的方案,即,每条消息,都有一个唯一的 ID,

Message ID

ID由broker IP + Port + CommitLog Offset 组成,通过这两个参数,可快速定位到一条消息。注意,Kafka是没有这个功能的,但理论上,通过 Kafka 的 offset 也是可以找到具体的消息的。

另外 RocketMQ 有 2 种索引。

  • 消息消费索引
  • Hash 查询索引

消息消费索引

消息消费索引,可以理解为,就是 topic 的索引数据,类似 kafka 的索引数据。如果没有这个,消费者基本就找不到消息了。这个索引里,存放着对应topic 、对应 queue 里的消息连续 offset 集合(不像 commitLog 是混合存储的)。



RocketMQ的存储层架构



RocketMQ 的运作流程图

RocketMQ 的存储设计图:

消息被不停的 append 到 commitlog,然后,再构建消费索引,如果没有这个索引,consumer 要在 commitlog 里消费消息,那可真是太难了。



每个consumerQueue文件里存放着 30w 个元素,每个元素 20 字节,8 字节 offset ,4 字节 size, 8 字节 tag hashcode,因此,每个文件也就 5.8MB 不到,很轻量。



Hash查询索引(我们可以称之为tag)

Hash查询索引,主要是根据 Key 来快速查询消息,属于一种附加功能。RocketMQ 采用了 Java HashMap 的思想,实现了 Hash 索引的存储。

  • 如果这个 Map 有 500w 个 slot,每个 slot 的链表长度为 4. 如果我们使用一个 key 进行消息查找,他的过程是这样的:先 hash key 得到 hashCode,然后对 500w 取余,找到槽位,这个槽位大小是4个字节,保存了链表尾部的具体元素地址。
  • 而这个链表元素的大小是 20 个字节,保存了 key 的 hash 值,commitlog offset,时间戳,还有他下一个链表节点的地址。
  • 为什么在 链表元素里保存 了 hash 值呢?为了防止 hash 值不同,但是 hash 取模后的结果相同(也就是 hash 冲突),如果冲突了,就用 hash 值比对一下。
  • 那如果 hash 值相同,key 内容不同呢?RocketMQ 的做法是放在客户端过滤。

简单介绍一下Kafka

Kafka 每个 topic 有多个 partition ,每个 partition 有多个 segment,每个 segment 里,存储了消息的相关文件:数据文件,索引文件。

Kafka 不像 RocketMQ,所有数据都存在一个文件里,Kafka 每个 topic 的文件都是隔离开的,而每个 topic 又可能会有很多的 partition(看你的配置),因此,如果你的topic非常多,或者你的partition非常多的话,顺序写就会变成随机写,性能会骤降。

Kafka 的索引文件和数据文件绑定在一起的。

与RocketMQ的消费索引类似,Kafka 里面是逻辑 offset 映射物理 offset ,并且采用了稀疏索引的方式。然后,我们看看他们的索引设计,如下图:

[逻辑索引,偏移量]

  • 逻辑索引,即这个 partition下的全局递增逻辑索引(当然,这个是相对偏移量,这里为了描述简单,就不区分了)
  • 偏移量,表示这条消息的所在文件的物理 position。

我现在是一个消费者,订阅了这个 partition 的消息,那么我将从 0 号逻辑索引开始订阅,从.index 开始遍历,然后找到对应的物理文件position。

kafka 的这个 .index 文件和 RocketMQ 的 consumerQueue 索引很相似,直接遍历 .log 文件,从头开始消费。但如果,我不想从头开始消费呢?我想从第 18 条消息开始消费呢?因为没有 .index ,我只能慢慢遍历。

一个 topic 设计一个递增的 offset,从 0 开始,每新增一条消息,加一。这是一个逻辑偏移量,我们让逻辑偏移量 映射 物理偏移量。消费者也从 0 开始消费,这样,就达到了某种默契。就算是第 18 条消息,我也能快速找到。

基于 partition 的分区原子计数器。使用 broker ID + 分区 ID + 计数器 就可以标识一条唯一的消息。然后,用计数器映射 偏移量 offset,简直就是完美。然后,为了达到搜索效率和空间消耗的平衡,边稠密索引为稀疏索引。

RocketMQ 和 Kafka 的索引设计相似之处:

RocketMQ 的 topic 和 kafka 的 topic 类似,RocketMQ 的 queue 和 kafka 的 partition 类似,都是为了 scale out。

  • RocketMQ 为每个 queue 设计了 consumerQueue 索引文件,每个文件大小固定 5.8MB;
  • Kafka 为每个 partition 设计了 segment (.index + .log)。

consumerQueue 索引文件和 segment 的 .index 本质是一样的,都是为了让 consumer 快速找到消息。

和 Kafka 的索引设计的最大不同

RocketMQ 是所有 topic 混合存储,目的是支持更多的topic,而 Kafka 的topic 是单独存储,好处是顺序读性能好,另外,根据分区做副本也比较好做。

相关文章
|
3月前
|
消息中间件 Java Kafka
Java 事件驱动架构设计实战与 Kafka 生态系统组件实操全流程指南
本指南详解Java事件驱动架构与Kafka生态实操,涵盖环境搭建、事件模型定义、生产者与消费者实现、事件测试及高级特性,助你快速构建高可扩展分布式系统。
223 7
|
6月前
|
消息中间件 运维 Kafka
直播预告|Kafka+Flink双引擎实战:手把手带你搭建分布式实时分析平台!
在数字化转型中,企业亟需从海量数据中快速提取价值并转化为业务增长动力。5月15日19:00-21:00,阿里云三位技术专家将讲解Kafka与Flink的强强联合方案,帮助企业零门槛构建分布式实时分析平台。此组合广泛应用于实时风控、用户行为追踪等场景,具备高吞吐、弹性扩缩容及亚秒级响应优势。直播适合初学者、开发者和数据工程师,参与还有机会领取定制好礼!扫描海报二维码或点击链接预约直播:[https://developer.aliyun.com/live/255088](https://developer.aliyun.com/live/255088)
477 35
直播预告|Kafka+Flink双引擎实战:手把手带你搭建分布式实时分析平台!
|
6月前
|
消息中间件 运维 Kafka
直播预告|Kafka+Flink 双引擎实战:手把手带你搭建分布式实时分析平台!
直播预告|Kafka+Flink 双引擎实战:手把手带你搭建分布式实时分析平台!
214 12
|
7月前
|
消息中间件 搜索推荐 调度
RocketMQ实战—8.营销系统业务和方案介绍
本文详细介绍了电商营销系统的业务流程、技术架构及挑战解决方案。涵盖核心交易与支付后履约流程,优惠券和促销活动的发券、领券、用券、销券机制,以及会员与推送的数据库设计。技术架构基于Nacos服务注册中心、Dubbo RPC框架、RocketMQ消息中间件和XXLJob分布式调度工具,实现系统间高效通信与任务管理。针对千万级用户量下的推送和发券场景,提出异步化、分片处理与惰性发券等优化方案,解决高并发压力。同时,通过RocketMQ实现系统解耦,提升扩展性,并利用XXLJob完成爆款商品推荐的分布式调度推送。整体设计确保系统在大规模用户场景下的性能与稳定性。
RocketMQ实战—8.营销系统业务和方案介绍
|
6月前
|
消息中间件 架构师 Java
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
|
消息中间件 数据挖掘 Kafka
Apache Kafka流处理实战:构建实时数据分析应用
【10月更文挑战第24天】在当今这个数据爆炸的时代,能够快速准确地处理实时数据变得尤为重要。无论是金融交易监控、网络行为分析还是物联网设备的数据收集,实时数据处理技术都是不可或缺的一部分。Apache Kafka作为一款高性能的消息队列系统,不仅支持传统的消息传递模式,还提供了强大的流处理能力,能够帮助开发者构建高效、可扩展的实时数据分析应用。
649 5
|
7月前
|
消息中间件 存储 Kafka
RocketMQ实战—4.消息零丢失的方案
本文分析了用户支付完成后未收到红包的问题,深入探讨了RocketMQ事务消息机制的实现原理及其在确保消息零丢失中的作用。首先,通过全链路分析发现消息可能在推送、存储或消费环节丢失。接着,介绍了RocketMQ事务消息机制如何通过half消息、本地事务执行及回调确认来保证消息发送成功,并详细解析了其底层原理,如half消息对消费者不可见、rollback与commit操作等。同时,对比了同步重试方案,指出其在复杂场景下的局限性。
RocketMQ实战—4.消息零丢失的方案
|
10月前
|
消息中间件 运维 Java
招行面试:RocketMQ、Kafka、RabbitMQ,如何选型?
45岁资深架构师尼恩针对一线互联网企业面试题,特别是招商银行的高阶Java后端面试题,进行了系统化梳理。本文重点讲解如何根据应用场景选择合适的消息中间件(如RabbitMQ、RocketMQ和Kafka),并对比三者的性能、功能、可靠性和运维复杂度,帮助求职者在面试中充分展示技术实力,实现“offer直提”。此外,尼恩还提供了《尼恩Java面试宝典PDF》等资源,助力求职者提升架构、设计、开发水平,应对高并发、分布式系统的挑战。更多内容及技术圣经系列PDF,请关注【技术自由圈】获取。
|
12月前
|
消息中间件 大数据 Kafka
大厂面试高频:Kafka、RocketMQ、RabbitMQ 的优劣势比较
本文深入探讨了消息队列的核心概念、应用场景及Kafka、RocketMQ、RabbitMQ的优劣势比较,大厂面试高频,必知必会,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:Kafka、RocketMQ、RabbitMQ 的优劣势比较