Presto 有很多和内存相关的参数,如果你刚接触 Presto 难免会迷惑,接下来结合本人工作实践,分享下我的理解。
1. 内存用途
- 给操作系统:需要预留一定比例的内存,内核运行需要内存,Page Cache 需要内存,预留内存还有一个好处可以降低 Presto 进程被 Linux OOM Killer 干掉的风险;
- 给 Presto 进程运行:Presto 进程运行需要内存,在
etc/jvm.config
文件中可配置 JVM 使用的最大堆内存; - 给 SQL 查询:SQL 语句会经过语法分析 -> 语义分析 -> 逻辑计划 -> RemoteTaskFactory 创建多个 RemoteTask,RemoteTask 会在实际的 Work 中执行,所以需要限制 RemoteTask 执行时使用的内存,不然 Worker 会有内存溢出风险。
2. 内存参数设置建议
2.1 内核
- vm.dirty_background_ratio = 80%,当系统脏页比例达到 80% 以上时,开始将脏页写入磁盘,写入过程不会阻塞新的请求;
- vm.dirty_ratio = 95 %,系统脏页比例达到 95% 以上时,阻塞写入请求,将将脏页写入磁盘;
- 系统内存预留:总内存的 15%~20% ,假设主机内存 32GB,你可以留给操作系统 5~7GB 之间。
2.2 JVM
- -Xmx:总内存的 80% ~ 85% ,假设主机内存 32GB,最大堆内存 -Xmx25G~-Xmx27G;
- -XX:MaxDirectMemorySize:总内存的 10% 左右,假设主机内存 32GB,-XX:MaxDirectMemorySize=3G;
- -Djdk.nio.maxCachedBufferSize:每个线程可使用的最大临时缓冲区高速缓存,这个区域不受 GC 控制,NIO 底层实现时基于 DirectByteBuffer 用于 IO 的读写操作,该属性单位只支持 bytes,建议配置为 2 * 1024 * 1024(2MB)即 -Djdk.nio.maxCachedBufferSize=2097152。
2.3 Presto 内存参数
作用于单个 Work:
- query.max-memory-per-node:查询可使用最大 heap,默认 JVM 最大堆内存 * 0.1;
- query.max-total-memory-per-node:查询可使用的最大 heap + non-heap 内存;
- memory.heap-headroom-per-node:headroom 区域,JVM 堆中的保留区域,该区域不可被追踪,该值