我们遇到“不能分配内存的问题”导致Kafka Crash,观察kafka maps数超过了6w,实际RedHat 6.4(包括7.2和7.4)默认是65530,即使重启Kafka,也无法运行。于是我们在sysctl.conf文件中,将vm.max_map_count设置为262144。再重启Kafka,成功启动Kafka。于是问题来了,maps资源不够,是个直接原因,那根本原因是什么呢?
有人提出是log.roll.ms设置的问题,原来设置的是10分钟,导致频繁创建log segment,所以消耗了maps,这个说法,似乎有道理,但查过相关文献,没找到相关说法,不能肯定根本原因。我们需要通过一个测试来验证,测试的论点是– 减小log.roll.ms的值,是否kafka进程的maps会占用更多。为此,我们分以下步骤来验证:
1) 记录Broker的maps数。
2) 重启Broker,记录maps数,观察重启之后,是否有变化。
3) 通过性能测试工具’./bin/kafka-producer-perf-test.sh’,向集群中写入数据,观察maps是否有变化。
4) 修改Broker的log.roll.ms的数,由10分钟改为1s,并重启Kafka。
5) 通过性能测试工具’./bin/kafka-producer-perf-test.sh’,向集群中写入数据,观察maps是否有变化。
6) 对比配置修改前后的maps数值,由于性能测试工具写入的数据是一致的,这样可以得出log.roll.ms与maps的关系,如果maps变化不大,则说明与log.roll.ms无关;反之,有关。
测试结果如下:
其中集群包含3台虚机,每台虚机配置为4核、4G内存、10G磁盘,从测试结果可以看出,在log.roll.ms调小的情况下,log segment文件会增加,kafka进程的maps也会增加,官方默认log.roll.ms为null,没有配置,通过log.segment.byte来管理log segment的roll。单独配置log.roll.ms有点画蛇添足了,通过size和时间两个维度来决定log segment的roll,有点多余,实际上默认的log.roll.hour是168,即7天时间。所以我们去掉log.roll.ms,使用默认log.segment.byte为1G来roll。