Kafka
Apache Kafka 是一款开源的消息引擎系统,其主要功能是提供一套完备的消息发布与订阅解决方案。
在 Kafka 中,发布订阅的对象是主题(Topic),我们可以为每个业务、每个应用甚至是每类数据都创建专属的主题。
消息(Record)
我们已经知道,Kafka 是消息引擎,这里的消息就是指 Kafka 处理的主要对象。
主题(Topic)
主题是承载消息的逻辑容器,在实际使用中多用来区分具体的业务。
生产者(Producer)
向主题发布消息的客户端应用程序。
消费者(Consumer)
从主题订阅消息的应用程序。
客户端(Clients)
我们把生产者和消费者统称为客户端。
服务器端(Broker)
由被称为 Broker 的服务进程构成,即一个 Kafka 集群由多个 Broker 组成,Broker 负责接收和处理客户端发来的请求,以及对消息进行持久化。
分区(Partition)
一个有序不变的消息队列。每个主题下可以有多个分区。
生产者生产的每条消息只会被发送到一个分区中,也就是说如果向一个双分区的主题发送一条消息,这条消息要么在分区 0 中,要么在分区 1 中。(Kafka 的分区编号从 0 开始递增)
分区的设计是为了解决分布式系统中的伸缩性问题:把数据分割成多份保存在不同的 Broker 上,从而避免数据太多以至于单台 Broker 都无法容纳。
Partition 与 MongoDB 和 Elasticsearch 中的 Sharding、HBase中的Region,其实它们都是相同的原理,只是 Partitioning 是最标准的名称。
副本(Replica)
Kafka 中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方就是所谓的副本。
副本是在分区层级下实现的,即每个分区可配置多个副本实现高可用。
副本可以分为领导者副本(Leader Replica)和追随者副本(Follower Replica)。前者对外提供服务,这里的对外指的是与客户端程序进行交互;而后者只是被动的追随前者而已,不能与外界进行交互。
副本的工作机制:生产者总是向领导者副本写消息;而消费者总是从领导者副本读消息。至于追随者副本,它只做一件事:向领导者副本发送请求,请求领导者把最新生产的消息发给它,这样它能保持与领导者的同步。
我们知道,MySQL 的从库是可以处理读操作的,但是在 Kafka 中追随者副本不会对外提供服务。其原因有以下几点:
- kafka 的分区已经能够让读写操作在多个 Broker 上,而不像 MySQL 的主从,压力都在主上;
- kafka 保存的数据和数据库的性质有实质的区别:Kafka 中的数据是流数据,需要记录消费位移,而数据库是实体数据不存在这个概念,如果从 Kafka 的 Follower 读,消费端 offset 控制将更复杂;
- 对于生产者来说,kafka 可以通过配置来控制是否等待 Follower 的消息确认,如果从上面读,也需要所有的 Follower 都确认了才可以回复生产者,造成性能下降,如果 Follower 出问题了也不好处理。
消费者组(Consumer Group)
多个消费者实例共同组成的一个组,同时消费多个分区以实现高吞吐。
主题中的每个分区都只会被组内的一个消费者实例消费,其它消费者实例不能消费它。一个消费者实例可以消费多个分区。分区数决定了消费者个数的上限,一般情况下消费者个数应与分区数一致,消费者个数过多会浪费系统资源,因为多出的消费者不会被分配到任何分区。
重平衡(Rebalance)
消费者组内某个实例挂掉后,其它消费者实例自动重新分配订阅主题分区的过程。Rebalance 是 Kafka 实现高可用的重要手段。
消息位移(Offset)
表示分区中每条消息的位置信息,是一个单调递增且不变的值。
消费者位移(Consumer Offset)
表示消费者的消费进度,每个消费者都有自己的消费者位移。