Presto为什么比Spark SQL快?

2022-02-14 00:00:00 查询 集群 架构 节点 内存
作者:程序员守护石
链接:https://www.zhihu.com/question/461560750/answer/1909431981

Presto为什么比Spark SQL快?
Spark SQL属于MMP架构的吗?

个问题:Presto作为SQL查询引擎是一个纯内存的计算引擎,它对内存的优化近乎于一种的追求。Presto的架构主要是主从式,主节点是coordinator负责SQL的优化和执行计划分配,同时还负责整个集群的内存管理,这点是其为什么如此快的重要原因。

例如:一个查询Query需要消耗12G的内存,你有三台work负责查询,每个work的内存都是32GB,coordinator经过计算后,得出每个节点有6G就差不多了(4G执行,2G备用)。那么这个Query 即便重复执行5次约等于每个work付出30G内存,Presto照样敢一起执行,所以它快。但是假如一个Query需要消耗100GB的内存,这就超过了整个集群的内存了,那么Presto的coordinator就直接卡掉这个查询,防止内存溢出。多个查询之和若超出集群内存总量就排队。所以它是这么玩的。

反过来看Spark SQL,它主要在集群中的每个计算节点的Executor进程中进行内存管理,因此它的内存管理主要还是为了优化当前计算节点的性能而设计的,不同于Presto搞了个主从架构专门控制集群内存。Spark SQL的架构还是基于Spark,Spark的分布式架构又基于Hadoop Yarn(或者Mesos),作为Yarn不管你内部的内存效率,只关心将你的任务成功的分发到不同阶段的节点上去完成。

例如:Spark SQL生成优化后的物理计划若分成10个task去做,安排在3个Executor进程去创建task并管理,每台Executor在管理task的内存时,也许有的task比较费内存,有的task就不需要那么费,Executor发现自己内存不够,就缓冲到磁盘去做。所以Spark也会出现内存与磁盘的I/O交换,那么这个速度就不明显了。

因此Presto的主从架构是从集群整体上的内存情况,对进行中的查询进行定时监控,优化调度,将大将耗内存的查询,调度给work节点配置的大内存量去使用,大概在堆内存的10%。但是Spark还是单靠每个节点自己的Executor进程来解决内存与磁盘的平衡问题。

但是数据量太大的查询尤其是还存在复杂的关联的全量数据集处理,Spark大多数情况还是比Presto快,一方面因为Presto遇到这种情况,主要就是对查询的分解、分批、排队。但是Spark就能充分利用MPP架构的能力,多任务分配到切分后的多数据块,先调入计算处理,大不了内存和磁盘一起用。

另一方面Presto倾向于计算与存储分离的架构,每个work并不知道是不是从本地拿数据,只是根据查询要求来做,大多数情况都是远程调用数据,但是Spark还是计算与存储结合的架构,每个task可以和rdd的一个分区做对应,那么spark对rdd的分布式数据节点分配也会尽量按照就近原则进行,作为复杂的连接操作,尽量多的在本地处理,速度肯定比远程读取或者混洗(shuffle)要快很多。

第二个问题Spark SQL,它本质上包含了海量数据的并行计算(MPP),比MPP架构要更,因为通过DataFrame,对不同的数据源进行了统一的高层次抽象。这个是比传统MPP要有优势,例如Impala就是类似于传统MPP的架构,它就只是针对性HDFS和HBase。但是Spark SQL可以根据DF这种高层次的抽象,接入更多的数据源,终作为schema RDD(还是数据集的抽象)进入到Spark实现并行任务执行,可以说在MPP的基础上,将抽象进行到底。

相关文章