【kafka 原理深度剖析系列】之心技术概念与架构原理
简介
Kafka 起初是由 LinkedIn 公司采⽤Scala 语⾔开发的⼀个多分区、多副本且基于 ZooKeeper 协调的分布式消息系统,现已捐献给 Apache 基⾦会。⽬前 Kafka 已经定位为⼀个分布式流式处理平台,它以⾼吞吐、 可持久化、可⽔平扩展、⽀持流数据处理等多种特性被⼴泛使⽤。
在 0.10 版本之前,Kafka 主要定位是分布式、⾼吞吐、低延迟的消息引擎,平时⼯作中常⽤的消息中间件还有很多,⽐如 RabbitMQ,RocketMQ 等。
从 0.10 版本开始,Kafka 提供了连接器(kafka connect)和流处理(kafka stream),定位也从消息引擎变为流式处理平台。⽬前⽐较流⾏的另⼀个流式处理平台 Pulsar。Pulsar 与 Kafka 的对⽐也被⼤家津津乐道,其⼤部分都是对⽐ Pulsar 和 Kafka 在性能、架构和特性⽅⾯的区别。
Kafka 一些重要概念
Producer:消息⽣产者,向 Kafka Broker 发消息的客户端。
Consumer:消息消费者,从 Kafka Broker 取消息的客户端。
Consumer Group:消费者组(CG),消费者组内每个消费者负责消费不同分区的数据,提⾼消费能 ⼒。⼀个分区只能由组内⼀个消费者消费,消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的⼀个订阅者。
Broker:⼀台 Kafka 机器就是⼀个 Broker。⼀个集群由多个 Broker 组成。⼀个 Broker 可以容纳多个 Topic。
Topic:可以理解为⼀个队列,Topic 将消息分类,⽣产者和消费者⾯向的是同⼀个 Topic。
Partition:为了实现扩展性,提⾼并发能⼒,⼀个⾮常⼤的 Topic 可以分布到多个 Broker (即服务器)上,⼀个 Topic 可以分为多个 Partition,每个 Partition 是⼀个有序的队列。
Replica:副本,为实现备份的功能,保证集群中的某个节点发⽣故障时,该节点上的 Partition 数据不丢失,且 Kafka 仍然能够继续⼯作,Kafka 提供了副本机制,⼀个 Topic 的每个分区都有若⼲个副本,⼀个 Leader 和若⼲个 Follower。
Leader:每个分区多个副本的“主”副本,⽣产者发送数据的对象,以及消费者消费数据的对象,都 是 Leader。
Follower:每个分区多个副本的“从”副本,实时从 Leader 中同步数据,保持和 Leader 数据的同步。Leader 发⽣故障时,某个 Follower 还会成为新的 Leader。
Offset:消费者消费的位置信息,监控数据消费到什么位置,当消费者挂掉再重新恢复的时候,可以从消费位置继续消费。
Zookeeper:Kafka 集群能够正常⼯作,需要依赖于 Zookeeper,Zookeeper 帮助 Kafka 存储和 管理集群信息。
Kafka 原理
控制器选举及恢复
控制器是 Kafka 的核⼼组件之⼀,它的主要作⽤是在 ZooKeeper 的帮助下协调和管理整个 Kafka 集群。 Kafka 利⽤ZooKeeper 的领导者选举机制,每个 Broker 都会参与竞选主控制器,但是最终只会有⼀个 Broker 可以成为主控制器。
控制器有以下⼏个职责:
监听分区相关的变化,例如:运⾏kafka-reassign-partitions.sh 脚本对已有主题分区的细粒度的分配功能
监听主题相关的变化
监听 broker 相关的变化
控制器选举:每个代理节点都会作为 ZooKeeper 的客户端,向 ZooKeeper 服务端尝试创建 /controller 临时节点,但是最终只有 1 个 Broker 可以成功创建临时节点。因为 /controller 节点是临时节点,当主控制器出现故障或者会话失效时,临时节点会被删除。此时所有的 Broker 都会重新竞选 Leader,也就是尝试创建 /controller 临时节点。
Kafka 控制器将 Broker 节点信息存放在 ZooKeeper 的 /controller 节点上,每个 broker 都会在内存中保存当前控制器的 brokerid 值,这个值可以标识为 activeControllerId,每个 broker 还会对/controller 节点添加监听器,以此来监听此节点的数据变化。
当/controller 节点的数据发⽣变化时,每个 broker 都会更新⾃身内存中保存的 activeControllerId。如果 broker 在数据变更前是控制器,在数据变更后⾃身的 brokerid 值与新的 activeControllerId 值不⼀致,那 么就需要“退位”,关闭相应的资源。有可能控制器由于异常⽽下线,造成/controller 这个临时节点被⾃动 删除;也有可能是其他原因将此节点删除了。
当/controller 节点被删除时,每个 broker 都会进⾏选举。如果有特殊需要,则可以⼿动删除/controller 节点来触发新⼀轮的选举,当然关闭控制器对应的 broker 以及⼿动向/controller 节点写⼊新的 brokerid 所对应的数据同样可以触发新⼀轮的选举。
分区 leader 的选举
分区 leader 副本的选举由 Kafka Controller 负责具体实施。当创建分区(创建主题或增加分区都有创建分区的动作)或分区上线(⽐如分区中原先的 leader 副本下线,此时分区需要选举⼀个新的 leader 上线来 对外提供服务)的时候都需要执⾏leader 的选举动作。
基本思路是按照 AR 集合中副本的顺序查找第⼀个存活的副本,并且这个副本在 ISR 集合中。⼀个分区的 AR 集合在分配的时候就被指定,并且只要不发⽣重分配的情况,集合内部副本的顺序是保持不变的,⽽ 分区的 ISR 集合中副本的顺序可能会改变。注意这⾥是根据 AR 的顺序⽽不是 ISR 的顺序进⾏选举的。举个 例⼦,集群中有 3 个节点:broker0、broker1、broker2,在某⼀时刻具有 3 个分区且副本因⼦为 3 的主题
quickstart 的具体信息如下:
此时关闭 broker0,那么对于分区 2⽽⾔,存活的 AR 就变为[1,2],同时 ISR 变为[2,1]。此时查看主题 quickstart 的具体信息,分区 2 的 leader 就变为了 1⽽不是 2。
如果 ISR 集合中没有可⽤的副本,那么此时还需要再检查⼀下所配置的 unclean.leader.election.enable 参 数(默认值为 false)。如果这个参数配置为 true,那么表示允许从⾮ISR 列表中选举 leader,从 AR 列表 中找到第⼀个存活的副本即为 leader。
当分区进⾏重分配的时候也需要执⾏leader 的选举动作。这个选举策略⽐较简单:从重分配的 AR 列表中 找到第⼀个存活的副本,且这个副本在⽬前的 ISR 列表中。当发⽣优先副本的选举时,直接将优先副本设置为 leader 即可,AR 集合中的第⼀个副本即为优先副本。
还有⼀种情况就是当某节点被优雅地关闭(也就是执⾏ControlledShutdown)时,位于这个节点上的 leader 副本都会下线,所以与此对应的分区需要执⾏leader 的选举。这⾥的具体思路为:从 AR 列表中找 到第⼀个存活的副本,且这个副本在⽬前的 ISR 列表中,与此同时还要确保这个副本不处于正在被关闭的 节点上。
Kafka 的核心概念我们就介绍到这里,下一篇文章,我们将为大家带带来 Kafka 分区分配策略的介绍。技术
版权声明: 本文为 InfoQ 作者【云智慧AIOps社区】的原创文章。
原文链接:【http://xie.infoq.cn/article/b699c552dace0f7c519882f1b】。文章转载请联系作者。
评论