rocketMQ design

Motivation

Persistence

和kafka的思想一样,利用顺序IO。

但是,当一个broker上有多个partition的时候,顺序又变成了随机。

RocketMQ为了解决这个问题,采用了单一的日志文件。即把一台机器上的所有的topic的所有queue的消息都存放在同一个文件里面。

先写入Commit log文件里面(单个文件),然后有后台线程异步的同步到ConsumeQueue(也是一个文件),再由Consumer进行消费。这是RocketMQ的方案。

4.2 Persistence

As a result the performance of linear writes on a JBOD configuration with six 7200rpm SATA RAID-5 array is about 600MB/sec but the performance of random writes is only about 100k/sec—a difference of over 6000X.

磁盘的顺序写和随机写,性能相差6000倍,sequential disk access can in some cases be faster than random memory access!

  • OS pagecache

    现代操作系统很乐于使用所有的空闲内存来做disk caching。所有的磁盘读写都会通过这些cache进行。

  • Furthermore, we are building on top of the JVM, and anyone who has spent any time with Java memory usage knows two things:

     The memory overhead of objects is very high, often doubling the size of the data stored (or worse).
    
    Java garbage collection becomes increasingly fiddly and slow as the in-heap data increases.
    

基于上面的两个原因, 得出的结论:

using the filesystem and relying on pagecache is superior to maintaining an in-memory cache

直接使用带pagecache的OS filesystem 甚至性能会比使用内存cache要更好。

This style of pagecache-centric design is described in an article on the design of Varnish

4.3 Efficiency

For more background on the sendfile and zero-copy support in Java, see this article.

4.4 The Producer

任意一个broker都保存着metadate,关于哪些节点是活着的,还有一个topic的partition的leader是谁?所以producer可以找到对应的leader,直接向其发送消息。

4.5 The Consumer

consumer执行‘fetch’操作,同时带着offset,来向leader拉去消息。

offset:

一般的队列都会在broker端记录consumer消费的位置,这样做可以及时的删除消费掉的消息,但是维护这个位置是很费事的,还需要consumer返回ack。

kafka也会记录一个offset,表示下一个可以消费的消息的位置,而且可以‘倒带’,即重现消费之前消费过的消息。

4.6 Message Delivery Semantics

4.7 Replication