Kafka 进阶学习(五)—— 如何合理选择合适的分区数

281 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

前言

本文是我 Kafka 学习的第 5 天,今天我们来研究一个常见的问题,如果选择合适的分区数?对于分区数设置为多少合适,其实没有权威的答案,同编程中的数组扩容时的阈值一样,最终设置的值也是需要根据实际的业务场景、软件条件、硬件条件、负载情况等来做具体的考量。

下面我们来看看设置分区数时需要考虑哪些指标。

分区概念

那么何为分区呢?主题作为消息的归类,可以再细分为一个或多个分区,分区也可以看作对消息的二次归类。分区的划分不仅为 Kafka 提供了可伸缩性、水平扩展的功能,还通过多副本机制来为 Kafka 提供数据冗余以提高数据可靠性。

分区是 Kafka 中最小的并行操作单元,对生产者而言,每一个分区的数据写入是完全可以并行化的;对消费者而言,Kafka 只允许单个分区中的消息被一个消费者线程消费,一个消费组的消费并行度完全依赖于所消费的分区数。

从 Kafka 的底层实现来说,主题和分区都是逻辑上的概念,分区可以有一至多个副本,每个副本对应一个日志文件,每个日志文件对应一至多个日志分段(LogSegment),每个日志分段还可以细分为索引文件、日志存储文件和快照文件等。

影响因素

Kafka 性能测试主要依赖其自身提供的工具,即:用于生产者性能测试的 kafka-producer-perf-test.sh 和用于消费者性能测试的 kafka-consumer-perf-test.sh

性能的比较主要看 吞吐量,消息的吞吐量不仅受硬件资源的影响,还会受消息大小、、消息压缩方式、消息发送方式(同步/异步)、消息确认类型(acks)、副本因子等参数的影响。消息消费的吞吐量还会受到应用逻辑处理速度的影响。这里我们保证所有的因子一致即可,只测试主题的分区数不同。

文件描述符

经过测试我们可以看到分区数为 1 时吞吐量最低,随着分区数的增长,相应的吞吐量也跟着上涨。一旦分区数超过了某个阈值之后,整体的吞吐量是不升反降的。也就是说,并不是分区数越多吞吐量也越大。

并且分区数也并不能一直增加,如果超过默认的配置值,还会引起 Kafka 进程的崩溃。其中一个原因是 文件描述符不足。这个情况下,我们可以根据系统资源来调大这个参数,比如使用 ulimit-n 65535 命令将上限提高到 65535,这样足以应对大多数的应用情况。

消息写入

另外,当生产者向 Kafka 中写入基于 key 的消息时,Kafka 通过消息的 key 来计算出消息将要写入哪个具体的分区,这样具有相同 key 的数据可以写入同一个分区。

比如对于同一个 key 的所有消息,消费者需要按消息的顺序进行有序的消费,如果分区的数量发生变化,那么有序性就得不到保证。在创建主题时,最好能确定好分区数,这样也可以省去后期增加分区所带来的多余操作。尤其对于与 key 高关联的应用,在创建主题时可以适当地多创建一些分区,以满足未来的需求。

系统可用性

分区数的多少还会影响系统的可用性。Kafka 通过多副本机制来实现集群的高可用和高可靠,每个分区都会有一至多个副本,每个副本分别存在于不同的 broker 节点上,并且只有 leader 副本对外提供服务。在K afka 集群的内部,所有的副本都采用自动化的方式进行管理,并确保所有副本中的数据都能保持一定程度上的同步。当 broker 发生故障时,leader 副本所属宿主的 broker 节点上的所有分区将暂时处于不可用的状态,此时 Kafka 会自动在其他的 follower 副本中选举出新的 leader 用于接收外部客户端的请求,整个过程由 Kafka 控制器负责完成。分区在进行 leader 角色切换的过程中会变得不可用,不过对于单个分区来说这个过程非常短暂,对用户而言可以忽略不计。如果集群中的某个 broker 节点宕机,那么就会有大量的分区需要同时进行 leader 角色切换,这个切换的过程会耗费一笔可观的时间,并且在这个时间窗口内这些分区也会变得不可用。

分区数越多也会让 Kafka 的正常启动和关闭的耗时变得越长,与此同时,主题的分区数越多不仅会增加日志清理的耗时,而且在被删除时也会耗费更多的时间。

参考文档

  • 《深入理解 Kafka:核心设计与实践原理》—— 朱忠华

往期文章