Apache Kafka 是一个快速、可扩展的、高吞吐的、可容错的分布式“发布-订阅”消息系统, 使用 Scala 与 Java 语言编写,能够将消息从一个端点传递到另一个端点。
1. Kafka 作为存储系统可以将 Kafka 视为一种专用于高性能,低延迟提交日志存储,复制和传播的专用分布式文件系统。
2. Kafka 作为消息传递系统
Kafka 的消费者群体概念概括了这两个概念。与队列一样,使用者组允许您将处理划分为一组进程(使用者组的成员)。与发布订阅一样,Kafka 允许您将消息广播到多个消费者组。
3. Kafka 用作流处理
Kafka 中,流处理器是指从输入主题中获取连续数据流,对该输入进行一些处理并生成连续数据流以输出主题的任何东西。
二、Kafka 架构体系 1. 物理模型
2. 逻辑模型
3. 架构
三、概念 1. Broker(节点)
Kafka 集群包含一个或多个服务器,每个服务器节点称为一个 Broker。
Broker 存储 Topic 的数据。如果某 Topic 有 N 个 Partition,集群有 N 个 Broker,那么每个 Broker 存储该 Topic 的一个 Partition。
如果某 Topic 有 N 个 Partition,集群有(N+M)个 Broker,那么其中有 N 个 Broker 存储该 Topic 的一个 Partition,剩下的 M 个 Broker 不存储该 Topic 的 Partition 数据。
如果某 Topic 有 N 个 Partition,集群中 Broker 数目少于 N 个,那么一个 Broker 存储该 Topic 的一个或多个 Partition。在实际生产环境中,尽量避免这种情况的发生,这种情况容易导致 Kafka 集群数据不均衡。
2. Topic:主题在Kafka中消息以主题为单位进行归类,每个主题都有一个Topic Name,生产者根据Topic Name将消息发送到特定的Topic,消费者则同样根据Topic Name从对应的Topic进行消费。
Topic 相当于消息的分类标签,是一个逻辑概念。
物理上不同 Topic 的消息分开存储,逻辑上一个 Topic 的消息虽然保存于一个或多个 Broker 上但用户只需指定消息的 Topic 即可生产或消费数据而不必关心数据存于何处。
3. Partition:分区
Topic 中的消息被分割为一个或多个 Partition,其是一个物理概念,对应到系统上 就是一个或若干个目录。
Partition 内部的消息是有序的,但 Partition 间的消息是无序的。
Topic(主题)是消息归类的一个单位,但每一个主题还能再细分为一个或多个Partition(分区),一个分区只能属于一个主题。
主题和分区都是逻辑上的概念,举个例子,消息1和消息2都发送到主题1,它们可能进入同一个分区也可能进入不同的分区(所以同一个主题下的不同分区包含的消息是不同的),之后便会发送到分区对应的Broker节点上。
4. Offset(偏移量):
分区可以看作是一个只进不出的队列(Kafka只保证一个分区内的消息是有序的),消息会往这个队列的尾部追加,每个消息进入分区后都会有一个偏移量,标识该消息在该分区中的位置,消费者要消费该消息就是通过偏移量来识别。
5. Segment 段
将 Partition 进一步细分为了若干的 Segment,每个 Segment 文件的大小相等。
6. Producer:生产者
即消息的发布者,生产者将数据发布到他们选择的主题。生产者负责选择将哪个记录分配给主题中的哪个分区。即:生产者生产的一条消息,会被写入到某一个 Partition。
7. Consumer:消费者
可以从 Broker 中读取消息。一个消费者可以消费多个 Topic 的消息;一个消费者可以消费同一个 Topic 中的多个 Partition 中的消息;一个 Partiton 允许多个 Consumer 同时消费。
8. Consumer Group
Consumer Group 是 Kafka 提供的可扩展且具有容错性的消费者机制。组内可以有多个消费者,它们共享一个公共的 ID,即 Group ID。组内的所有消费者协调在一起来消费订阅主题 的所有分区。Kafka 保证同一个 Consumer Group 中只有一个 Consumer 会消费某条消息。
实际上,Kafka 保证的是稳定状态下每一个 Consumer 实例只会消费某一个或多个特定的 Partition,而某个 Partition 的数据只会被某一个特定的 Consumer 实例所消费。
下面我们用官网的一张图, 来标识 Consumer 数量和 Partition 数量的对应关系。
9. Replizcas of partition:分区副本
副本是一个分区的备份,是为了防止消息丢失而创建的分区的备份。
10. Partition Leader
每个 Partition 有多个副本,其中有且仅有一个作为 Leader,Leader 是当前负责消息读写的 Partition。即所有读写操作只能发生于 Leader 分区上。
11. Partition Follower
所有 Follower 都需要从 Leader 同步消息,Follower 与 Leader 始终保持消息同步。Leader 与 Follower 的关系是主备关系,而非主从关系。
12. Broker Controller
Kafka集群的多个 Broker 中,有一个会被选举 Controller,负责管理整个集群中 Partition 和 Replicas 的状态。
只有 Broker Controller 会向 Zookeeper 中注册 Watcher,其他 Broker 及分区无需注册。即 Zookeeper 仅需监听 Broker Controller 的状态变化即可。
13. ZooKeeper
ZooKeeper 负责维护和协调 Broker,负责 Broker Controller 的选举。在 Kafka 0.9 之前版本,Offset 是由 ZooKeeper 负责管理的。
总结:ZooKeeper 负责 Controller 的选举,Controller 负责 Leader 的选举。
三、Kafka 的应用场景
四、Kafka 高可用
1. 副本
在0.8版本后引入副本则很好地解决宕机后数据丢失的问题。
副本是以Topic中每个Partition的数据为单位,每个Partition的数据会同步到其他物理节点上,形成多个副本。
每个Partition的副本都包括一个Leader副本和多个Follower副本,Leader由所有的副本共同选举得出,其他副本则都为Follower副本。
在生产者写或者消费者读的时候,都只会与Leader打交道,在写入数据后Follower就会来拉取数据进行数据同步。
2. 当某个Broker挂掉了?
甭担心,这个Broker上的Partition在其他Broker节点上还有副本。
3. 如果挂掉的是Leader怎么办?
那就在Follower中在选举出一个Leader即可,生产者和消费者又可以和新的Leader愉快地玩耍了,这就是高可用。
4. 多少个副本才算够用?
副本肯定越多越能保证Kafka的高可用,但越多的副本意味着网络、磁盘资源的消耗更多,性能会有所下降,通常来说副本数为3即可保证高可用,极端情况下将replication-factor参数调大即可。
5. Follower和Lead之间没有完全同步怎么办?
Follower和Leader之间并不是完全同步,但也不是完全异步,而是采用一种ISR机制(In-Sync Replica)。
每个Leader会动态维护一个ISR列表,该列表里存储的是和Leader基本同步的Follower。
如果有Follower由于网络、GC等原因而没有向Leader发起拉取数据请求,此时Follower相对于Leader是不同步的,则会被踢出ISR列表。
所以说,ISR列表中的Follower都是跟得上Leader的副本。
6. 一个节点宕机后Leader的选举规则是什么?
分布式相关的选举规则有很多,像ZooKeeper的Zab、Raft、Viewstamped Replication、微软的PacificA等。
而Kafka的Leader选举思路很简单,基于我们上述提到的ISR列表,当宕机后会从所有副本中顺序查找,如果查找到的副本在ISR列表中,则当选为Leader。
另外还要保证前任Leader已经是退位状态了,否则会出现脑裂情况(有两个Leader)。
7. 怎么保证不会有2个leader?
Kafka通过设置了一个controller来保证只有一个Leader。
https://mp.weixin.qq.com/s/R1en4V0Tlwlpt102BjotoA
因为一次 Kafka 宕机,我明白了 Kafka 高可用原理!
https://mp.weixin.qq.com/s/1-GpycMKdcgCjs1tSOg1Kg