kafka概念和设计概述

218 阅读3分钟

1. 概念

在文章开始之前,先初步了解一下kafka的一些重要概念:

  • Topic: 几乎所有的消息中间件都有这个概念,通常指的是一类消息,消息与消息之间主要通过topic进行隔离区分。
  • Broker: 消息的处理节点,一个kafka节点就是一个broker,多个broker组成了kafka集群。
  • Partition: 直接可以理解为一个有序的消息队列,一个topic对应多个partition。
  • Producer: 消息生产者,生产者可以向任意一个topic发送一些消息。
  • Consumer: 消息消费者,消息者可以订阅topic用于接收该topic下的所有消息。
  • Message: 消息,通信的基本单位,每个producer可以向一个topic发送消息。

2. 整体架构

2.1 推和拉

kafka数据的生产和众多消息中间件一样,由kafka的producer向broker push信息,但是数据消费是consumer从broker pull信息。kafka没有选择推送消息到消费者,主要是因为不同的消费者对于消息消费的速率是不同的,push模式的目标就是尽可能以最快速度传递消息,但是这样很容易造成consumer来不及处理消息,典型的表现就是拒绝服务以及网络拥塞,而pull模式则可以根据consumer的消费能力以适当的速率消费message。

生产消费者.png

2.2 Topic和Partition

topic是对不同消息的分类,消息的发送和订阅都需要用到topic。topic在broker上创建,kafka会为每一个topic创建一个单独的文件夹。每一个topic中又可以划分多个分区(partition), 分区中按顺序存储着当前topic下的每一条消息。

image.png

下图中我们创建了一个 topic 名为 mytopic,并且为这个topic创建了3个分区,文件上的存储结构:
image.png

关于kafka的存储后面会细说,这里先有个概念,知道kafka是如何组织的。

2.3 Producer生产者

生产者发送数据时必须要指定一个topic,除此以外,也可以指定一个partition,决定这条消息具体发送到哪里,但这不是必选的,在producer未指定partition序号时,client默认会通过哈希消息分区key选出一个partition,如果消息key也为空,会随机选出一个,并且缓存起来。
所以,如果想充分利用kafka的性能,最好是指定每条消息的分区key,这样可以保证消息均衡的发送到每个partition中。

Kafka的Java client对于分区选择的默认实现在:
org.apache.kafka.clients.producer.internals.DefaultPartitioner
除此之外还提供了其他的分区选择器,可以通过配置的方式切换,有兴趣可以看看。

2.4 Consumer消费者

Kafka提供了两套consumer api,分为high-level api和sample-api。Sample-api 是一个底层的API,它维持了一个和单一broker的连接,并且这个API是完全无状态的,每次请求都需要指定offset值,因此,这套API也是最灵活的。
在kafka中,当前读到消息的offset值是由consumer来维护的,因此,consumer可以自己决定如何读取kafka中的数据。比如,consumer可以通过重设offset值来重新消费已消费过的数据。不管有没有被消费,kafka会保存数据一段时间,这个时间周期是可配置的,只有到了过期时间,kafka才会删除这些数据。
High-level API封装了对集群中一系列broker的访问,可以透明的消费一个topic。它自己维持了已消费消息的状态,即每次消费的都是下一个消息。
High-level API还支持以组的形式消费topic,如果consumers有同一个组名,那么kafka就相当于一个队列消息服务,而各个consumer均衡的消费相应partition中的数据。若consumers有不同的组名,那么此时kafka就相当与一个广播服务,会把topic中的所有消息广播到每个consumer。

image.png