【译】Apache Kafka支持单集群20万分区

  以前网上关于肯定Kafka分区数的博客多多少少都源自于饶军大神的文章,现在他带来了这方面的第二篇文章,特此翻译一下,记录一下其中的要点。apache

  原贴地址: https://www.confluent.io/blog/apache-kafka-supports-200k-partitions-per-cluster异步


 

  Kafka中topic能够设置多个分区,而分区是最小的并行度单位。一般而言,分区数越多吞吐量也越高。可是依然有不少因素制约了一个Kafka集群所能支持的最大分区数。我如今高兴地宣布Kafka 1.1.0版本在这方面取得了重大的改进。目前生产环境中单Kafka集群支持的分区上限获得了极大的提高。性能

  为了便于理解这个改进是如何实现的,咱们重温一下分区leader和controller的基本概念。首先,每一个分区均可以配置多个副本用于实现高可用性以及持久性。其中的一个副本被指定为leader而全部client只与leader进行交互;其次,cluster中的某个broker被指定为controller来管理整个集群。若broker挂掉,controller负责为该broker上全部分区选举leader。测试

  默认状况下关闭Kafka broker执行的是一个受控关闭操做(下称controlled shutdown)。Controlled shutdown对client的影响是最小的。一个典型的controlled shutdown分为如下几步:1. 发送SIGTERM信号给待关闭的broker;2. Broker发送请求给controller代表本身要正常关闭;3. Controller变动该broker上全部分区的leader并将这部分数据保存回Zookeeper;4. Controller发送新的leader信息给其余broker;5. Controller发送响应给关闭中的broker代表操做成功,因而broker成功关闭。此时,client端不受任何影响由于新leader已经转移到其余broker上。下面的两张图描述了这个过程,注意到图中(4)和(5)步是能够并行执行的:优化

       

上图中步骤(1)发起broker关闭;步骤(2)发送controlled shutdown请求给controller;步骤(3)中controller写入新leader到Zookeeper;步骤(4)controller发送新leader信息到其余broker;步骤(5)controller发送成功信息给关闭中的broker翻译

   在Kafka 1.1.0以前,一旦发起controlled shutdown,controller每次只能为一个分区选举leader。对于每一个分区而言,controller顺序执行:选择新leader、同步写leader信息回Zookeeper以及同步leader信息给其余broker等操做。这种设计是低效率的:首先,同步写入Zookeeper就有很高的延时,从而总体拖慢controller shudown时间;其次,每次处理一个分区的作法致使须要给其余broker发送不少次请求,即便这些请求自己携带的数据量是很小的,从而最终致使对新leader的处理时间被极大地拉长。设计

  Kafka 1.1.0为controlled shutdown引入了多个方面的性能提高。第一个提高就是使用异步API来替代了以前的同步写入Zookeeper。在controlled shutdown过程当中,Kafka再也不是每次写入一个leader信息,等待其完成而后再写入下一个。相反地,controller使用异步API一次性地提交多个分区的leader到Zookeeper上,而后统一等待其执行完毕。这就等于在Kafka与Zookeeper之间构建了一种管道式请求处理流程,从而减小了总体的延时。第二个提高则是将于新leader的交互操做批量化。与其每次为一个分区发送RPC请求,controller使用单个RPC请求一次性地携带全部受影响分区的leader信息。日志

  同时,Kafka对于controller failover的时间也作了优化。当controller挂掉后,Kafka集群自动检测controller失败并选择其余broker做为新的controller。在开启controller工做以前,新选出的controller必需要从Zookeeper中加载全部分区的状态信息到内存中。若是controller直接崩溃的话,分区不可用的时间窗口将等同于Zookeeper会话超时时间加上controller状态加载时间,因此下降加载时间可以有效地帮助咱们改善Kafka可用性。在1.1.0以前,加载操做使用的也是同步Zookeeper API。在1.1.0中被替换成了异步API。blog

  社区对controlled shutdown时间和加载时间都作了测试。每一个测试都使用了5节点Zookeeper的集群。在测试controlled shutdown时,社区搭建了一个5节点broker的Kafka集群并为该集群建立了25000个单分区的topic,每一个topic都是双副本,故每一个broker上平均有10000个分区。以后测试controlled shutdown,测试结果以下:内存

  提高的很大一部分来自于修复了打日志(logging)的开销:以前在每一个分区leader变动时都会记录集群中全部分区的数据——这其实是不必的。经过修复了这个logging的bug,controller shutdown从6.5分钟被压缩到30秒,而采用异步API更进一步地将其拉低到3秒。这些提高都极大地缩短了Kafka集群重启恢复的时间。

  在第二项测试中,社区一样搭建了一个5节点集群,只不过此次建立了2000个配置有50分区的topic,单副本——故总数是1000000个分区。当测试controller状态加载时间时发现比1.0.0有了100%的提高(1.0.0耗时28秒,1.1.0耗时14秒)。

  有了这些提高,Kafka单集群可以支持多少分区呢?确切的数字天然依赖于诸如可容忍的不可用窗口时间、Zookeeper延时、broker存储类型等因素。根据经验法则咱们评估单台broker可以支撑的分区数可达4000个,而单集群可以支撑200000个分区。固然后者主要受限于集群对controller崩溃这种不常见情形的容忍度,另外其余影响分区数的因素也要考虑进来。

  1.1.0所作的改进仅仅是提高Kafka高扩展性的一小步。事实上社区在1.1.0版本还尝试了更多的分区并改进了它们的延时表现。后面可能会在另外一篇文章中给出具体的说明。在将来,Kafka社区计划实现单集群支撑百万级分区的构想,因此,敬请期待~~

相关文章
相关标签/搜索