Kafka和RocketMQ存储模型对比

Kafka和RocketMQ存储模型对比

文章目录

Kafka存储模型:以Partition为中心

物理结构 Topic -> Partition -> Segmet

  • Kafka的数据按照Topic分类;
  • 每个Topic被切分为多个Partition(分区数量尽量不要变动),每个Partition分区在物理磁盘对应一个文件夹;
  • 每个Partition分区文件夹下包含多个Segment段文件(日志文件.log、索引文件.index、时间索引文件.timeindex),按照1G或7天进行切分
markdown 复制代码
/kafak_logs/
├── my_topic_0 #分区0对应的文件夹
    ├── 00000000000000000000.log
    ├── 00000000000000000000.index
    ├── 00000000000000000000.timeindex
    ├── 00000000000000000005.log   #对应offset、size、body
    ├── 00000000000000000005.index    
    ├── 00000000000000000005.timeindex  
├── my_topic_1 #分区1对应的文件夹
    ├── 00000000000000000000.log
    ├── 00000000000000000000.index
    ├── 00000000000000000000.timeindex
    ├── 00000000000000000005.log
    ├── 00000000000000000005.index    
    ├── 00000000000000000005.timeindex  
├── ...    

IO特征

  • 局部顺序写:在一个Partition分区内部,写入是安全顺序的
  • 全局随机写:如果一个 Kafka 集群中有成百上千个 Topic,每个 Topic 又有多个 Partition,磁盘磁头需要在不同的 Partition 文件夹之间频繁跳跃。这会导致宏观上的随机 I/O,这也是Topic越多多会导致Kafka性能下降的原因

索引机制

  • 稀疏索引:Kafa的.index文件不会为每条消息建立索引,而是每个一定字节比如4K建立一条索引,查找时先二分查找找到最近的索引点,然后顺序扫描 .log 文件。

RocketMQ存储模型:以CommitLog为中心

物理结构:RocketMQ采用了分离式的存储设计,主要由三部分组成

  • **CommitLog消息主体:**所有的Topic消息,全部顺序写入同一个CommitLog文件中
  • **ConsumeQueue逻辑队列:**每个Topic的每个Queue对应一个ConsumeQueue,只存储消息的在CommitLog中的偏移量Offset、消息长度Size、标签Tag Hash
  • Index消息索引: 支持按照Key或时间进行快速查询消息
markdown 复制代码
/RokcetMQ_HOME/
├── commitLog 
    ├── 00000000000000000000 #每个文件大小1G/ 结构化的格式存储的消息体
    ├── 00000000010300000000
    ├── 00000000021400000000
    ├── 00000000033200000005
    ├── ...
├── consumeQueue
    ├── Topic1
        ├── 0
    				├── 00000000000000000000  #CommitLog的偏移量、消息长度、TagHashCode
    				├── 00000000000066000000
    		├── 1
    				├── 00000000000000000000
    				├── 00000000000066000000  
├── index
		├── 1230000000000000000 #TODO
		├── 2110000000000000000

IO特征

  • 顺序写(全局的) :无论有多少个 Topic,写入操作永远是追加到 CommitLog 的末尾。这保证了绝对的顺序写,极大提高了写入性能,尤其是在 Topic 数量巨大的时候。
  • 随机读:消费者读取消息时,需要先查 ConsumeQueue 拿到位置,再去读 CommitLog。这看似是随机读,但 RocketMQ 通过 PageCache 预读和 Mmap 内存映射机制进行了优化

索引机制

  • 密集索引:ConsumeQueue 是定长的,每个消息都在里面有记录,可以通过下标定位到物理位置。

深度对比分析:核心差异点

特性 Kafka (Partition-Based) RocketMQ (CommitLog-Based)
写入方式 分区内顺序写,多分区导致磁盘随机写 全局顺序写,所有消息写入一个文件
Topic 数量影响 敏感。Topic/Partition 越多,磁盘随机 I/O 越严重,性能急剧下降。 不敏感。Topic 再多也只是写 CommitLog,性能几乎无衰减。
读取方式 直接读 Partition 文件,利用零拷贝 (sendfile) 效率极高。 先读 ConsumeQueue 再读 CommitLog,利用 Mmap
数据可靠性 依赖副本机制 (ISR),单机可靠性相对较弱。 支持同步刷盘/异步刷盘,同步双写/异步复制,单机可靠性高。
消息查询 只能按 Offset 消费,不支持按 Key 查询。 支持按 Offset、Message Key时间段查询。
过滤机制 客户端过滤 (主要是)。 服务端过滤 (Tag/SQL92),减少无效数据传输。

适用场景推荐

1. 什么时候选 Kafka?

  • 大数据日志采集:ELK stack,用户行为日志收集。
  • 流式计算管道:配合 Spark Streaming、Flink 进行实时数仓建设。
  • Topic 数量可控:业务场景不需要动态创建成千上万个 Topic。
  • 容忍少量丢失,追求极致吞吐:例如监控打点数据。

2. 什么时候选 RocketMQ?

  • 核心业务链路:订单、支付、交易、物流等金融级或电商级场景(阿里双11的核心)。
  • 微服务解耦:系统庞大,微服务众多,导致 Topic 数量非常多。
  • 需要复杂消息特性:需要使用分布式事务消息保持最终一致性,或者需要延时消息。
  • 消息查询需求:经常需要通过 OrderID 或 TransactionID 去查询消息轨迹进行排错。

总结

  • Kafka 是为了**"数据流"**而设计的,它不仅是队列,更是流存储平台。
  • RocketMQ 是为了**"业务"**而设计的,它更像是一个可靠的、高性能的分布式消息总线。
相关推荐
空中海24 分钟前
Kafka :存储、复制与可靠性
分布式·kafka·linq
渣渣盟26 分钟前
构建企业级实时数据管道:Kafka + Flink 最佳实践
分布式·flink·kafka
KmSH8umpK1 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第四篇
数据库·redis·分布式
KmSH8umpK2 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第五篇
数据库·redis·分布式
卧室小白3 小时前
ceph-分布式存储
分布式
aXin_ya3 小时前
微服务第九天 分布式缓存(Redis)
分布式·缓存·微服务
空中海3 小时前
Spring Boot Kafka 项目 Demo:订单事件系统 专家知识、源码阅读路线与面试题
spring boot·kafka·linq
空中海4 小时前
Kafka 基础:从消息队列到事件流平台
分布式·kafka·linq
空中海6 小时前
Kafka Streams、Connect 与生态
分布式·kafka·linq
KmSH8umpK20 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第三篇
redis·分布式·wpf