Kafka类似于传统的消息系统,但是又不同于消息系统,因为它不仅具有传统消息系统的消息传递的功能,而且它还具备流失处理能力。

###消息
Kafka中的数据单元被称为消息。相当于数据库中的“行”。

  • 消息由字节数组组成
  • 消息有一个可选的元数据,称为“键”
  • 消息是存在一个称为“主题”的地方的,主题就相当与数据库中的表,一个主题分成了很多个“分区”,具体的,消息就是被存到了某一主题的一个分区上

为了提高效率,会将消息进行“批量”处理,也就是批量的存储到分区中,这就有了“批次”的概念,一个批次就是一组消息,这一组消息属于同一个主题和分区。为什么要进行批量处理?

这是因为:

  • 消息是通过网络传输到Kafka集群中进行存储的
  • 如果每一个消息都进行一个网络传输,那么毫无疑问,会导致大量的网络IO开销
  • 但是,通过把消息批量传输,一组消息只需要一次网络IO,这样可以大大降低整体的IO开销

同时,进行批量处理的消息还会被压缩,可以最小限度的提升数据的传输和存储能力。但是,这也意味着,需要经过更多的计算才行。

###主题和分区

主题
  • Kafka中的消息是按主题来进行分类的,主题相当于数据库中的表的概念,或者是文件系统的文件夹的概念;
  • 一个主题可以被分成若干个分区;
  • 消息是以追加的方式写入到分区的尾部,FIFO的方式进行读取;
  • 消息在整个主题中无法保障顺序性,但是消息在一个分区中是具有顺序性的;
  • Kafka通过分区来保障数据的冗余和伸缩性(这句话我不是很理解)

####那么消息是如何被存储到主题的某一个特定的分区的呢?

#####哈希取模分段

  1. 在前面我们提到了对每个消息都有一个可选的元数据,称为“键”,对这个key进行一致性hash运算,计算得到一个hash值,然后将这个hash进行取模分段,一般是对分区个数进行取模,然后可以建立消息与分区之间的一种映射关系。
  2. 消息键:可选的元数据“键”
  3. 分区器:进行分区映射的计算逻辑,用户可以根据不同的业务场景,自己实现分区器

#####随机

  1. 对消息进行随机的分配,分到哪个分区就是哪个分区

###生产者
生产者就是往主题中放消息的进程

###消费者

#####消费者从主题中读取消息;
#####偏移量

  1. 一种元数据,在创建消息的时候,Kafka会把偏移量添加进消息中,这是一个不断递增的整数,每个消息的偏移量是唯一的;
  2. 消费者通过这个偏移量来区分已经读取到哪个消息了;
  3. 消费者会把每个分区最后读取到的消息偏移量保存在ZooKeeper中或者Kafka上,如果消费者中途关闭重启,它的读取状态也不会丢失;

#####消费者群组

  1. 消费者是消费者群组的一部分;
  2. 一般是一个消费者群组里的所有消费者共同读取某一个主题,群组可以保证每个消息只会被读取一次;
  3. Kafka可以保证一个分区只会被一个群组中的消费者读取;
  4. 如果群组中有一个消费者挂了,那么其他消费者可以接管其工作。