presto spill to disk

概况

为了预防内存紧张的operator,presto容许将中间操做的结果转存到磁盘上。这个机制的目的是为了让那些须要的内存超过一台机器一个query内存限制的query可以执行。html

这个机制相似于操做系统级的页交换。可是,它是被应用在应用程序级去知足presto的特殊需求。node

溢写的属性在https://prestodb.io/docs/current/admin/properties.html#tuning-spilling这里描述并发

内存管理和溢写

默认状况下,presto杀掉那些执行内存超过会话属性query_max_memory 或 query_max_memory_per_node。这个机制保证内存的公平分配,防止内存分配形成死锁。当集群中有不少小查询的时候,这是很是有效的。可是会杀掉那些超过限制的大查询。函数

为了克服这个问题,可撤回的内存概念被提出。一个查询能够请求不限制的内存,可是这个内存能够被任什么时候候被内存管理回收。当内存被回收,这个查询在内存中的数据被溢写到磁盘上,稍后继续处理。性能

事实上,当集群是空闲的时候,全部内存均可以获取,一个消耗内存的查询能够用完整个集群的内存。相反的,当集群没有足够的内存,一样的查询当前的数据被强制写到磁盘上。被溢写到磁盘上的查询可能有一个较长的执行时间比彻底在内存中运行。spa

请注意开启溢写到磁盘机制不保证消耗内存的查询运行成功。当加载数据到内存的时候,查询运行程序可能没法将中间数据划分为足够小的块,以便每一个块都适合于内存,致使 out of memory 错误。操作系统

溢出磁盘

溢写中间数据到磁盘,而后再加载到内存是一个高IO的操做,所以,磁盘多是这些查询的瓶颈。为了提升性能,建议在分开的磁盘上提供多重路径。相关属性https://prestodb.io/docs/current/admin/properties.html#tuning-spilling。rest

系统驱动盘不要被用做溢写,也不要运行在JVM运行和写日志的地方。这样作可能会致使系统不稳定。除此以外,建议监控溢写路径磁盘的饱和状态。日志

presto将溢写路径做为独立的磁盘,没有必要用 RAID 作溢写。htm

支持的操做

不是全部的操做支持溢写到磁盘,每个处理溢写不一样。目前,这个机制被用于以下操做。

Joins

在join期间,其中一个表被存在内存。这个表被称为生成表。若是另外一张表里的记录与生成表里的记录匹配,则被传递给下一个操做。join中最费内存的部分就是生成表。

当任务的并发性大于1,生成表被分区。分区的数目等于任务的并发数task.concurrency 。属性配置如https://prestodb.io/docs/current/admin/properties.html#task-properties

当生成表被分区,溢写磁盘机制能下降join操做须要内存的峰值。当一个查询接近内存限制,生成表的部分分区被溢写到内存,与此同时,这些分区内的另外一张表的记录也被写入磁盘。被溢写到磁盘的分区数量决定着占用磁盘空间的大小。

后面,被溢写的分区一个一个的读会内存,完成join操做。

有了这个机制,join操做使用的内存峰值被下降到生成表的最大分区的大小。假设没有数据倾斜,这将是整个生成表的 1/task.concurrency

Aggregations

聚合函数处理一组数据返回一个值。若是分组数目很是大,须要的内存也天然就不少。当启动溢写机制,直接计算的聚合结果被写到磁盘,当有内存资源的时候,它被读入内存合并。

相关文章
相关标签/搜索