rocketMq是消息中间件,通常用于业务上的解藕,消峰。
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
单机吞吐量 | 万级,比 RocketMQ、Kafka 低一个数量级 | 同 ActiveMQ | 10 万级,支撑高吞吐 | 10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景 |
topic 数量对吞吐量的影响 | topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic | topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源 | ||
时效性 | ms 级 | 微秒级,这是 RabbitMQ 的一大特点,延迟最低 | ms 级 | ms 级以内 |
可用性 | 高,基于主从架构实现高可用 | 同 ActiveMQ | 非常高,分布式架构 | 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 |
消息可靠性 | 有较低的概率丢失数据 | 基本不丢 | 经过参数优化配置,可以做到 0 丢失 | 同 RocketMQ |
功能支持 | MQ 领域的功能极其完备 | 基于 erlang 开发,并发能力很强,性能极好,延时很低 | MQ 功能较为完善,还是分布式的,扩展性好 | 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用 |
从对比中可以看出,rocketMq整体吞吐量相对比较优秀单机可达10w,同时在参数在实时刷盘的时候可以做到0丢失,在架构上也是分布式架构。
相比kafka,rocketMq支持的topic数量在几百到几千,而kafka在几十到几百就会性能下降。
同时rocketmq还支持消息事务,kafka则功能比较简单适用于大数据实时计算或日志采集场景。
而activeMq及rabbitMq无论从吞吐量及高可用性来讲都赶不上rocketMq。rabbitMq最多做到镜像集群模式,此种模式下这个queue所有数据可在多个集群结点上存储,但是这个queue如果消息量很多突破了单机broker存储的限制,此时就会有问题。
综上分析rocketmq在吞吐量,分布式架构,topic数量上有较大的优势,同时是阿里的中间件整体经历过大流量复杂场景的验证比较可靠。
kafka元数据存储在kafaController结点,对应分区的master挂了后用zk进行选举。
从物理文件上看每个时刻rocketMq对应就是一个commitLog文件。而kafka的物理文件由topic的partion数量决定,一个partion就是一个物理文件。
kafka单机支持的队列数远小于rocketMq,rocketmq理论支持1万个以上。
kafka超过topic超过一千个整体性能就会很差,这是因为kafka多个topic是多个物理文件,因些在写消息的时候整体kafka服务进程就变成随机写了。而rocketMq不会有这个问题因为所有topic都是一个文件。
kafka架构:
rocketMq是分布式的,可以支持多个master slave组成的集群。
但slave只在master消费读取压力比较高时才会触发从slave取数据,且如果master挂了并不会将slave升级成master。
在部署master及slave时,配置master写消息时是同步还是异步写slave。
name sevrer集群保存了所有的broker地址,消费者及生产者是在本地保存了name server集群地址。
当消息发送者发送消息给broker的时候,broker会存储消息到commitLog中。然后会异步构建consumerQueue及消息索引服务。
这样的好处是写操作能保证是磁盘的顺序写从而保证了写的高效能。
而对于消费消息这块则是从consumerQueue拉取数据,consumerQueue保存了一个消息在commitLog中的offset位置及消息大小,所以一次消息消费需要2次读取。consumerQueue这样设计因为存储的内容少,所以整体可以利用操作的系统的PageCache来加快消息的消费速度。
在消息消费时,如果存在slave的情况,并且发现消费者拉取的是磁盘上的内容时此时将consumer的消费重定向到slave服务器。这里不需要担心slave的写性能会减少,因为slave在同步时是同步一批数据,如1M的数据,整体写入量要远远大于master的写入。
这里补充下传统io读取的步骤:
从图中可以看到pageCache相当于一个缓存如果在这个缓存存在则直接从这个缓存读取数据从而加速消费的速度。
但这个图中使用传统io的读取如果没命中缓存则会涉及2次内存拷贝:文件系统到内核,内核到用户空间堆内存。
rcoketMq为了提升性能使用了Mmap零拷贝能力,去除了内核到用户空间堆内存的拷贝。
如下图:
当使用java的mmap后,用户进程空间与内核空间pageCache做了映射。
rocketMq用户态情况下直接从pageCache取数据,不需要再拷贝到用户进程堆空间中,这样做就减少了从内核到用户堆空间的拷贝耗时。