分布式队列的几个名词和解释--以Kafka为例

Topic 或者Subject

每一个生产者都需要向队列中生产消息,不同的生产者生产消息需要有所区别,供对应的消费者消费消息,这个是队列名称之为 Topic或者Subject

MessageLog,ConsumerLog

队列的消息需要一个存储的介质,Kafka的对应的存储为文件存储,生产者生产的消息存储在MessageLog, 然后根据不同的消费和路由规则路由,投递到对应的服务器上面,产生对应的ConsumerLog.

Partition

当投递的消息比较多的时候,就需要对ConsumerLog进行分片,分到不同的服务器上面,这个分片称之为partition,对于Kafka来说,一个Consumer一般和Partition成倍数关系,一个Consumer可以消费一个或者多个Partition.

Broken

Broken可以理解为消费者的服务器。

顺序IO

很多成熟的MQ的消息的存储都采用的磁盘的存储模式,可能有人会认为为什么不采用内存?内存的效率不应该更快吗?我开始也有这个疑问,后来才知道顺序IO的时候,才知道不适用内存的原因:

  1. 磁盘的顺序IO开销很低,甚至会小于内存的随机读写
  2. 使用磁盘读写,由系统来维护,相对来说更稳定和健壮
  3. GC的效率很低,开销也很大,频繁的内存回收对于GC并不友好
  4. 服务器宕机后,内存的回复和备份比较麻烦,使用磁盘读写能够很好的避免的这个问题(依赖系统的刷盘的时间)

Zero Copy

当Kafka的消费者访问服务端的时候,需要经历一下几个过程:

  1. 调用操作系统的接口,把数据从磁盘读入内核空间读缓冲区
  2. kafka从内核空间的缓冲区将数据拷贝到用户空间缓冲区
  3. 应用程序将数据从用户空间缓冲区读入到内核空间Socket的缓冲区
  4. 操作系统将socket的缓冲区的数据拷贝到NIC的缓冲区,然后发送给客户端

    (后面补个图)

    从上面的过程可以看出,数据经历了从内核态-->用户态-->内核态的流转,如果使用零拷贝的技术,直接从内核态的数据拷贝的Socket的缓冲区,避免了从内核态到用户态的流转