Kafka 核心技术与实战
Kafka的基本使用
08 | 最最最重要的集群参数配置(下)
Topic 级别参数
如果同时设置了 Topic 级别参数和全局 Broker 参数,Topic 级别参数会覆盖全局 Broker 参数的值,而每个 Topic 都能设置自己的参数值,这就是所谓的 Topic 级别参数。
保存消息方面:
- retention.ms:规定了该 Topic 消息被保存的时长。默认是 7 天,即该 Topic 只保存最近 7 天的消息。一旦设置了这个值,它会覆盖掉 Broker 端的全局参数值。
- retention.bytes:规定了要为该 Topic 预留多大的磁盘空间。和全局参数作用相似,这个值通常在多租户的 Kafka 集群中会有用武之地。当前默认值是 -1,表示可以无限使用磁盘空间。
- max.message.bytes:决定了 Kafka Broker 能够正常接收该 Topic 的最大消息大小。
Topic 级别参数的设置有两种方式:
- 创建 Topic 时进行设置
- 修改 Topic 时设置
假设部门需要将交易数据发送到 Kafka 进行处理,需要保存最近半年的交易数据,同时这些数据很大,通常都有几 MB,但一般不会超过 5MB。用以下命令来创建 Topic:
bin/kafka-topics.sh --bootstrap-server localhost:9092
--create --topic transaction
--partitions 1 --replication-factor 1
--config retention.ms=15552000000
--config max.message.bytes=5242880
使用 kafka-configs 命令来修改 Topic 级别参数:
bin/kafka-configs.sh --zookeeper localhost:2181
--entity-type topics --entity-name transaction
--alter --add-config max.message.bytes=10485760
建议最好始终坚持使用第二种方式来设置,未来 Kafka 社区很有可能统一使用 kafka-configs 脚本来调整 Topic 级别参数。
JVM 参数
只需要设置下面这两个环境变量即可:
-
KAFKA_HEAP_OPTS:指定堆大小
(建议设置成 6GB)
。 -
KAFKA_JVM_PERFORMANCE_OPTS:指定 GC 参数
(建议设置成 G1 收集器)
。
可以这样启动 Kafka Broker,即在启动 Kafka Broker 之前,先设置上这两个环境变量:
$> export KAFKA_HEAP_OPTS=--Xms6g --Xmx6g
$> export KAFKA_JVM_PERFORMANCE_OPTS= -server -XX:+UseG1GC
-XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35
-XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true
$> bin/kafka-server-start.sh config/server.properties
操作系统参数
通常情况下,Kafka 并不需要设置太多的 OS 参数,但有些因素最好还是关注一下,比如下面这几个:
- 文件描述符
- 限制文件系统类型
- Swappiness
- 提交时间
文件描述符限制:ulimit -n
设置这个参数一点都不重要,但不设置的话后果很严重,比如会经常看到 “Too many open files” 的错误。
文件系统类型
指的是如 ext3、ext4 或 XFS 这样的日志型文件系统。根据官网的测试报告,XFS 的性能要强于 ext4,所以
生产环境最好还是使用 XFS
。
swap 的调优
设置成一个较小的值,但不要设置为0。因为一旦设置成 0,当物理内存耗尽时,操作系统会触发
OOM killer
这个组件,它会随机挑选一个进程然后 kill 掉,即根本不给用户任何的预警。但如果设置成一个比较小的值,当开始使用 swap 空间时,至少能够观测到 Broker 性能开始出现急剧下降,从而拥有进一步调优和诊断问题的时间。基于这个考虑,建议将 swappniess 配置成一个接近 0 但不为 0 的值,比如 1。
提交时间
向 Kafka 发送数据并不是真要等数据被写入磁盘才会认为成功,而是只要数据被写入到操作系统的页缓存(Page Cache)上就可以了,随后操作系统根据 LRU 算法会定期将页缓存上的“脏”数据落盘到物理磁盘上。这个定期就是由提交时间来确定的,默认是 5 秒。
一般情况下会认为这个时间太频繁了,可以适当地增加提交间隔来降低物理磁盘的写操作。
如果在页缓存中的数据在写入到磁盘前机器宕机了,数据就丢失了。但
鉴于 Kafka 在软件层面已经提供了多副本的冗余机制,因此稍微拉大提交间隔去换取性能还是一个合理的做法。