《Kafka权威指南》读书笔记-操做系统调优篇html
做者:尹正杰算法
版权声明:原创做品,谢绝转载!不然将追究法律责任。api
大部分Linux发行版默认的内核调优参数配置已经可以知足大多数应用程序的运行需求,不过仍是能够经过调整一些参数来进一步提高Kafka的性能。这些参数主要与虚拟内存,网络子系统和用来存储日志片断的磁盘挂在点有关。这些参数通常配置在“/etc/sysctl.conf” 文件里,不过在对内核参数进行调整时,最好参考官方提供的操做系统文档。缓存
一.虚拟内存安全
通常来讲,Linux的虚拟内存会根据系统的工做负荷进行自动调整。咱们能够对交换分区的处理方式和内存脏页进行调整,从而让Kafka更好的处理工做负载。对于大多数依赖吞吐量的应用程序来讲,要尽可能避免内存交换。内存页和磁盘之间的交换对Kafka各方面的性能都有重大影响。kafka大量地使用系统页面缓存,若是虚拟内存被交换到磁盘,说明已经没有多余的内存能够分配该页面缓存啦。服务器
1>.把vm.swappiness的值设置的更小一点(默认值是60,推荐设置为小于10的数字,好比1。)网络
一种避免内存交换的方法是不设置任何交换分区。内存交换不是必须的 ,不过它确实可以在操做系统发生灾难性错误时提供一些帮助。进行内存交换能够防止操做系统因为内存不足而忽然终止进程。基于上述缘由,建议把vm.swappiness的值设置的更小一点,好比1.该参数指明了操做系统将如何使用交换分区,而不是把内存页从页面缓存里移除。要优先考虑减小页面缓存,而不是进行内存交换。详细操做步骤可参考个人笔记(连接在下文中能够看到)。app
2>.为何不把vm.swappiness设置为零jvm
先前,人们建议把vm.swapiness设置为0,它意味着“除非发生内存益处,不然不要进行内存交换”。直到Linux内核3.5-rcl版本发布,这个值的意义才发生了变化。这个变化被一直到其余的发行版本上,包括RedHat企业版内核2.6.32-303。在发生变化以后,0意味着“在任何状况下都不要发生交换”。因此如今建议把这个值设置为1。 性能
3>.Linux虚拟内存(swap)调优篇-“swappiness”,“vm.dirty_background_ratio”和“vm.dirty_ratio”
详情请参考:http://www.javashuo.com/article/p-npamtzcy-m.html
二.磁盘与文件系统
除了选择合适的磁盘硬件设备和使用RAID外,文件系统是性能影响的另外一个重要因素。有不少中文件系统可供选择,不过对于本地文件系统来讲,EXT4(第四代可扩展文件系统)和XFS最为常见。近来,XFS称为不少Linux发行版默认的文件系统,由于它只须要作少许的调优即就能够承担大部分的工做负荷,比EXT4具备更好的表现。EXT4也能够作得很好,但须要作更多的调优,存在较大的风险。其中包括设置设置更长的时间间隔(默认是5)一边下降刷新的频率。EXT4还引入了块分配延迟,一旦系统崩溃,更容易形成数据的丢失和文件系统损坏。XFS也使用分配延迟算法,不过比EXT4的要安全些。
XFS为Kafka提供了更好的性能,除了有文件系统提供的自动优化以外,无需额外的调优。批量写入具备更高的效率,能够提高总体的I/O吞吐量。换句话说,这种性能的提高主要影响的是Kafka的写入能力。根据官网的测试报告,使用XFS的写入时间大约是160ms,而使用Ext4大约是250ms。所以生产环境中最好使用XFS文件系统。
无论使用哪种文件系统来存储日志片断,最好要对挂在点的noatime参数进行合理的设置。文件元数据包括三个时间戳:建立时间(ctime),最后修改时间(mtime)以及最后访问时间(atime)。默认状况下,每次文件被读取后,都会更新atime,这会致使大量的磁盘读写操做,并且atime属性用处不大,除非某些应用程序想要某个文件在最后一次修改后有没有访问过(这种状况可使用retime)。Kafka用不到该属性,因此彻底能够把它禁用掉。为挂载点设置noatime参数能够防止更新atime,但不会影响ctime和mtime。
对于XFS用户而言,推荐设置largeio参数,该参数将影响stat调用返回的I/O大小。对于大数据量的磁盘写入操做而言,它可以提高必定的性能。largeio是标准的mount属性,故可以使用与nobh相同的方式设置。
咱们只须要修改“/etc/fstab”这个开机启动时会加载的文件便可,它主要时记录操做系统开机自动挂载的事情,咱们能够经过“df -h”查看磁盘挂载的状况。咱们须要修改的地方我已经标识出来啦:
三.网络
这里指的的是OS级别的Socket缓冲区大小,而非Kafka本身提供的Socket缓冲区参数。事实上,Kafka本身的参数将其设置为64KB,这对于普通的内网环境而言是足够的,由于内网环境下往返时间(round-trip time,RRT)通常都很低,不会产生过多的数据堆积在Socket缓冲区中,但对于那些跨地区的数据传输而言,仅仅增长Kafka参数就不够了,由于前者也受限于OS级别的设置。所以若是是作远距离的数据传输,那么建议将OS级别的Socket缓冲区调大,好比增长到128KB,甚至更大。
还有就是关掉没有用不到的网络服务,好比IPV6等,具体实操请参考个人笔记:http://www.javashuo.com/article/p-hewxfrui-m.html。
四.文件描述符限制优化
Kafka会频繁地建立并修改文件系统中的文件,这包括消息的日志文件,索引文件以及各类元数据管理文件等。咱们可使用ulimit进行资源管控,设置文件打开数据和用户打开进程数等等,咱们也能够编辑配置文件(/etc/security/limits.conf)并添加如下内容:(添加后推出当前终端,下一次登录服务器时就会生效!)
[root@yinzhengjie ~]# cat /etc/security/limits.conf | grep -v ^# | grep -v ^$ * soft nofile 32768 * hard nofile 1048576 * soft nproc 65536 * hard nproc unlimited * soft memlock unlimited * hard memlock unlimited [root@yinzhengjie ~]#
除了上面的参数,咱们还能够适当调大用户打开的进程数:
[root@yinzhengjie ~]# cat /etc/security/limits.d/20-nproc.conf | grep -v ^# | grep -v ^$ * soft nproc 40960 root soft nproc unlimited [root@yinzhengjie ~]#
五.JVM参数优化
鉴于Kafka broker主要使用的时堆外内存,即大量使用操做系统的页缓存,所以并不须要为JVM分配太多的内存。在实际使用中,一般broker设置不超过6GB的堆空间,我们关于kafka的JVM调优对象主要针对2个配置文件,即:“kafka-run-class.sh”和“kafka-server-start.sh”两个脚本(这两个脚本都在Apache kafka安装包解压后的bin目录下)。
1>."kafka-run-class.sh"
找到“# JMX settings” 这一行,咱们能够自定义JMX的端口,举个案例以下:
if [ -z "$KAFKA_JMX_OPTS" ]; then KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" fi
找到“# Generic jvm settings you want to add”这一行,你能够自行添加JVM的参数列表,举个案例以下:(注意,这个脚本会被kafka-server-start.sh脚本调用,所以这里配置了就最好不要在其余位置配置哟!)
# Generic jvm settings you want to add if [ -z "$KAFKA_OPTS" ]; then KAFKA_OPTS="-Xmx6g -Xms6g -XX:MetaspaceSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=85" fi
2>."kafka-server-start.sh"
咱们能够找到“export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G”这一行参数,它定义了kafka启动的堆内存大小,通常推荐不要超过6G,由于Kafka并非很吃内存,它主要吃的的是离堆内存。所以咱们须要把更多的内存留给OS。而kafka在写数据时,数据并非真正写入磁盘,而是写到页缓存中,而这些页缓存就是OS的内存空间,最终数据由操做系统负责写入磁盘。Kafka并不负责底层直接和内存进行交互。
if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then export KAFKA_HEAP_OPTS="-Xmx5G -Xms5G" fi
舒适提示,咱们这里制定了Kafka的heap内存为5G,若是你在"kafka-run-class.sh"脚本中指定了Kafka的参数时,你会发现这个脚本的配置并不会生效,缘由是咱们在使用"kafka-server-start.sh"时会调用“kafka-run-class.sh”这个脚本,即Kafka的变量被覆盖啦!所以咱们在启动时发现kafka的heap内存为6G。