Kafka自维护计划:删除ZooKeeper依赖关系


Apache Kafka是高吞吐的分布式式消息发布订阅系统 。 现在Kafka使用Apache ZooKeeper存储其元数据和集群维护 。 Kafka分区位置和主题配置之类的元数据都存储在ZooKeeper群集中 。 去年Kafka社区提出了一项提议KIP-500用以去掉该依赖 , 使用Kafaka本身来管理元数据的自维护计划 , 我们本文就来介绍KIP-500改进 。
Kafka自维护计划:删除ZooKeeper依赖关系
本文插图
概述
Kafka是由Apache软件基金会下一个开源的高吞吐量的分布式发布订阅消息系统 , 由Scala和Java编写 。 常用于对网站日志中进行流数据 。 由于其高效的数据处理能力 , Kafka是现代大数据处理的基础组件之一 。
目前的问题
在Kafka的设计中 , 使用了Zookeeper来进行所有Broker的管理 , 每个Broker服务器启动时都会到连接到Zookeeper注册 , 创建/brokers/ids/[0-N]节点 , 写入IP , 端口等信息 。 当Broker发生状态变化 , 比如下线 , 对应Broker节点也就被删除 。 因此zookeeper上Broker节点的变化就可以用来表示Broker服务器的可用性,Kafka的Topic管理也通过类似这种方式管理 。
这样一来 , 每一个Kafka集群中 , 都必须部署两套系统 , 会导致很多重复 。 两套系统都有其自己的网络通信 , 安全性 , 监视和配置方式 。 这样使安装部署和运维操作的结果总复杂度也会翻倍 。 不仅会导致陡峭学习曲线 , 也增加了某些配置错误导的风险 。
其次 , 在外部存储元数据不是很有效 。 在现有集群中至少要运行三个附加的Java进程 , 有时还要运行更多 。 经常能看到Kafka集群的ZooKeeper节点与Kafka节点一样多 。 而且ZooKeeper中的数据也需要反映在Kafka控制器上 , 会导致双重缓存 。
再次 , 外部存储元数据限制了Kafka的可伸缩性 。 当Kafka集群启动或选择新的控制器时 , 控制器必须从ZooKeeper加载集群的完整状态 。 随着元数据量的增加 , 该加载过程的时间也随之增加 。 这限制了Kafka可以存储的分区数量 。
最后 , 将元数据存储在外部会增加控制器的内存状态与外部状态不同步的可能性 。 控制器的活动视图也可以与ZooKeeper的视图不统一 。
KIP-500
KIP-500议案提出了在Kafka中处理元数据的更好方法 。 基本思想是''Kafka on Kafka'' , 将Kafka的元数据存储在Kafka本身中 , 无需增加额外的外部存储比如ZooKeeper等 。
在KIP-500议案中 , 元数据将存储在Kafka分区中 , 而不是存储在ZooKeeper中 。 控制器将是该分区的所有者 。 Kafka本身就不会配置和管理外部元数据系统 。
元数据将被视为日志 。 需要最新更新的Brokers只能读取日志的末尾 。 类似于需要最新日志条目的使用者仅需要读取日志的最后而不是整个日志的方式 。 Brokers还将能够在整个流程重启期间保留其元数据缓存 。
控制器架构
Kafka自维护计划:删除ZooKeeper依赖关系
本文插图
Kafka集群选择一个控制器节点来管理分区领导者和集群元数据 。 拥有的分区和元数据越多 , 控制器的可伸缩性就越重要 。 期望将需要时间与主题或分区的数量成线性比例的操作的数量减至最少 。
一种这样的操作是控制器故障转移 。 当前 , 当Kafka选择新控制器时 , 它需要在继续之前加载整个集群状态 。 随着群集元数据数量的增加 , 此过程将花费越来越长的时间 。
Kafka自维护计划:删除ZooKeeper依赖关系
本文插图
相比之下 , 在后KIP-500中 , 只要活动控制器消失 , 就会有几个备用控制器准备接管 。 这些备用控制器只是元数据分区的Raft仲裁中的其他节点 。 这种设计确保了当选择一个新的控制器时 , 永远不需要经过漫长的加载过程 。


推荐阅读