Kafka: Configure Kafka
1. Broker 配置
1.1 num.partitions
指定了主题分区数。Kafka 集群通过分区对主题进行横向扩展,当有新的 Broker 加入集群时,可以通过分区实现负载均衡。
不过,并不强制要求分区数大于 Broker 数。
在进行分区数量选择时,需要考虑以下几点:
- 主题的吞吐量
- 消费者从单个分区读取数据的吞吐量
- 生产者往单个分区写入数据的吞吐量
-
每个 Broker 包含的分区个数,可用的磁盘空间与网络带宽
单个 Broker 所承载的分区个数是有限的:分区越多,占用内存越多,分区 Leader 选举的时间越长
- 如果消息是按照 Key 写入各个分区的,那么新增分区会比较麻烦
1.1 log.retention.ms
数据被保留的时间;对应的有 log.retention.minutes, log.retention.hours.
1.3 log.retention.bytes
数据被保留的大小;该参数作用在每个分区上
如果同时指定了数据保留的时间与大小参数,那么只要任意一个参数满足,数据就会被删除
1.4 log.segment.bytes
当消息到达 Broker 时,会被追加到分区的当前日志片段(segment)上。当日志片段大小达到了 log.segment.bytes 时,当前日志片段就会被关闭,新的日志片段会被打开。
被关闭的日志片段,就开始等待过期。如果日志片段一直没被关闭,就不会过期。上面的 log.retention.ms/bytes 日志过期参数需要在日志片段关闭之后才有效。
该参数值越小,会导致越频繁地开启与关闭文件,降低磁盘效率
1.5 log.segment.ms
日志片段被关闭的时间。
如果同时指定了 log.segment.ms/bytes 两个参数,那么日志片段会在大小/时间达到上限时被关闭。
1.6 message.max.bytes
用来限制单个消息的大小。如果生产者发送的消息大于该值,那么消息不会被接收,并且 Broker 会返回错误消息。
如果该值越大,那么请求处理耗时就越大。同时,会增加磁盘写入块的大小,影响 IO 吞吐量。
2. 硬件
Kafka 本身对硬件没什么要求,但是如果对系统性能比较关注,可以注意以下几点:
2.1 磁盘吞吐量
生产者客户端的性能受服务端磁盘吞吐量的影响。生产者在发送完消息之后,一般会等待服务端将消息保存在磁盘上,磁盘写入越快,客户端生成消息的延迟就越低。
2.2 磁盘容量
磁盘容量大小取决于需要保存的消息数量,同时也受集群复制策略的影响。
2.3 内存
除了磁盘性能,服务端可用内存容量也是影响客户端性能的主要因素。
磁盘影响生产者,而内存影响消费者
一般情况下,消费者从分区尾部读取消息,如果有生产者存在,就紧跟在生产者后面。此时,消费者读取的消息会直接放在系统的页面缓存里,比磁盘上重新读取性能更高。
运行 Kafka 的 JVM 不需要太大的缓存,剩余的系统内存可以直接用作页面缓存,或者缓存正在使用中的日志片段
2.4 网络
网络吞吐量决定了 Kafka 能够处理的最大数据流量。
网络吞吐量与磁盘存储是制约 Kafka 扩展规模的主要因素
2.5 CPU
Kafka 对计算处理能力要求较低,主要用在消息批量压缩与解压过程中。
3. Kafka 集群
使用 Kafka 集群可以为客户端提供高性能与高可用性:
- 可以跨服务器进行负载均衡
- 使用复制功能避免单点故障造成的数据丢失
3.1 Broker 数量
一个 Kafka 集群需要多少个 Broker 数量取决于下面几个因素:
-
需要多少磁盘空间保存数据
单个 Broker 有多少可用空间,副本的复制系数多少
-
集群处理请求的能力
需要考虑网络吞吐量,磁盘吞吐量,系统内存容量因素
3.2 操作系统调优
默认操作系统配置已经能够满足大部分应用程序的运行需求,不过可以优化一些参数进一步提升性能,这些参数主要与虚拟内存,网络子系统,存储日志的磁盘挂载点有关。
3.2.1 虚拟内存
为了提高系统吞吐量,应该尽量避免内存交换。
内存页与磁盘之间的交换对 Kafka 各方面性能都有影响。Kafka 大量使用系统页面缓存,如果虚拟内存被交换到磁盘,说明没有多余的内存分配给页面缓存了。
一种优化方式是,不设置任何交换分区,避免内存交换。
- 奸笑 vm.swappiness 参数
另一种优化方式是,调整内核对脏页的处理方式。
- 减小 vm.dirty_background_ratio 参数,增大 vm.dirty_ratio 参数
3.2.2 磁盘
除了合适的磁盘硬件设备,文件系统是影响性能的另一个重要因素。
XFS 批量磁盘写入具有更高的效率,提高整体的 IO 吞吐量,为 Kafka 提供更好的性能。
3.2.3 网络
-
调整分配给 Socket 读写缓冲区的内存大小
参数 net.core.wmem_default, net.core.rmem_default.
-
调整 TCP Socket 读写缓冲区
参数 net.ipv4.tcp_wmem, net.ipv4.tcp_rmem