概述
本文档描述了安装Zookeeper 3.5.8和Kafka 2.4.0与部分调优的配置。
平台化的 Kafka 需要在开源的基础上做很多的工作。
1. Apache Zookeeper 3.5.8 安装与配置
1.1. 服务器硬件配置
建议 Zookeeper 的服务器最好专属(或是资源隔离的)。内存 4g 就够。磁盘由于 Zookeeper 的数据写入磁盘,强烈建议要使用 SSD。
1.2. Linux 操作系统优化
Zookeeper 的性能会很明显受到交换分区的影响。建议部署 Zookeeper 的服务器关闭交换分区功能或是通过内核参数调整,减少对于交换分区的使用。
原则上,不建议 Zookeeper 和 Kafka Broker 部署在同一台服务器,除非做好资源隔离或是机器有明显的资源富余。
1.3. 解压安装
解压apache-zookeeper-3.5.8-bin.tar.gz,并在conf目录下增加新的配置文件。
$ cd /opt $ tar zxvf apache-zookeeper-3.5.8-bin.tar.gz $ cd /opt/apache-zookeeper-3.5.8-bin/conf
1.3.1. zoo.cfg
# The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=5 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=2 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/tmp/zookeeper/data dataLogDir=/tmp/zookeeper/datalog # the port at which the clients will connect clientPort=2181 # the maximum number of client connections. # increase this if you need to handle more clients # Setting this to 0 entirely removes the limit on concurrent connections. maxClientCnxns=120 # # Be sure to read the maintenance section of the # administrator guide before turning on autopurge. # # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance # # The number of snapshots to retain in dataDir autopurge.snapRetainCount=3 # Purge task interval in hours # Set to "0" to disable auto purge feature autopurge.purgeInterval=24 ## Metrics Providers # # https://prometheus.io Metrics Exporter #metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider #metricsProvider.httpPort=7000 #metricsProvider.exportJvmInfo=true # Disable AdminServer admin.enableServer=false #server.1=zoo1:2888:3888 #server.2=zoo2:2888:3888 #server.3=zoo3:2888:3888
说明:
- tickTime配置的单位是毫秒。这个配置是 Zookeeper 的基础操作的长度。心跳或是各种超时的时长都是基于tickTime计算得出。比如会话超时设置,minSessionTimeout默认值是 2 倍tickTime,maxSessionTimeout默认值是 20 倍tickTime。
- clientPort是 Zookeeper 进程的网络监听端口,一般用端口号 2181。如果服务器有多块网卡,可以通过clientPortAddress指明 Zookeeper 进程监听的 IP 地址。可以不配置clientPortAddress,默认的是绑定所有的网卡和相应的 IP 地址。建议对于生产环境下多网卡的服务器进行配置。
- initLimit和syncLimit是分别用来配置 Zookeeper 初始化和同步(允许最大不同步)时长。也是基于tickTime计算得出。这里推荐的配置是initLimit=5,Zookeeper 最大 10 秒(5 * 2000 毫秒)完成和 leader 节点的初始化。syncLimit=2是说允许集群中的节点最长有 4 秒的不同步。如果 Zookeeper 集群节点都在一个 VLAN 下,这样的配置是足够的。如果 Zookeeper 集群要跨交换机(网络延迟相对较高),要重新评估这两项配置。
- maxClientCnxns是最大的客户连接数。对于Kafka来说,就是最大有多少 Broker 可以连到Zookeeper节点上。默认值是60。配置成0是对客户端连接无限制。强烈建议根据实际情况(比如 Kafka broker 的数量),配置成一个固定值,以防止因为太多的客户端连接从而用尽资源。
- dataDir是 Zookeeper 用来存放内存 snapshot 的路径。强烈建议dataDir要配置到 SSD 硬盘上以提升性能。如果不配置dataLogDir, 默认事务日志会写到dataDir路径下。这样会带来写 Snapshot 和写事务日志的 IO 操作竞争。这里建议,明确配置dataLogDir,把事务日志写到另外的硬盘上以减少 IO 操作竞争。
- 默认情况下,Zookeeper 不会清理 Snapshot,这样会造成硬盘上 Snapshot 文件越来越多。对于 kafka 的场景,建议打开自动清理功能。配置成autopurge.snapRetainCount=3和autopurge.purgeInterval=24。意思是每 24 小时自动执行清理 Snapshot 任务,保留最新的三份 Snapshot。
- Zookeeper 3.5.0 后引入了 admin server,默认打开。建议配置admin.enableServer=false关闭 admin server。
- 集群大小建议3或是5节点起步,一般 3 节点(允许 1 节点当机)在可用性上就足够了。以后可以实际集群压力再进行扩展。不建议一开始就上特别多节点的 Zookeeper 集群。
- 对于 Zookeeper 集群,要在dataDir目录下创建一个文件myid。文件内容就一行,是个从 1 到 255 之间的数字。对应的是zoo.cfg中的配置。格式是server.=::。leaderport用供 follower 节点来连接 leader 节点。electionport是用于集群通讯进行选主。
server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
1.3.2. zookeeper-env.sh
- 根据实际情况,修改以下的 log 目录配置ZOO_LOG_DIR和ZOO_GC_LOG_DIR。
- zookeeper-env.sh主要是配置 JVM 的 GC 为 G1GC,以及修改 heap 大小成 2g (默认是 1000m)。GC 日志主要用于诊断问题和进一步的 GC 调优,生产环境可以先不打开 GC 日志。
- JMX 可根据监控要求可以打开远程 JMX,要指明JMXPORT的端口号,或是JMXLOCALONLY=true打开本地 JMX,也可以通过配置JMXDISABLE=true关闭 JMX。
#------------------------------------------------------------------- # zookeeper-env.sh #-------------------------------------------------------------------- # Configure Log ZOO_LOG_DIR="/opt/apache-zookeeper-3.5.8-bin/logs" ZOO_LOG4J_PROP="INFO,DAILYROLLINGFILE" # Maximum Heap Size(m) ZK_SERVER_HEAP=2048 # Configure JVM GC log ZOO_GC_LOG_DIR="/opt/apache-zookeeper-3.5.8-bin/logs" SERVER_JVMFLAGS="-Xms2048m -Xmx2048m -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:+AlwaysPreTouch -Djute.maxbuffer=4194304" # Enable GC log #SERVER_JVMFLAGS="-Xms2048m -Xmx2048m -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:+AlwaysPreTouch -Djute.maxbuffer=4194304 -verbose:gc -XX:+PrintHeapAtGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M -Xloggc:$ZOO_GC_LOG_DIR/zookeeper.gc" # Configure JMX (enabled by default for local monitoring by PID) # define JMXPORT allows remote monitoring JMXDISABLE=true #JMXLOCALONLY=true #JMXPORT=10900 # Backup log GC at startup if [ "x$1" = "xstart" ]; then for f in $ZOO_GC_LOG_DIR/zookeeper.gc*; do ## Check if the glob gets expanded to existing files. ## If not, f here will be exactly the pattern above ## and the exists test will evaluate to false. if [ -e "$f" ] ; then echo "GC log files found - backing up" d=$PWD && cd $ZOO_GC_LOG_DIR && tar czf zookeeper.gc.$(date +%Y%m%d-%H%M%S).tgz zookeeper.gc* && cd $d else echo "No GC log files found" fi ## This is all we needed to know, so we can break after the first iteration break done fi
1.3.3. log4j.properties
修改conf**log4j**.properties文件,增加以下内容。用于配置 log4j 的DailyRollingFileAppender。把一天当中的日志输出到一个日志文件中。zookeeper自带的 log4j 配置是基于文件大小来滚动日志文件。
log4j.appender.DAILYROLLINGFILE=org.apache.log4j.DailyRollingFileAppender log4j.appender.DAILYROLLINGFILE.DatePattern='.'yyyy-MM-dd log4j.appender.DAILYROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file} log4j.appender.DAILYROLLINGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.DAILYROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L][%x] - %m%n
2. Apache Kafka 2.4.0 安装与配置
2.1. 服务器硬件配置
- CPU 一般不会是 Kafka 集群的瓶颈。常见的服务器 CPU 都没有问题,建议 24 核或是 32 核。
- 内存要大一些。Kafka 会使用很多的 Linux 操作系统 Cache Page。
Linux 操作系统优化
- 内核的 Cache 行为会很大程序影响 Kafka 性能。但这部分的调优需要运维监控与相应的服务器调优。重点关注以下几个内核参数。
- vm.dirty_background_ratio
- vm.dirty_ratio
- vm.dirty_expire_centisecs
2.2. 解压安装
解压kafka_2.12-2.4.0.tgz。
$ cd /opt $ tar zxvf kafka_2.12-2.4.0.tgz $ cd /opt/kafka_2.12-2.4.0
2.2.1. 新增加 kafka-server-start-tuned.sh 脚本
$ cd /opt/kafka_2.12-2.4.0/bin
脚本内容如下
#!/bin/bash #------------------------------------------------------------------- # kafka-server-start-tuned.sh #-------------------------------------------------------------------- base_dir=$(dirname $0) export LOG_DIR="/tmp/kafka/logs" export KAFKA_OPTS="-Djute.maxbuffer=4194304 -Dlog4j.rootLogger=INFO,kafkaAppender" export KAFKA_HEAP_OPTS="-Xmx6g -Xms6g -XX:+AlwaysPreTouch" export KAFKA_JVM_PERFORMANCE_OPTS="-server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -Djava.awt.headless=true" export KAFKA_GC_LOG_OPTS=" " export KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=59999" #export KAFKA_LOG4J_OPTS exec $base_dir/kafka-server-start.sh -daemon $base_dir/../config/server.properties #exec $base_dir/kafka-server-start.sh -daemon -loggc $base_dir/../config/server.properties
$ chmod +x kafka-server-start-tuned.sh
说明:
- LOG_DIR配置到相应目录。
- 通过KAFKA_HEAP_OPTS,把 Kafka Broker 进程的 heap 大小设置为 6g。Kafka 不需要配置特别大的堆内内存。
2.2.2. 修改 server.properties 文件
$ cd /opt/kafka_2.12-2.4.0/config
基础配置
请按服务器实际情况配置
- broker.id
- listeners
- advertised.listeners
- log.dirs
- zookeeper.connect
优化配置
- num.network.threads: 默认值是 3。创建 Processor 处理网络请求线程个数,建议设置为 broker 当 CPU 核心数*2,这个值太低经常出现网络空闲太低而缺失副本。
- num.io.threads: 默认值是 8。创建 KafkaRequestHandler 处理具体请求线程个数,建议设置为 broker 磁盘个数2。但磁盘如果组了 RAID 后,建议可以实际测试一下磁盘阵列的 IOPS。对于 SSD,可以配置的更大一些。但不要配置超过核心数2。
- queued.max.requests: 默认值为 500。建议配置为 4000。在网络线程停止读取新请求之前,可以排队等待 I/O 线程处理的最大请求个数。增大 queued.max.requests 能够缓存更多的请求,以撑过业务峰值。如果过大,会造成内存的浪费。
- num.replica.fetchers: 默认值 1。建议设置为 CPU 核心数/4,适当提高可以提升 CPU 利用率及 follower 同步 leader 数据当并行度。
- log.flush.scheduler.interval.ms、log.flush.interval.ms和log.flush.interval.messages: 这几个参数表示日志数据刷新到磁盘的策略,应该保持默认配置,刷盘策略让操作系统去完成,由操作系统来决定什么时候把数据刷盘;如果设置来这个参数,可能对吞吐量影响非常大;
- auto.leader.rebalance.enable: 表示是否开启 leader 自动负载均衡,默认值是true。应该把这个参数设置为false,因为自动负载均衡不可控,可能影响集群性能和稳定。但可按的集群负载平衡需要额外工作。
2.3. 其他一些 Kafka 功能级别的思考
2.3.1. 压缩
消息体的大小会对网络带宽带来压力,从吞吐量的角度考虑,建议开启压缩。需要和 Kafka producer 配合一起。
compression.type - 建议采用 lz4 或是 snappy 压缩类型,压缩可以提升 CPU 利用率同时可以减少网络传输数据量。
2.3.2. 限流
经常会出现一些突发的,不可预测的异常生产或者消费流量会对集群的 IO 等资源产生巨大压力,最终影响整个集群的稳定与性能。那么作为平台级的 Kafka,可以对用户的生产、消费、副本间数据同步进行流量限制,这个限流机制并不是为了限制用户,而是避免突发的流量影响集群的稳定和性能,给用户可以更好的服务。
2.3.3. 集群负载平衡管理
开源版本的 Kafka 在大集群的负载平衡管理上,可以通过命令行工具结合运维监控来做。也可以考虑其他相应的开源工具。