影响kafka性能的配置
影响kafka性能的配置
暖海砬 发表于8个月前
影响kafka性能的配置
  • 发表于 8个月前
  • 阅读 9
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

总结一下Kafka本身可能会对性能产生影响的配置项。


Broker

num.network.threads:3

用于接收并处理网络请求的线程数,默认为3。其内部实现是采用Selector模型。启动一个线程作为Acceptor来负责建立连接,再配合启动num.network.threads个线程来轮流负责从Sockets里读取请求,一般无需改动,除非上下游并发请求量过大。

num.partitions:1

Partition的数量选取也会直接影响到Kafka集群的吞吐性能。例如我写过MapReduce任务从Kafka中读取数据,每个Partition对应一个Mapper去消费数据,如果Partition数量太少,则任务会因为Mapper数不足而非常慢。此外,当Partition数量相对于流入流出的数据量显得较少,或由于业务逻辑和Partition数量没有匹配好造成个别Partition读写数据量大,大量的读写请求集中落在一台或几台机器上时,很容易就会打满NIC的全部流量。不难想象这时不仅这一个Partition的读写会出现性能瓶颈,同Broker上的其他Partition或服务都会陷入一个网络资源匮乏的情况。

queued.max.requests:500

这个参数是指定用于缓存网络请求的队列的最大容量,这个队列达到上限之后将不再接收新请求。一般不会成为瓶颈点,除非I/O性能太差,这时需要配合num.io.threads等配置一同进行调整。

 

Replica相关配置:

replica.lag.time.max.ms:10000replica.lag.max.messages:4000num.replica.fetchers:1

上篇文章已经简单介绍过上两项配置的含义,这里不再重复,重点说一下第三项配置。对于任意(Broker, Leader)元组,都会有replication.factor-1个Broker作为Replica,在Replica上会启动若干Fetch线程把对应的数据同步到本地,而num.replica.fetchers这个参数是用来控制Fetch线程的数量。

一般来说如果发现Partition的ISR当中只有自己一个Partition,且长时间没有新的Replica增加进来时,就可以考虑适当的增大这个参数加快复制进度。其内部实现上,每个Fetch就对应了一个SimpleConsumer,对于任意一台其他机器上需要Catch-up的Leader,会创建num.replica.fetchers个SimpleConsumer来拉取Log。

当初刚知道这块设计的时候还蛮疑惑的,在Kafka文档开篇的时候就郑重介绍过,同一个ConsumerGroup内的Consumer和Partition在同一时间内必须保证是一对一的消费关系,而这么简单地增加SimpleConsumer就可以提高效率又是什么原因呢?

查看源码,在AbstractFetcherThread.scala里可以看到,Fetch启动的多线程其实就是一个个的SimpleConsumer。

首先,getFetcherId()利用numFetcher来控制FetchId的范围,进而控制Consumer数量。partitionsPerFetcher结构则是一个从Partition到Partition上启动的Fetchers的Mapping。

上面为每个Partition启动的多个Fetcher(也就是SimpleConsumer)之间通过partitionMap: mutable.HashMap[TopicAndPartition, Long]来共享offset,达到并行Fetch数据的目的。因此,通过共享offset既保证了同一时间内Consumer和Partition之间的一对一关系,又允许我们通过增多Fetch线程来提高效率。

default.replication.factor:1

这个参数指新创建一个topic时,默认的Replica数量。当Producer中的 acks!=0 && acks!=1时,Replica的大小可能会导致在Produce数据时的性能表现有很大不同。Replica过少会影响数据的可用性,太多则会白白浪费存储资源,一般建议在2~3为宜。

fetch.purgatory.purge.interval.requests:1000producer.purgatory.purge.interval.requests:1000

首先让我先来介绍一下这个“炼狱”究竟是用来做什么用的。Broker的一项主要工作就是接收并处理网络上发来的Request。这些Request其中有一些是可以立即答复的,那很自然这些Request会被直接回复。另外还有一部分是没办法或者Request自发的要求延时答复(例如发送和接收的Batch),Broker会把这种Request放入Paurgatory当中,同时每一个加入Purgatory当中的Request还会额外的加入到两个监控对队列:

  • WatcherFor队列:用于检查Request是否被满足。

  • DelayedQueue队列:用于检测Request是否超时。

Request最终的状态只有一个,就是Complete。请求被满足和超时最终都会被统一的认为是Complete。

目前版本的Purgatory设计上是存在一定缺陷的。Request状态转变为Complete后,并没能立即从Purgatory中移除,而是继续占用资源,因此占用内存累积最终会引发OOM。这种情况一般只会在topic流量较少的情况下触发。更详细的资料可以查阅扩展阅读,在此不做展开。

在实际使用中我也是踩了这个坑过来的,当时的情况是集群新上了一个topic,初期该topic数据很少(Low volume topic),导致那段时间在凌晨3,4点左右会随机有Broker因为OOM挂掉。定位原因后把*.purgatory.purge.interval.requests的配置调整小至100就解决了这个问题。

 

原文连接:http://blog.csdn.net/stark_summer/article/details/50203133

共有 人打赏支持
粉丝 0
博文 10
码字总数 2222
×
暖海砬
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: