前言:
presto 集群配置了JVM dump 策略,当节点发生内存不足时,会生成这个文件。也就是说出现这个文件,说明节点发生了内存溢出。
观察节点什么时候发生OOM
从下图中可以发现:
在06-25 09:21 时 10.21.4.205 节点发生了内存溢出。
在06-25 09:26 时 10.21.18.25 节点发生了内存溢出。
根据我们设置的内存不足保护策略query.low-memory-killer.policy=total-reservation
应该会在 节点发生内存溢出时,kill掉占用资源最多的任务。
因为presto集群,默认只能查看最近的100条任务记录,所以会定时采集presto的任务到es集群,然后使用kibana进行展示。
观察kb:
从下图可以看出:
任务在 06-25 09:25 和 09:30 时刻,kill掉了任务。
奇怪,是什么原因导致任务并没有立刻被kill掉?
排查:
只能先重启下 presto 服务,然后观察输出的日志:
然后发现日志会打印输出加载配置的日志:
具体内容如下:
2021-06-25T09:00:16.092+0800 INFO main Bootstrap query.low-memory-killer.delay 5.00m 5.00m Delay between cluster running low on memory and invoking killer
2021-06-25T09:00:16.092+0800 INFO main Bootstrap query.low-memory-killer.policy none total-reservation
- 重点来了
query.low-memory-killer.delay 5.00m 5.00m Delay between cluster running low on memory and invoking killer
看来当presto集群内存不足时,也并不是立刻就触发内存不足保护策略,而是会有个延迟。
也就是说当有节点内存不足时,5分钟后才会触发内存不足的保护策略。
实验步骤:
由于官方的文档中并没有这个配置, 官方配置文档如下:
https://prestodb.io/docs/current/admin/properties.html
于是只能自己尝试进行修改:
第一次修改:
想让当集群出现内存不足时,就立刻kill掉任务,于是设置。
1. 修改配置
query.low-memory-killer.delay=0s
重启presto服务:
重启报错,报错内容如下:
2021-06-25T16:22:06.531+0800 ERROR main com.facebook.presto.server.PrestoServer Unable to create injector, see the following errors:
1) Error: Invalid configuration property query.low-memory-killer.delay: {io.airlift.units.MinDuration.message} (for class com.facebook.presto.memory.MemoryManagerConfig.killOnOutOfMemoryDelay)
1 error
com.google.inject.CreationException: Unable to create injector, see the following errors:
1) Error: Invalid configuration property query.low-memory-killer.delay: {io.airlift.units.MinDuration.message} (for class com.facebook.presto.memory.MemoryManagerConfig.killOnOutOfMemoryDelay)
1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:543)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:159)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
at com.google.inject.Guice.createInjector(Guice.java:87)
at io.airlift.bootstrap.Bootstrap.initialize(Bootstrap.java:240)
at com.facebook.presto.server.PrestoServer.run(PrestoServer.java:127)
at com.facebook.presto.server.PrestoServer.main(PrestoServer.java:73)
报错原因:
Invalid configuration property
无效的配置属性? 那么到底是配置的不正确还是确实不支持自行修改这个配置,正好报错内存细心的贴出了报错地方
com.facebook.presto.memory.MemoryManagerConfig.killOnOutOfMemoryDelay
那么只能看一眼代码了(重点代码如下):
@NotNull
@MinDuration("5s")
public Duration getKillOnOutOfMemoryDelay()
{
return killOnOutOfMemoryDelay;
}
@Config("query.low-memory-killer.delay")
@ConfigDescription("Delay between cluster running low on memory and invoking killer")
public MemoryManagerConfig setKillOnOutOfMemoryDelay(Duration killOnOutOfMemoryDelay)
{
this.killOnOutOfMemoryDelay = killOnOutOfMemoryDelay;
return this;
}
@MinDuration("5s")
原来是有个注解,最小只能为5s,所以我之前设置的0s 报无效配置错误。
第二次修改:
有了上面的分析,那么内存不足保护策略延迟生效时间只能设置为最低,也就是5s
1. 修改配置:
query.low-memory-killer.delay=5s
2. 重启服务
重启服务,服务可以正常启动。
总结
presto集群在发生节点内存不足时,并不会直接出发内存不足保护策略,而是会有个延迟(默认5分钟),所以如果想要让服务稳定性提高的话,还是让这个延迟策略尽可能早的触发吧。
接下来的重点是观察当内存不足时,任务是否会在5s后杀死。