kafka调优参数设置

下面将以Kafka集群设计的各方面参数进行说明:
broker端口参数
topic级别参数
GC配置参数
JVM参数
OS参数

broker端参数
Kafka目前尚不支持动态参数修改,也就是说,如果修改了参数,需要重新启动对应broker服务器。

  • broker.id:kafka使用唯一的一个整数来标识broker。该参数默认值是-1,如果不指定,kafka会自动生成一个唯一值。
  • log.dirs:非常重要的参数,kafka持久化消息的目录,该参数可以设置多个目录,用逗号分隔,这样kafka会将负载均匀地分配到多个目录下。如果每个目录都在不同的磁盘上,那么还能提升整体写消息的吞吐量。默认情况下是/tmp/kafka-logs。
  • zookeeper.connect:此参数没有默认值,必须指定,该参数可以是一个csv列表,如果使用一套zookeeper管理多个kafka集群,则zookeeper的chroot必须指定。
  • listeners:broker监听的csv列表,格式是[协议]://[主机名]:[端口],[协议]://[主机名]:[端口]。该参数用于客户端连接broker使用。如果不指定,默认绑定网卡;如果主机名是0.0.0.0,则表示绑定所有网卡。Kafka当前支持的协议类型包括:PLAINTEXT、SSL以及SASL_SSL等。
  • advertised.listeners:和listeners类似,该参数也是用于发布给client的监听器,不过该参数主要用于IaaS环境,比如云上的机器通常都配有多块网卡(私网网卡和公网网卡)。对于这种机器,用户可以设置该参数绑定公网IP供外部client使用,然后配置上面的listeners来绑定私网IP供broker之间通讯。当然不配置也是可以的,但是云上的机器一般绑定的都是私网网卡,可能会出现客户端无法访问数据问题。
  • unclean.leader.election.enable:是否开启unclean leader选举。何为unclean leader选举?ISR中所有副本都有资格随时成为新的leader,但若ISR变空而此时leader又宕机了,kafka会如何选举新的leader呢?为了不影响kafka的服务,该参数默认为false,即表明如果发生这种情况,Kafka不允许从剩下存活的非ISR中选举一个leader。因为如果允许,这样做必然可以让Kafka继续提供服务,但会造成数据丢失,因此该参数默认值为false。
  • delete.topic.enable:是否允许kafka删除topic。默认情况下,Kafka集群允许用户删除topic及其数据。
  • log.retention.{hours|minutes|ms}:这组参数控制了消息数据的存留时间。如果同时设置,优先选取ms的设置,minutes次之,hours最后。Kafka会根据日志文件的最后修改时间(last modified time)进行判断。
  • log.retention.bytes:上面的参数是时间维度,这个参数就是空间维度。它控制着Kafka集群需要为每个消息日志保存多大的数据。对于超过该参数的分区日志而言,Kafka会自动清理该分区的过期日志段文件。该参数默认值为-1,表示kafka永远不会根据消息日志文件总大小来删除日志。
  • min.insync.replicas:该参数实际是和product的acks参数配合使用的。它指定了broker端必须成功响应client消息发送的最小副本数。如果broker段无法满足,则client的消息并不会被认为是成功的。它与product的acks配置使用可以令kafka集群达到最高等级的消息持久化。
  • num.network.threads:控制broker在后台处理来自网络请求的线程数,默认是3。该参数只是转发请求(转发给其他线程处理),并不会对其进行处理。在生产环节中,应该实时监控NetworkProcessorAvgIdlePercent JMX指标,如果该指标持续低于0.3,则应该增加该参数的值。
  • num.io.threads:该参数控制broker实际处理网络请求的线程数,默认是8。即Kafka创建8个线程,采用轮询的方式监听转发过来的网络请求并进行实时处理。如果RequestHandlerAvgIdlePercent指标持续低于0.3,则应该增加该参数的值。
  • message.max.bytes:Kafka broker能够接受的最大消息数,默认值是977KB。

topic级别参数
Topic级别参数是指覆盖broker端全局参数。每个不同的topic都可以设置自己的参数值。通常topic级别参数可以在创建topic时,使用—config key=value进行配置,多个参数用逗号进行分隔

  • delete.retention.ms:每个topic可以配置自己的日志留存时间以覆盖全局默认值。
  • max.message.bytes:覆盖全局的message.max.bytes,即为每个topic指定不同的最大消息大小。
  • retention.bytes:覆盖全局的log.retention.bytes,每个topic设置不同的日志留存大小。
  • retention.ms:日志文件保存的分钟数。数据存储的最大时间超过这个时间会根据cleanup.policy策略处理数据。
  • cleanup.policy:过期或达到日志上限的清理策略(delete:删除;compact:压缩)默认值为delete。
  • compression.type:指定给该topic的压缩类型(uncompressed、snappy、lz4、gzip、producer),默认值为producer。
  • file.delete.delay.ms:从文件系统中删除前的等待时间(默认60000)。
  • flush.message:在消息刷盘前,日志分区收集的消息数(默认值为MAX_VALUE)。
  • flush.ms:消息在刷盘前,保存在内存中的最长时间,单位ms(默认值MAX_VALUE)。
  • index.interval.bytes:当执行fetch操作后,需要一定的空间来扫描最近的offset大小。设置越大,扫描速度更快,但更耗内存,一般不用设置此参数(默认为4096)。
  • min.cleanable.dirty.ratio:日志清理的频率控制,越大清理越高效(默认值为0.5)。
  • segment.bytes:topic文件是以segment文件进行存储的,该参数控制segment文件的大小,默认值为1073741824(10G)。
  • segment.index.bytes:对于segment索引文件的大小限制,默认为10M。

OS参数

  • 文件描述符限制:Kafka会频繁地创建并修改文件系统中的文件,这包括消息的日志文件、索引文件及各种元数据管理文件等。因此如果一个broker上面有很多topic的分区,那么这个broker势必会打开很多个文件—大致约等于分区数 * (分区总大小/日志段大小) * 3。打开方式:ulimit -n 100000
  • Socket缓存区大小:这里指的是OS级别的Socket缓冲区大小,而非Kafka自己提供的Socket缓存区参数。事实上,Kafka自己的参数将其设置为64KB,对于普通的内网环境是足够的。如果是做远距离的数据传输,那么建议将OS级别的Socket缓冲区调大,比如增加到128KB,甚至更大。
  • 最好使用Ext4活XFS文件系统:其实Kafka操作的都是普通文件,并没有依赖于特定的文件系统,但依然推荐Ext4活XFS文件系统,特别是XFS通常有更好的性能。
  • 关闭swap:其实这是很多使用磁盘的应用程序的常规调优手段,具体命令为sysctl vm.swappiness = <一个较小的数>,即大幅度降低对swap空间的使用,以免极大地拉低性能。
  • 设置更长的flush时间:Kafka依赖OS页缓存的“刷盘”功能实现真正写入无力磁盘,默认的刷盘间隔是5s。通常情况下,这个间隔时间太短了,适当增加该值可以在很大程度上提升OS物理写入的性能。LinkedIn公司就将该值设置为2min以增加整体的物理写入吞吐量。

推荐阅读更多精彩内容