如何为Kafka集群确定合适的分区数量以及分区过多带来的弊端,针对这个问题,本文详细介绍了相应的分析和解决方法,希望能帮助更多想要解决这个问题的小伙伴找到更简单更容易的方法。
卡夫卡高吞吐量的原因之一是主题中的消息通过分区保存到卡夫卡集群中的不同代理。卡夫卡的生产者和消费者都可以在主题中并发操作分区,所以分区是卡夫卡并行性调优的最小单位。
理论上,如果有更多的主题分区,理论上整个集群的吞吐量会更大。
但是,在实际生产中,卡夫卡话题的分区越多越好,这是真的吗?显然不是!
过多的分区会有以下缺点:
一、客户端/服务器端需要使用的内存就越多
在Kafka0.8.2之后,客户端生成器中有一个参数batch.size,默认为16KB。它为每个分区缓存消息。当数据累积到一定的大小或足够的时间时,累积的消息将从缓存中删除并发送到代理节点。此功能旨在提高性能,但随着分区数量的增加,这部分缓存将需要更多内存。
同时,消费者在消费消息时占用的内存和为获得更高吞吐量性能而打开的消费者线程数量也会随着分区数量的增加而增加。例如,如果有10,000个分区,并且消费者线程的数量应该与分区的数量相匹配(这在大多数情况下是最佳的消费吞吐量配置),那么将在消费者客户端中创建10,000个线程,然后在消费者客户端中创建10,000个线程,并且将创建大约10,000个Socket来获取分区数据。线程的开销成本显然不容小觑!
此外,服务器端开销也不小。如果你阅读卡夫卡的源代码,你会发现服务器端的很多组件都在内存中维护分区级的缓存,比如控制器、FetcherManager等。因此分区越多,该缓存的成本就越大。二、文件句柄的开销
在Kafka的代理中,每个分区对应于磁盘文件系统的一个目录。在Kafka的数据日志文件目录中,两个文件,一个索引文件和一个数据文件被分配给每个日志数据段。在kafka的当前版本中,每个代理将为每个日志段文件打开一个索引文件句柄和一个数据文件句柄。因此,随着分区的增加,需要保持打开的文件句柄数量也会增加,最终可能会超过底层操作系统配置的文件句柄限制。三、越多的分区可能增加端对端的延迟
Kafka端到端延迟定义为生产者发布消息到消费者收到消息所需的时间,即消费者收到消息的时间减去生产者发布消息的时间。
Kafka只会在消息提交后才会向消费者公开消息。例如,在同步所有同步副本列表之前,该消息不会公开。因此,花在同步复制上的时间将是卡夫卡端到端延迟中最重要的部分。默认情况下,当每个代理从其他代理节点复制数据时,代理节点将只为此作业分配一个线程,该线程需要完成代理的所有分区数据的复制。
请注意,上述问题可以通过增加kafka集群来缓解。例如,如果在一个代理节点和10个代理节点中放置1000个分区领导者,则它们之间的延迟是不同的。在10个代理节点的集群中,每个代理节点平均需要处理100个分区的数据复制。此时,端到端延迟将从几十毫秒变为几毫秒。
根据经验,如果你非常关心消息延迟,那么限制每个代理节点的分区数量是一个好主意:对于b代理节点和复制因子为R的kafka集群,整个kafka集群的分区数量不应该超过100*b*r,即单个分区的leader数量不应该超过100。四、降低高可用性
Kafka通过多副本复制技术实现了Kafka集群的高可用性和稳定性。每个分区都有多个数据副本,每个副本都存在于不同的代理中。在的所有数据副本中,一个数据副本是领导者,其他数据副本是追随者。
在Kafka集群中,所有数据副本都以自动化方式进行管理,所有数据副本的数据保持同步。无论生产者还是消费者对分区的请求,都是由leader的数据副本所在的代理处理的。当经纪人失败时,领导者的数据副本存储在经纪人办公室。
有partition将会变得暂时不可用。Kafka将会自动在其它数据副本中选择出一个leader,用于接收客户端的请求。这个过程由Kafka controller节点broker自动完成,主要是从Zookeeper读取和修改受影响partition的一些元数据信息。
在通常情况下,当一个broker有计划地停止服务时,那么controller会在服务停止之前,将该broker上的所有leader一个个地移走。由于单个leader的移动时间大约只需要花费几毫秒,因此从客户层面看,有计划的服务停机只会导致系统在很小时间窗口中不可用。(注:在有计划地停机时,系统每一个时间窗口只会转移一个leader,其他leader皆处于可用状态。)
然而,当broker非计划地停止服务时(例如,kill -9方式),系统的不可用时间窗口将会与受影响的partition数量有关。假如,一个2节点的kafka集群中存在2000个partition,每个partition拥有2个数据副本。当其中一个broker非计划地宕机,所有1000个partition同时变得不可用。假设每一个partition恢复时间是5ms,那么1000个partition的恢复时间将会花费5秒钟。因此,在这种情况下,用户将会观察到系统存在5秒钟的不可用时间窗口。
总而言之,通常情况下Kafka集群中越多的partition会带来越高的吞吐量。但是,如果Kafka集群中partition总量过大或者单个broker节点partition过多,都可能会对系统的可用性和消息延迟带来潜在的负面影响,需要引起我们的重视。
在partition级别上达到均衡负载是实现吞吐量的关键,合适的partition数量可以达到高度并行读写和负载均衡的目的,需要根据每个分区的生产者和消费者的目标吞吐量进行估计。
可以遵循一定的步骤来确定分区数:根据某个topic日常"接收"的数据量等经验确定分区的初始值,然后测试这个topic的producer吞吐量和consumer吞吐量。假设它们的值分别是Tp和Tc,单位可以是MB/s。然后假设总的目标吞吐量是Tt,那么numPartitions = Tt / max(Tp, Tc)
关于如何为Kafka集群确定合适的分区数以及分区数过多带来的弊端问题的解答就分享到这里了,希望
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/146808.html