一.说到Kafka之前,我们首先了解消息系统(又称消息队列)是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用,其主要有两种模式:

  1. 队列模式(又称点对点模式):多个消费者读取消息队列,每条消息只发送给一个消费者。
  2. 发布/订阅模式:多个消费者订阅主题,主题的每条记录会发送给所有的消费者。

kafka 订阅者 kafka订阅消息_数据

 二.Apache Kafka是一个分布式的、基于发布/订阅的消息系统,其由Scala语言编写而成,具备快速、可扩展、可持久化的特点。

在学习之前,我们首先要了解Kafka的基本模型和一些概念。下图是一张完整的Kafka集群架构。

kafka 订阅者 kafka订阅消息_数据_02

  1. 消息:消息是Kafka最基本的数据单元,由一串字节组成,内部是由Key-value形式构成。Key和value都是byte数组。在Kafka中根据key值将消息分配到指定的Partition,key可以为null,value中存放数据。
  2. Topic(主题):用于存储消息的集合。生产者向Topic推送(push)消息,消费者从其中消费信息。每个Topic可以划分为多个Partition,每个消息被分配到指定Partition时,Kafka会给消息分配一个offset(偏移量),通过offset确保消息在分区中的顺序,同时因为offset不跨分区,所以Kafka只保证同一分区内的消息是有序的。
  3. 分区:同一Topic的不同分区会分配在不同的Broker上。分区是Kafka水平扩展性的基础,我们可以通过增加服务器并在其上分配Partition的方式增加其并行处理能力。
  4. Log:分区在逻辑上对应一个Log,生产者将消息写入分区时,实际上是将写入对应的Log中。Log是一个逻辑概念,对应到磁盘的一个文件夹,Log由多个Segment组成,每个Segment对应一个日志文件和索引文件。在海量数据中为避免出现超大文件,当日志文件大小超过限制后则创建新的Segment(因为Kafka采用顺序I/O,所以只向最新的Segment追加数据)。
  5. Broker:即一个单独的Kafka Server。Broker主要工作就是接受生产者的消息并分配offset,然后保存到磁盘上,同时接受消费者和其他Broker的请求,根据请求类型进行相应处理并返回响应。一般一个Broker独占一个物理服务器。
  6. Cluster:多个Broker组成一个Cluster对外提供服务。每个Cluster会选取一个Broker担任Controller作为Kafka集群的指挥中心,而其他Broker听从Controller实现相应的功能。Controller主要负责的管理分区的状态,管理每个分区的副本状态,监听Zookeeper中数据的变化等工作。
  7. 生产者:生产消息并按照一定规则push消息到Topic的分区中,一般采用根据消息的key的hash值选择分区或按序轮训全部分区。
  8. 消费者:从Topic拉取消息,并对消息进行消费。各个消费者拉去哪个offset的信息是由每个Consumer自己来维护的。
  9. Consumer Group:多个消费者组成一个Consumer Group,一个消费者只能属于一个Consumer Group。Consumer Group保证其订阅的Topic的每个分区只被Consumer Group中的一个消费者处理,即使Consumer Group订阅了同一Topic,Consumer Group之间也不会干扰。例子:如果要实现一个消息被多个消费者同时消费(广播),我们只需将每个消费者放入单独的一个Consumer Group。如果要实现一个消息只被一个消费者消费的效果,我们只需将Consumer放入一个Consumer Group中。

kafka的优势

  • 实时性:Kafka具有近乎实时的消息处理能力,即使面对海量消息也能够高效地存储消息和查询消息。
  • 可持久性:Kafka将消息保存在磁盘中,通过顺序读写地方式去访问磁盘,从而避免了随机读写磁盘导致的性能瓶颈(两者寻址操作上所耗费的时间存在巨大差异导致顺序读写性能远优于随机读写)。
  • 批处理:Kafka支持批量读写消息,并且对消息进行批量压缩,这样既提高了网络的利用率,也提高了压缩效率。
  • 扩展性:Kafka支持在线分区,支持在线水平扩展(一个topic实际是由多个partition组成的,遇到瓶颈时,可以通过增加partition的数量来进行水平扩展)。
  • 分布式:Partitions分布在集群的每一台server上,而每一个Partition在集群中都可以有多个备份,这个备份数量是可配置的。Kafka支持为每个分区创建多好个副本,其中只有一个Leader副本负责读写,其他副本只负责与Leader副本进行同步,这种方法提高了数据的容灾能力。Kafka会将Leader副本均匀地分布在集群中地服务器上,实现性能地最大化。