Kafka官方说明不是太详细,但网上也有很多参考,现还是将自己在CentOS7.6上架设生产环境的笔记记录下。同时由于Kafka的版本也在不断的升级,有些参数也许有变化,这里也将持续更新,如有错误还望指出。

调优

网络及swappiness

# vi /etc/sysctl.d/99-kafka.conf

# swap
vm.swappiness = 1
# dirty page
vm.dirty_background_ratio = 5
vm.dirty_ratio = 70
# tcp socket
net.core.rmem_default = 4194304
net.core.wmem_default = 4194304
# tcp socket
net.ipv4_tcp_rmem = 4096 65536 4194304
net.ipv4_tcp_wmem = 4096 65536 4194304
# other network
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_max_syn_backlog = 5120
net.core.netdev_max_backlog = 100000

修改系统最大文件和进程打开数

之前配置好kafka后,运行一段时间会报打开的文件太多,日志中具体发现如下记录

...
Caused by: java.io.IOException: Too many open files
...

通过命令可以查看当前系统中对最大文件打开数的设置,默认是1024,运行命令为'ulimit -a'(root用户)

修改系统环境变量

临时修改
# ulimit -n 65535
# ulimit -u 65535
永久修改
  • /etc/security/limits.conf文件中添加如下
# vim /etc/security/limits.conf
...
# Add following items at end
*         -      nofile    65535
*         -      nproc    65535
  • /etc/pam.d/su文件中添加如下
#vim /etc/pam.d/login

...
session    required    pam_limit.so

修改完成中重启生效,对于/etc/security/limits.conf文件的详细说明请见我的另外一篇笔记https://blog.51cto.com/huanghai/2437446

topic管理

通过kafka自带工具实现topic的管理,主要依靠kafka-topic.sh工具实现

列出主题

> kafka-topics.sh --bootstrap-server <kafka_host1>:9092,<kafka_host2>:9092,... --list

删除主题

> kafka-topics.sh --bootstrap-server <kafka_host1>:9092,<kafka_host2>:9092,... --delete --topic <topic_name>

说明: 1.如果Kafka服务配置了delete.topic.enable=true,直接通过命令行删除,未能删除Topic则可以通过zookeeper-client来进行删除。以下是单独使用zookeeper的二进制程序包的说明,并且已经进入bin目录。

# 进入zookeeper命令行客户端
> zkCli.sh -server <zkhost1:2181>[,<zkhost:2181>,...]
# 执行删除topic的操作
] deleteall /brokers/topics/<topic_name> 

2.如果Kafka服务未配置delete.topic.enable=false,直接通过delete命令删除topic,删除时只会将topic标记为“marked for deletion”,然后通过zookeeper-client进行删除是不会删除topic的data.log数据目录的,需要将相应的broker服务器上的log目录下相应的topic目录删除。

参数replica.fetch.max.bytes说明

设置了多个副本的kafka集群,存在副本间的同步问题,会有replica因为不能同步成功而掉线,最终topic的可用isr只剩下一个。查看log4j.properties(log4j.logger.kafka默认TRACE),有如下:

TRACE Did not finish writing, registering for write again on connection /192.168.1.238:46389 (kafka.network.Processor)

这条日志表明broker一直在发送数据,然后失败重试。kafka的配置文件中,replica.fetch.max.bytes默认值是1048576(1MiB),在短消息的应用场景下是没有问题的,但是我们的消息长度比较大,经常有大于1MiB的消息,虽然在topic中定义了max.message.bytes=52428700,即50MiB,但是对于broker,replica.fetch.max.bytes是不会随着topic的max.message.bytes变大而自动更新的,这样就导致一个问题,一旦消息的长度大于1M,而配置文件中没有定义 replica.fetch.max.bytes,就会导致replica之间数据同步失败。因此,我自己是将配置中max.message.bytes赋给replica.fetch.max.bytes。 另外,在apache上相关的issue也有类似的讨论, https://issues.apache.org/jira/browse/KAFKA-1756

参数log.retention.bytes说明

kafka原文解释: The maximum size of the log before deleting it 说的不是很清楚,根据个人使用踩坑,以及多次查找,终于在cloudera的一个历史发行版中找到了说明: The amount of data to retain in the log for each topicpartition. By default, log size is unlimited. 原文链接https://docs.cloudera.com/HDPDocuments/HDP2/HDP-2.6.5/bk_kafka-component-guide/bk_kafka-component-guide.pdf, 同时经过测试确实如上所说,此参数限制的是每个主题(topic)的每个分区(partition)的大小。 看到此处感觉还是挺恼火的,kafka毛刺问题真不是吹的,在不能预知主题的大小的情况下这个参数真不好确定,但调整的手段还是有的,就是要在跟踪kafka运行的基础上,调整数据的分布,工具就是kafka自带的kafka-reassign-partitions.sh。