集群部署最佳实践

概要

记录线上 Zookeeper 集群和 Kafka 集群部署过程,操作系统配置,以及一些参数的设置。给大家部署提供一些宝贵意见和参考。部署一个集群,按照官方社区的文档,很容易就搭建一个集群,但是为了更好的发挥集群的性能,有很多设置是可以避免产生不必要的问题,都是在惨痛的教训中产生的经验。

本文内容来自NeweggConfluent 产线上 Kafka cluster 运维经验,仅供参考。

Newegg 产线 Kafka 版本选择 Confluent 发行版本,版本对照表:

Confluent PlatformApache Kafka
5.5.x2.5.x

Docker 镜像列表:

ServiceInfo
Zookeeperconfluentinc/cp-zookeeper:5.5.1
Kafkaconfluentinc/cp-kafka:5.5.1

Zookeeper Cluster

硬件

内存至少 4GB,Zookeeper 对 swap 敏感,应当避免 swap。

集群配置

zookeeper 节点数据应该为 2n+1,n 大于 0,保持集群中超过一半节点存活。

Confluent docker 镜像参数设置是在 ENV(环境变量)中设置,以 ZOOKEEPER 开头,以_替换.

参数清单

- ZOOKEEPER_SERVER_ID=1
- ZOOKEEPER_TICK_TIME=2000
- ZOOKEEPER_CLIENT_PORT=2181
- ZOOKEEPER_INIT_LIMIT=10
- ZOOKEEPER_SYNC_LIMIT=5
- ZOOKEEPER_SERVERS=192.168.0.1:2888:3888;192.168.0.2:2888:3888;192.168.0.3:2888:3888
- ZOOKEEPER_AUTOPURGE_SNAP_RETAIN_COUNT=5
- ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL=10
- KAFKA_HEAP_OPTS=-Xmx4G -Xms4G

ZOOKEEPER_AUTOPURGE_SNAP_RETAIN_COUNT 控制快照的数量,ZOOKEEPER_AUTOPURGE_PURGE_INTERVAL 控制清除快照的时间间隔,默认不清除,这个很重要。

文件映射

Host volumeContainer volume
/opt/app/cp-zookeeper-5.5.1/data/var/lib/zookeeper/data
/opt/app/cp-zookeeper-5.5.1/log/var/lib/zookeeper/log
/etc/localtime/etc/localtime

Kafka Cluster

硬件

CPU 推荐 24 核+,内存推荐 64GB,Kafka 对堆内内存使用很谨慎,不需要将它堆内存设置超过 6GB,剩余更多的内存留给系统和 Page Cache,有助于提交读写效率。

系统参数

File Descriptors

众所周知,Kafka 严重依赖磁盘,越多的 partition 需要创建越多的文件。文件描述符限制了系统打开文件句柄数,避免系统在今后的运行中出现Too many open files

ulimit -n 1000000

临时性修改,系统重启后会失效

为了重启后同样生效,可以修改/etc/security/limits.conf,重新登录 session

* soft nofile 1000000
* hard nofile 1000000

mmap

vm.max_map_count会限制一个进程可以拥有的 VMA(虚拟内存区域)的数量,这个值应该远远大于 index 文件的数量(broker segment growth)。关于 index 文件的统计可以使用:find . -name '*index' | wc -l

临时性生效,重启后失效:

sysctl -w vm.max_map_count=262144

设置机器重启后仍然生效

echo 'vm.max_map_count=262144' >> /etc/sysctl.conf
sysctl -p

JVM

推荐的 GC(在 JDK 1.8 u5 测试)配置如下:

-Xms6g -Xmx6g -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20
-XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M
-XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80

按以上配置,如下是领英内部最繁忙集群的状态 (at peak):

  • 60 brokers
  • 50k partitions (replication factor 2)
  • 800k messages/sec in
  • 300 MBps inbound, 1 GBps + outbound

所有 broker 90%的 GC 暂停时间大约 21ms,每秒执行不到一次 young GC

集群配置

Confluent docker 镜像参数设置是在 ENV(环境变量)中设置,以 KAFKA 开头,以_替换.

参数清单

- KAFKA_BROKER_ID=0
- KAFKA_ZOOKEEPER_CONNECT=192.168.0.1:2181,192.168.0.2:2181,192.168.0.3:2181
- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.0.1:9092
- KAFKA_AUTO_CREATE_TOPICS_ENABLE=false
- KAFKA_DELETE_TOPIC_ENABLE=true
- KAFKA_SOCKET_RECEIVE_BUFFER_BYTES=102400
- KAFKA_JMX_PORT=8888
- KAFKA_JMX_HOSTNAME=192.168.0.1
- KAFKA_HEAP_OPTS=-Xms6g -Xmx6g -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80
-KAFKA_LOG4J_LOGGERS=kafka.controller=INFO,state.change.logger=INFO,kafka.producer.async.DefaultEventHandler=INFO
- KAFKA_MESSAGE_MAX_BYTES=4000000
- KAFKA_REPLICA_FETCH_MAX_BYTES=4100000
- KAFKA_CONFLUENT_SUPPORT_METRICS_ENABLE=false

KAFKA_SOCKET_RECEIVE_BUFFER_BYTES 和 KAFKA_MESSAGE_MAX_BYTES,KAFKA_REPLICA_FETCH_MAX_BYTES 非必须,需要根据真实消息的限制进行修改。但是需要谨记的是修改 MESSAGE_MAX_BYTES 切记修改 REPLICA_FETCH_MAX_BYTES。

KAFKA_CONFLUENT_SUPPORT_METRICS_ENABLE 只有在使用 Confluent docker images 的时候需要设置。避免产生一些收集指标的错误 log。

文件映射

Host volumeContainer volume
/opt/app/cp-kafka-5.5.1/data/var/lib/kafka/data
/opt/app/cp-kafka-5.5.1/log/var/log/kafka
/etc/localtime/etc/localtime

参考

  1. Running ZooKeeper in Production
  2. Running Kafka in Production