kafka与RocketMQ的不同

1:kafka 与rocketMQ的零拷贝

kafka 在使用时更偏向sendFile方式, sendfile只能用来搬运数据,不能对数据进行操作。整个过程在内核态完成,不经过用户态。

rocketMq使用时更偏向Mmap方式。通过内存映射的方式,用户态通过虚拟地址,可以直接读取修改内核态数据。

kafka 与rocketMQ , 在brocke 发送到消费者时,使用sendFile 进行发送数据,发送时消息在内核态就完成了数据的发送。

kafka 的 Mmap方式,操作index索引文件,timeIndex 时间索引文件进行写入。这些操作是写入到pagecache后同步步完成的。 index索引文件是稀疏索引,不会每条消息都添加索引。timeIndex也是。

写入真正消息log文件时直接通过,调用操作系统write函数以顺序写方式写入log文件,没有使用 零拷贝技术,因为kafka是将一批消息数据,直接写入log文件,直接通过消息的量级,分摊了单条消息写入性能。

rocketMQ 也支持一批数据直接发送到brocker,但是需要对每条消息进行拆解,对单条消息做操作。

rocketMQ 是通过Mmap写入 commitLog 文件的, rocketMq 写入消息需要对单条数据进行操作,比如计算消息的tag,索引,偏移量,更新索引文件,延时信息,所有每条消息在写入时都需要进行解析。

所以rocketMQ 批量发送无法向kafka那样单次将一批数据刷入pagecache。他使用了Mmap方式

将内核态数据直接映射到用户态,通过映射直接操作内核态数据,省去数据在用户态写入后再复制到内核态的复制开销。

无法支持将消息批量刷入pagecache,使用Mmap方式降低消息写入的消耗。

2:批量发送

kafka的生产者会自动将消息惨成批次后发送到brocker,brocker会直接通过调用操作系统的write 直接将数据写入到pagecache。

rocketMq生产者需要手动组成list后发送到brocker,brocker 会对每条消息进行拆解,计算每条消息的偏移量,tag的hash等,然后同步索引文件。

3:文件格式

kafka 每个Partition 存在一个log文件存储消息,大小过1g后自动切换下一个。每个parttion 会有一个文件夹存储,里面存放多个segment文件夹,每个segment由.log,index,timeIndex文件组成。 当顺序写入的消息达到默认4kb 时,同步 更新index,与timeIndex文件信息,增加索引项(稀疏索引 )。

查找:先通过索引定位到大概位置,在扫描一小段数据。

rocketMq 整体使用一个commitlog文件存储所有messageQueue消息。大小过1g后自动切换下一个。会为每一条消息建立索引(稠密索引 )。每个队列都有不同的ConsumeQueue 索引文件(数据和索引分离),IndexFile 索引文件是全局的。

存储结构:store目录下,存在commitlog,consumequeue,indexFIle文件夹,

commitlog # 目录1:存放所有消息实体,以偏移量命名

consumerlog # 目录2:存放队列索引(每个Topic/Queue独立)每个topic文件夹下存放多个队列,队列下根据单文件默认存 30 万个条目(约 5.72MB),写满 30 万条索引 后滚动生成新文件。每个条目是定长的 20 字节。

index # 目录3:存放全局哈希索引(IndexFile)------ 按创建时间戳命名的文件, 默认开启但可配置。文件达到 约 400MB 时创建新文件。

索引建立:异步线程每1ms检查commitLog文件新增数据,存在新增数据,重放后解析创建对应的索引,写入consumerQueue,与indexFile索引文件。

bash 复制代码
$HOME/store/
├── commitlog/               # 目录1:存放所有消息实体(CommitLog)
│   ├── 00000000000000000000
│   └── 00000000001073741824
│
├── consumequeue/            # 目录2:存放队列索引(每个Topic/Queue独立)
│   ├── TopicA/
│   │   ├── 0/
│   │   │   └── 00000000000000000000
│   │   └── 1/
│   │       └── 00000000000000000000
│   └── TopicB/
│       └── 0/
│           └── 00000000000000000000
│
└── index/                   # 目录3:存放全局哈希索引(IndexFile) 
    ├── 20240521123056123     # 按创建时间戳命名的文件
    └── 20240521144562123     # 上一个写满后滚动生成的新文件

如何对 messageQueue或partition扩容

1:停机扩容

停止所有生产者服务,队列中所有消息被消费者消费完后,进行扩容操作,新增队列,启动生产者,新消息按照新队列数路由

缺点:不适合需要持续服务的生产环境。

2:成倍扩容,

队列数成倍增加,如8个到16个,保证部分旧key路由到相同队列。

缺点:只能减少乱序概率,无法全部避免

3:应用层双写,灰度迁移

(顺序消息)创建新topic,修改生产者代码,将新消息根据特定逻辑进行分流 / 选择性写入新旧 两个topic。消息100%迁移到新topic后,保证生产者不在向旧topic发送消息。消费者处理完旧topic消息后不要立即删除,可以将旧topic磁盘数据备份,或者停止消费者保留旧topic数据。

回滚预案:在确定新topic稳定运行前一定不能直接删除旧topic, 如果brocker出现异常,大量消息发送失败时,直接切回旧topic。及时止损。

特定逻辑进行分流:

如 工控机台,批次信息,新批次进入新topic,旧批次依然进入旧topic。或者分机台进入不同topic。

如 订单号分流,根据订单号的范围 ,或者用户类型,普通用户的订单,vip用户的订单,测试用户的订单。或者根据订单产生的城市位置。先切

测试订单,在百分之10,50,100 的用用户订单。

如果不需要保证顺序,直接进行Partition,messageQueue增加,但是要注意消费端重分配问题。

相关推荐
johnrui1 小时前
kafka4.x单机版安装部署(单节点 KRaft 模式)
kafka
国科安芯3 小时前
基于抗辐射MCU的卫星分布式控制系统CANFD总线架构研究
网络·人工智能·分布式·单片机·嵌入式硬件·架构·抗辐射
阿里云云原生19 小时前
深入解析 RocketMQ LiteTopic:如何以百万级轻量主题实现用户级消息治理?
rocketmq
深蓝电商API20 小时前
Redis 在分布式爬虫中的作用
redis·分布式·爬虫
凤山老林21 小时前
高可用分布式任务调度架构:Spring Boot 集成 PowerJob 实战指南
spring boot·分布式·架构
面向Google编程21 小时前
Kafka 成了 Agent 的「共享内存」,Flink 成了它的「大脑」
flink·kafka·agent
海宇数据1 天前
零信任架构实战:基于海宇运营商近3个月平均账单构建自动化分布式租赁网关
人工智能·分布式·架构·自动化
IT大白鼠1 天前
MySQL 分布式集群系列 · 第二篇:架构深度拆解--NDB 三大核心节点
分布式·mysql·架构
醉颜凉1 天前
Kafka ISR与AR深度解析:副本同步机制核心概念
分布式·架构·kafka·ar