消息存储,高可用机制,负载均衡,消息重试,死信队列,消息幂等
消息存储:为了保障高可用需要持久化:
存储介质:
1)关系型数据库DB:Apache下开源的另外一款MQ—ActiveMQ(默认采用的KahaDB做消息存储)可选用JDBC的方式来做消息持久化,通过简单的xml配置信息即可实现JDBC消息存储。
2)文件系统:(RocketMQ/Kafka/RabbitMQ)均采用的是消息刷盘至所部署虚拟机/物理机的文件系统来做持久化
存储过程读和写是如何保持高速的:
写:RocketMQ的消息用顺序写,保证了消息存储的速度:目前的高性能磁盘,顺序写速度可以达到600MB/s, 超过了一般网卡的传输速度。 磁盘随机写的速度只有大概100KB/s ,和顺序写的性能相差6000倍!
读:Linux操作系统分为【用户态】和【内核态】,文件操作、网络操作需要涉及这两种形态的切换 。一台服务器 把本机磁盘文件的内容发送到客户端,一般分为两个步骤:
1)read;读取本地文件内容;
2)write;将读取的内容通过网络发送出去。
这两个看似简单的操作,实际进行了4 次数据复制,分别是:
-
从磁盘复制数据到内核态内存;
-
从内核态内存复 制到用户态内存;
-
然后从用户态 内存复制到网络驱动的内核态内存;
-
最后是从网络驱动的内核态内存复 制到网卡中进行传输。
这种mmap也就是零拷贝省去向用户态的内存复制,提高速度。 RocketMQ充分利用了上述特性,提高消息存盘和网络发送的速度。 这种机制在Java中是通过MappedByteBuffer实现的,但采用MappedByteBuffer这种内存映射的方式有几个限制,其中之一是一次只能映射1.5~2G 的文件至用户态的虚拟内存,这也是为何RocketMQ默认设置单个CommitLog日志数据文件为1G的原因
消息存储结构:
RocketMQ消息的存储是由ConsumeQueue和CommitLog配合完成 的,消息真正的物理存储文件是CommitLog,ConsumeQueue是消息的逻辑队列,类似数据库的索引文件,存储的是指向物理存储的地址。每 个Topic下的每个Message Queue都有一个对应的ConsumeQueue文件