Kafka 核心常用配置项
- [1、Broker 端配置](#1、Broker 端配置)
-
- [1.1、Broker 配置存储信息](#1.1、Broker 配置存储信息)
- [1.2、Broker 配置连接信息](#1.2、Broker 配置连接信息)
- [1.3、Broker 配置 Topic 管理信息](#1.3、Broker 配置 Topic 管理信息)
- [1.4、Broker 配置 数据留存 管理信息](#1.4、Broker 配置 数据留存 管理信息)
- [2、Topic 级别参数](#2、Topic 级别参数)
- [3、JVM 参数](#3、JVM 参数)
- 4、操作系统参数
以下参数都是那些要修改默认值的参数,因为它们的默认值不适合一般的生产环境。
1、Broker 端配置
1.1、Broker 配置存储信息
首先 Broker 是需要配置存储信息的,即 Broker 使用哪些磁盘。那么针对存储信息的重要参数有以下这么几个:
- log.dirs:这是非常重要的参数,指定了Broker需要使用的若干个文件目录路径。要知道这个参数是没有默认值的,这说明它必须由你亲自指定。
- log.dir:注意这是dir,结尾没有s,说明它只能表示单个路径,它是补充上一个参数用的。
这两个参数应该怎么设置呢?很简单,你只要设置 log.dirs,即第一个参数就好了,不要设置 log.dir。而且更重要的是,在线上生产环境中一定要为 log.dirs 配置多个路径,具体格式是一个 CSV 格式,也就是用逗号分隔的多个路径,比如/home/kafka1,/home/kafka2,/home/kafka3这样。如果有条件的话你最好保证这些目录挂载到不同的物理磁盘上。这样做有两个好处:
- 提升读写性能:比起单块磁盘,多块物理磁盘同时读写数据有更高的吞吐量。
- 能够实现故障转移:即 Failover。这是 Kafka 1.1 版本新引入的强大功能。要知道在以前,只要 Kafka Broker 使用的任何一块磁盘挂掉了,整个 Broker 进程都会关闭。但是自 1.1 开始,这种情况被修正了,坏掉的磁盘上的数据会自动地转移到其他正常的磁盘上,而且 Broker 还能正常工作。没有这种 Failover 的话,我们只能依靠 RAID 来提供保障。
1.2、Broker 配置连接信息
这组参数是与 Broker 连接相关的,即客户端程序或其他 Broker 如何与该 Broker 进行通信的设置。有以下三个参数:
- listeners:学名叫监听器,其实就是告诉外部连接者要通过什么协议访问指定主机名和端口开放的 Kafka 服务。
- advertised.listeners:和listeners相比多了个advertised。Advertised的含义表示宣称的、公布的,就是说这组监听器是Broker用于对外发布的。
- host.name/port:这两个参数是过期的,不要为它们指定值。
具体说说监听器的概念,从构成上来说,它是若干个逗号分隔的三元组,每个三元组的格式为 <协议名称,主机名,端口号>。这里的协议名称可能是标准的名字,比如 PLAINTEXT 表示明文传输、SSL 表示使用 SSL 或 TLS 加密传输等;也可能是你自己定义的协议名字,比如 SSL: //localhost:9092。
1.3、Broker 配置 Topic 管理信息
- auto.create.topics.enable:是否允许自动创建 Topic。
auto.create.topics.enable 参数我建议最好设置成 false,即不允许自动创建 Topic。否则线上环境可能有很多名字稀奇古怪的 Topic,某主题出现阻塞等问题时,无法及时通知负责人,我想大概都是因为该参数被设置成了 true 的缘故。
特别是对于那些大公司而言,每个部门被分配的 Topic 应该由运维严格把控,决不能允许自行创建任何 Topic。
1.4、Broker 配置 数据留存 管理信息
- log.retention.{hours|minutes|ms}:这是个"三兄弟",都是控制一条消息数据被保存多长时间。从优先级上来说 ms 设置最高、minutes 次之、hours 最低。
- log.retention.bytes:这是指定 Broker 为消息保存的总磁盘容量大小。
- message.max.bytes:控制 Broker 能够接收的最大消息大小。
第一个参数 log.retention.{hours|minutes|ms},虽然 ms 设置有最高的优先级,但是通常情况下我们还是设置 hours 级别的多一些,比如 log.retention.hours=168 表示默认保存 7 天的数据,自动删除 7 天前的数据。很多公司把 Kafka 当作存储来使用,那么这个值就要相应地调大。
第二个参数 log.retention.bytes。这个值默认是 - 1,表明你想在这台 Broker 上保存多少数据都可以,至少在容量方面 Broker 绝对为你开绿灯,不会做任何阻拦。这个参数真正发挥作用的场景其实是在云上构建多租户的 Kafka 集群:设想你要做一个云上的 Kafka 服务,每个租户只能使用 100GB 的磁盘空间,为了避免有个 "恶意" 租户使用过多的磁盘空间,设置这个参数就显得至关重要了。
第三个 message.max.bytes。这个参数默认的 1000012 字节,还不到 1MB。实际场景中突破 1MB 的消息都是屡见不鲜的,因此在线上环境中设置一个比较大的值还是比较保险的做法。毕竟它只是一个标尺而已,仅仅衡量 Broker 能够处理的最大消息大小,即使设置大一点也不会耗费什么磁盘空间的。
2、Topic 级别参数
正确设置以下参数是搭建高性能 Kafka 集群的关键因素。
2.1、级别问题
说起 Topic 级别的参数,你可能会有这样的疑问:如果同时设置了 Topic 级别参数和全局 Broker 参数,到底听谁的呢?哪个说了算呢?答案就是 Topic 级别参数会覆盖全局 Broker 参数的值,而每个 Topic 都能设置自己的参数值,这就是所谓的 Topic 级别参数。
举个例子说明一下,上面提到了消息数据的留存时间参数,在实际生产环境中,如果为所有 Topic 的数据都保存相当长的时间,这样做既不高效也无必要。更适当的做法是允许不同部门的 Topic 根据自身业务需要,设置自己的留存时间。如果只能设置全局 Broker 参数,那么势必要提取所有业务留存时间的最大值作为全局参数值,此时设置 Topic 级别参数把它覆盖,就是一个不错的选择。
2.2、三个核心配置项
1.保存消息的维度:
- retention.ms:规定了该 Topic 消息被保存的时长。默认是 7 天,即该 Topic 只保存最近 7 天的消息。一旦设置了这个值,它会覆盖掉 Broker 端的全局参数值。
- retention.bytes:规定了要为该 Topic 预留多大的磁盘空间。和全局参数作用相似,这个值通常在多租户的 Kafka 集群中会有用武之地。当前默认值是 - 1,表示可以无限使用磁盘空间。
2.处理消息的维度:
- max.message.bytes:它决定了 Kafka Broker 能够正常接收该 Topic 的最大消息大小。我知道目前在很多公司都把 Kafka 作为一个基础架构组件来运行,上面跑了很多的业务数据。如果在全局层面上,我们不好给出一个合适的最大消息值,那么不同业务部门能够自行设定这个 Topic 级别参数就显得非常必要了。在实际场景中,这种用法也确实是非常常见的。
3、JVM 参数
JVM参数对Kafka集群的影响:Kafka服务器端代码是用Scala语言编写的,但终归还是编译成Class文件在JVM上运行。
- 堆大小,通用建议:将 JVM 堆大小设置成 6GB,这是目前业界比较公认的一个合理值。Heap Size 是 1GB 来跑 Kafka,说实话默认的 1GB 有点小,毕竟 Kafka Broker 在与客户端进行交互时会在 JVM 堆上创建大量的 ByteBuffer 实例,Heap Size 不能太小。
4、操作系统参数
Flush 落盘时间。
- 向 Kafka 发送数据并不是真要等数据被写入磁盘才会认为成功,而是只要数据被写入到操作系统的页缓存(Page Cache)上就可以了,随后操作系统根据 LRU 算法会定期将页缓存上的"脏"数据落盘到物理磁盘上。
- 这个定期就是由提交时间来确定的,默认是 5 秒。
- 一般情况下 5 秒这个时间太频繁了,可以适当地增加提交间隔来降低物理磁盘的写操作。当然你可能会有这样的疑问:如果在页缓存中的数据在写入到磁盘前机器宕机了,那岂不是数据就丢失了。的确,这种情况数据确实就丢失了,但鉴于 Kafka 在软件层面已经提供了多副本的冗余机制,因此这里稍微拉大提交间隔去换取性能还是一个合理的做法。