那些要修改默认值的参数
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 还能正常工作。还记得上一期我们关于 Kafka 是否需要使用 RAID 的讨论吗?这个改进正是我们舍弃 RAID 方案的基础:没有这种 Failover 的话,我们只能依靠 RAID 来提供保障。
ZooKeeper
它是一个分布式协调框架,负责协调管理并保存 Kafka 集群的所有元数据信息,比如集群都有哪些 Broker 在运行、创建了哪些 Topic,每个 Topic 都有多少分区以及这些分区的 Leader 副本都在哪些机器上等信息。
-
listeners
:学名叫监听器,其实就是告诉外部连接者要通过什么协议访问指定主机名和端口开放的 Kafka 服务。 -
advertised.listeners - advertised.listeners主要是为外网访问用的。如果clients在内网环境访问Kafka不需要配置这个参数。
常见的玩法是:你的Kafka Broker机器上配置了双网卡,一块网卡用于内网访问(即我们常说的内网IP);另一个块用于外网访问。那么你可以配置listeners为内网IP,advertised.listeners为外网IP。
Topic 管理
auto.create.topics.enable
:是否允许自动创建 Topic。不能自立为王unclean.leader.election.enable
:是否允许 Unclean Leader 选举。宁缺毋滥auto.leader.rebalance.enable
:是否允许定期进行 Leader 选举。江山不易改
数据留存方面
log.retention.{hour|minutes|ms}
:这是个“三兄弟”,都是控制一条消息数据被保存多长时间。从优先级上来说 ms 设置最高、minutes 次之、hour 最低。数据寿命 hours=168log.retention.bytes
:这是指定 Broker 为消息保存的总磁盘容量大小。祖宅大小 -1 表示没限制message.max.bytes
:控制 Broker 能够接收的最大消息大小。祖宅大门宽度,默认 1000012=976KB
Topic 级别参数
保存消息
Topic 级别参数会覆盖全局 Broker 参数的值,而每个 Topic 都能设置自己的参数值,这就是所谓的 Topic 级别参数。
-
retention.ms
:规定了该 Topic 消息被保存的时长。默认是 7 天,即该 Topic 只保存最近 7 天的消息。一旦设置了这个值,它会覆盖掉 Broker 端的全局参数值。 -
retention.bytes
:规定了要为该 Topic 预留多大的磁盘空间。和全局参数作用相似,这个值通常在多租户的 Kafka 集群中会有用武之地。当前默认值是 -1,表示可以无限使用磁盘空间。 -
max.message.bytes:它决定了 Kafka Broker 能够正常接收该 Topic 的最大消息大小
JVM 参数
使用 Java 8
- Heap Size,建议6GB,默认的 1GB 有点小,最好还是监控一下实时的堆大小,特别是GC之后的live data大小,通常将heapsize设置成其1.5~2倍就足以了
- JAVA7 如果 Broker 所在机器的 CPU 资源非常充裕,建议使用 CMS 收集器。启用方法是指定
-XX:+UseCurrentMarkSweepGC
。 - JAVA7 否则,使用吞吐量收集器。开启方法是指定
-XX:+UseParallelGC
。 - Java 8 G1,在没有任何调优的情况下,G1 表现得要比 CMS 出色,主要体现在更少的 Full GC,需要调整的参数更少等,所以使用 G1 就好了。
操作系统参数
- 文件描述符限制,ulimit -n 1000000,不设置的话后果很严重,比如你会经常看到“Too many open files”的错误。
- 文件系统类型,文件系统类型的选择。这里所说的文件系统指的是如 ext3、ext4 或 XFS 这样的日志型文件系统。根据官网的测试报告,XFS 的性能要强于 ext4,所以生产环境最好还是使用 XFS。对了,最近有个 Kafka 使用 ZFS 的数据报告,貌似性能更加强劲,有条件的话不妨一试。
- Swappiness,swap 的调优。网上很多文章都提到设置其为 0,将 swap 完全禁掉以防止 Kafka 进程使用 swap 空间。我个人反倒觉得还是不要设置成 0 比较好,我们可以设置成一个较小的值。为什么呢?因为一旦设置成 0,当物理内存耗尽时,操作系统会触发 OOM killer 这个组件,它会随机挑选一个进程然后 kill 掉,即根本不给用户任何的预警。但如果设置成一个比较小的值,当开始使用 swap 空间时,你至少能够观测到 Broker 性能开始出现急剧下降,从而给你进一步调优和诊断问题的时间。基于这个考虑,我个人建议将 swappniess 配置成一个接近 0 但不为 0 的值,比如 1。
- 提交时间,提交时间或者说是 Flush 落盘时间。向 Kafka 发送数据并不是真要等数据被写入磁盘才会认为成功,而是只要数据被写入到操作系统的页缓存(Page Cache)上就可以了,随后操作系统根据 LRU 算法会定期将页缓存上的“脏”数据落盘到物理磁盘上。这个定期就是由提交时间来确定的,默认是 5 秒。一般情况下我们会认为这个时间太频繁了,可以适当地增加提交间隔来降低物理磁盘的写操作。当然你可能会有这样的疑问:如果在页缓存中的数据在写入到磁盘前机器宕机了,那岂不是数据就丢失了。的确,这种情况数据确实就丢失了,但鉴于 Kafka 在软件层面已经提供了多副本的冗余机制,因此这里稍微拉大提交间隔去换取性能还是一个合理的做法
常见问题
-
把message.max.bytes设置地挺大,但是java生产者发送1M以上数据就失败,集群也重启过
producer、broker、consumer三端都需要调整
broker: message.max.bytes和replica.fetch.max.bytes
consumer:fetch.message.max.bytes -
G1是jdk9中默认的,jdk8还是需要显式指定的
-
修改 Topic 级 max.message.bytes,还要考虑以下两个吧?
还要修改 Broker的 replica.fetch.max.bytes 保证复制正常
消费还要修改配置 fetch.message.max.bytes -
页缓存属于磁盘缓存(Disk cache)的一种,主要是为了改善系统性能。重复访问磁盘上的磁盘块是常见的操作,把它们保存在内存中可以避免昂贵的磁盘IO操作。
既然叫页缓存,它是根据页(page)来组织的内存结构。每一页包含了很多磁盘上的块数据。Linux使用Radix树实现页缓存,主要是加速特定页的查找速度。另外一般使用LRU策略来淘汰过期页数据。总之它是一个完全由内核来管理的磁盘缓存,用户应用程序通常是无感知的。
无论应用还是数据库 甚至操作系统,为了防止直接操作磁盘,都会有缓存这一层
-
怎么能限制消费者的消费速度,或者限制消费带宽啊,https://www.cnblogs.com/huxi2b/p/8609453.html
-
多个日志段文件删除
路径下有多个.log文件才有可能删除消息,如果只有一个.log文件是不会开启的,即使满足条件也不行。
地址:
- https://time.geekbang.org/column/article/101171
- https://time.geekbang.org/column/article/101763