CN108710640B - 一种提高Spark SQL的查询效率的方法 - Google Patents
一种提高Spark SQL的查询效率的方法 Download PDFInfo
- Publication number
- CN108710640B CN108710640B CN201810351379.9A CN201810351379A CN108710640B CN 108710640 B CN108710640 B CN 108710640B CN 201810351379 A CN201810351379 A CN 201810351379A CN 108710640 B CN108710640 B CN 108710640B
- Authority
- CN
- China
- Prior art keywords
- size
- data
- intermediate data
- total
- stage
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Landscapes
- Information Retrieval, Db Structures And Fs Structures Therefor (AREA)
Abstract
本发明公开了一种提高Spark SQL的查询效率的方法。本发明包括步骤S1:构建查询预分析模块,通过估算模型,计算Shuffle产生的中间数据的大小,从而计算出用于缓存所述中间数据的中间数据缓存层的总大小;步骤S2:根据步骤1计算出的中间数据缓存层的总大小,结合集群中每个结点输入数据的分布情况,通过缓存层分配模块为每个结点设置合理的内存空间大小。本发明能有效地通过Shuffle中间数据缓存处理方法解决Spark SQL查询中磁盘I/O开销较高的问题。
Description
技术领域:
本发明涉及一种提高Spark SQL的查询效率的方法,具体涉及一种通过Shuffle操作中间数据缓存的处理提高Spark SQL的查询效率的方法。
背景技术:
随着互联网的不断发展与普及,企业、政府机关,科研机构等每天产生的数据量是可观的。例如,淘宝每天产生的数据量达到7T,百度每天需要处理的数据量达到了100PB,处理大数据的现实需求促进了云计算领域很多的学术研究。Apache Spark是一个基于内存的计算框架,它以弹性分布式数据集RDD(Resilient Distributed Datasets)的实现为核心,实现数据的分布与容错。Spark是一个高速而通用的大数据处理引擎,由加州大学伯克利分校AMP (Algorithms,Machines,and People Lab)实验室团队使用语言Scala开发。SparkSQL从基于 Hive的Shark开发而来,是一种用于处理结构化数据的Spark组件。
Spark在执行一个作业的过程中,会首先为该作业生成一个有向无环图(DirectedAcyclic Graph,DAG)来记录所进行的操作。其次,DAG图将会根据RDD间的依赖关系被划分成若干个阶段,同一个阶段中的RDD之间的依赖关系均为窄依赖,连接两个阶段的RDD之间的依赖关系为宽依赖。在发生窄依赖时,数据在内存中的多个RDD操作之间进行传递,不会发生磁盘I/O开销。但是在发生宽依赖时,由于需要读取所有的父RDD的内容并做连接操作,该操作开销较大,如果都在内存中进行容易内存溢出。因此Spark默认在发生宽依赖时,会把每个阶段生成的中间数据写到磁盘,该过程称为Shuffle。而Spark Shuffle阶段会产生大量的中间数据,图1是Spark SQL运行一个简单查询产生中间文件的个数,最多时产生了8000 个文件,并且波动较大从而造成了大量的随机磁盘I/O开销,该开销是阻碍Spark SQL执行效率的主要因素之一。
发明内容
本发明的目的是提供一种提高Spark SQL的查询效率的方法,通过Shuffle中间数据缓存处理方法解决Spark SQL查询中磁盘I/O开销较高的问题。
上述的目的通过以下技术方案实现:
一种提高Spark SQL的查询效率的方法,该方法包括如下步骤:
步骤S1:构建查询预分析模块,通过估算模型,计算Shuffle产生的中间数据的大小,从而计算出用于缓存所述中间数据的中间数据缓存层的总大小;
步骤S2:根据步骤1计算出的中间数据缓存层的总大小,结合集群中每个结点输入数据的分布情况,通过缓存层分配模块为每个结点设置合理的内存空间大小。
进一步地,步骤S1中所述的计算Shuffle产生的中间数据的大小的具体方法是:查询预分析模块通过解析用户输入的查询语句得到Spark下该作业的工作流,根据估算模型计算工作流中每个阶段生成的中间数据大小。
进一步地,步骤S2中在获得缓存层的总大小后,缓存层分配模块统计输入数据的每一个数据块在集群中的分布情况,按比例为不同的结点开辟不同大小的内存。
进一步地,所述工作流包括两个阶段,分别是进行投影、选择、聚集操作的阶段,和进行连接操作的阶段,每个阶段产生的中间数据的大小之后,通过求和即可得到缓存层的总大小Mtotal。
进一步地,所述的投影、选择、聚集操作的阶段生成的中间数据大小的计算公式是:
投影操作的阶段生成的中间数据大小:
|Dout(pro)|=βpro|Din| (1)
式中,|Dout(pro)|表示投影操作生成中间数据的大小,|Din|表示输入数据的大小。βpro表示做投影操作后的数据占总数据的比例,其中βpro=Lpro/LD,Lpro是投影属性长度,LD是所有属性总长度;
选择操作的阶段生成的中间数据大小:
|Dout(fil)|=βfil|Din| (2)
式中,|Dout(fil)|表示选择操作生成中间数据的大小。βfil表示做选择操作后的数据占总数据的比例,其值由具体的选择条件和原表的数据分布有关;
聚集操作的阶段生成的中间数据大小:
|Dout(agg)|≈0 (3)
式中,|Dout(agg)|表示聚集操作生成的中间数据的大小,聚集操作返回某一属性的和或平均值,因此输出大小可以忽略不计。
进一步地,所述的连接操作,使用以下规则计算该阶段输出数据的大小:
如果无连接条件C,则变成笛卡尔乘积,γ=1;
如果没有元组满足连接条件C,则γ=0,一般地0≤γ≤1;
如果连接条件为D1.A=D2.B,则有下面三种特殊情况:
(2)如果A不是D1的主键,B也不是D2的主键,而属性A、B在相同的域M上服从均匀分布,则
式中,M表示属性A、B在域M上重叠部分的大小。
(3)如果A不是D1的主键,且B也不是D2的主键,而属性A、B不服从均匀分布,则γ需要根据具体的数据集,参照表结构和数据规模,实际运行采样获取数据,采用直方图方法进行估计。
进一步地,所述的中间数据缓存层利用分布式内存文件***Alluxio。
有益效果:
本发明的方法与现有的Spark SQL缓存策略相比,其显著的优点是:现有的方法通常是把输入数据存入分布式内存文件***来提高查询效率,而在实际的生产环境中,输入数据的大小往往大于内存的最大容量,因此通过输入数据放入内存来减少磁盘I/O的方法不太现实。 Spark Shuffle阶段产生的中间数据的大小在通常情况下都是小于输入数据的大小的,磁盘I/O 的开销主要是Shuffle阶段产生的文件数量过多而造成的随机I/O的开销。因此为了减少这部分开销,为这些数据开辟一块内存缓存层,并能根据不同的查询适当调整缓存层的大小,是本发明所解决的主要问题。
附图说明
图1为Spark Shuffle中间数据波动图;
图2为Spark SQL执行查询流程图;
图3为数据块在集群中的分布情况图;
图4为Shuffle优化后对比实验图。
具体实施方式
下面结合具体实施方式,进一步阐明本发明,应理解下述具体实施方式仅用于说明本发明而不用于限制本发明的范围。
一种提高Spark SQL的查询效率的方法,该方法包括如下步骤:
步骤S1:构建查询预分析模块,通过估算模型,计算Shuffle产生的中间数据的大小,从而计算出用于缓存所述中间数据的中间数据缓存层的总大小;
步骤S2:根据步骤1计算出的中间数据缓存层的总大小,结合集群中每个结点输入数据的分布情况,通过缓存层分配模块为每个结点设置合理的内存空间大小。
进一步地,步骤S1中所述的计算Shuffle产生的中间数据的大小的具体方法是:查询预分析模块通过解析用户输入的查询语句得到Spark下该作业的工作流,根据估算模型计算工作流中每个阶段生成的中间数据大小。
进一步地,步骤S2中在获得缓存层的总大小后,缓存层分配模块统计输入数据的每一个数据块在集群中的分布情况,按比例为不同的结点开辟不同大小的内存。
下面的实验是在拥有11个结点的集群的环境下进行的,其中每个结点的硬件配置是2.7GHz 8核的CPU和64GB内存。使用TPC-H标准测试数据集生成了10GB大小的原始数据,表格中输入数据大于10g的,是因为SQL语句中有一些嵌套查询,对于父查询和子查询中被多次使用的输入数据需要重复载入。
表1 Spark TPC-H运行结果表。
通过对TPC-H中具有代表性的几个查询的运行结果的分析可以发现,Spark的磁盘I/O主要发生在对输入数据的读取和对中间数据的读写上,由于SQL查询产生的输出结果一般较少,该代价不做考虑。并且Shuffle阶段产生的中间数据大小与输入数据的大小无关,有的查询输入数据不大,产生的中间数据却很多,例如Q9查询。有的查询输入数据很大,产生的中间数据却很少,例如Q19查询。为了缓存中间数据,必须评估每个查询所产生的中间数据的大小。
对于Spark SQL什么时候将中间数据写到磁盘上,本文通过对一个查询的执行过程进行分析;
使用Spark SQL运行上述查询的执行流程如图2所示,Spark在执行一个作业的过程中,会为该作业生成一个DAG图来记录所进行的操作,同时DAG图会根据RDD间的依赖关系被划分成若干个阶段。
Spark SQL将该查询划分成3个阶段。阶段0读取part表格,在该表格上对属性p_partkey 做投影运算。阶段1读取lineitem表格,对该表格上的l_partkey、l_quantity、l_extendedprice 三个属性做投影运算,并做l_quantity<40的选择运算。阶段2读取阶段0和阶段1生成的中间结果,做p_partkey=l_partkey的连接操作,最后将查询结果写入磁盘。
通过对该查询的分析本文发现,可以把Spark中执行查询的作业流分为两种阶段,一种是进行投影、选择、聚集操作的阶段,和进行连接操作的阶段。两种阶段计算输出数据大小的公式如下所示:
投影、选择、聚集操作:
(1)投影
|Dout|=βpro|Din| (1)
βpro=Lpro/LD,Lpro是投影属性长度,LD是所有属性总长度。
(2)选择
|Dout|=βfil|Din| (2)
βfil的值由具体的选择条件和原表的数据分布有关。
(3)聚集
|Dout|≈0 (3)
聚集操作返回某一属性的和或平均值,因此输出大小可以忽略不计。
连接操作:
对于连接操作,需要使用以下规则计算该阶段输出数据的大小:
如果无连接条件C,则变成笛卡尔乘积,γ=1。如果没有元组满足连接条件C,则γ=0。一般地0≤γ≤1。如果连接条件为D1.A =D2.B,则有下面三种特殊情况。
(2)如果A不是D1的主键,B也不是D2的主键,而属性A、B在相同的域M上服从均匀分布,则
(3)如果A不是D1的主键,且B也不是D2的主键,而属性A、B不服从均匀分布,则γ需要根据具体的数据集,参照表结构和数据规模,实际运行采样获取数据,采用直方图方法进行估计,直方图法的算法流程如表2所示:
表2直方图法计算连接操作元组数
算法的输入是关系R与关系S的变宽分布直方图,输出是两个关系做连接操作后总的元组个数Sum。算法从关系R和关系S直方图的第一个直方桶开始,若两个直方桶之间有重叠的部分,由于直方桶内是均匀分布,那么可以通过重叠部分的大小,除以直方桶的宽度,再乘以直方桶总的频次数,得到相等的属性在关系R、S中各自直方桶内出现的次数templeft 和tempright。将templeft与tempright相乘,再除以重叠部分的大小,得到相等的属性在关系R、S中第一个重叠的直方桶内做连接得到的元组总数。若两个直方桶没有重叠的部分,假设直方桶hir的范围小于直方桶hjs的范围,那么就要比较直方桶hi+1r与hjs的范围。继续上述步骤,直到遍历完关系R或关系S中所有的直方桶为止。
在通过上述方法计算每个阶段产生的中间数据的大小之后,通过求和即可得到缓存层的总大小Mtotal。由于Spark Shuffle中间数据缓存层本质上是内存存储***,需要划分一定的内存空间进行存储。为了简化***实现,并进一步提高内存的使用效率,本实施例在此利用分布式内存文件***Alluxio作为Shuffle中间数据缓存层。Alluxio是一个基于内存的分布式文件***,它是架构在底层分布式文件***和上层分布式计算框架之间的一个中间件,主要职责是以文件形式在内存或其它存储设施中提供数据的读写服务。在计算得到缓存层使用的总大小后,接下来的问题就是给集群中每个结点分配多大的内存。由于Spark数据本地化(Data Locality)的设计原则,即读取HDFS文件时,Spark会根据数据的存储位置,分配离数据存储最近的Executor去执行任务,对于存储较多输入数据的节点,应该分配更多的内存空间。在HDFS中输入数据是以数据块的形式(一个数据块的大小默认为128MB)组织的,因此在解析用户输入的查询语句获得待查询的表格后,需要分析每一张表的数据块在集群中的分布情况。由于在HDFS中每一个数据块的大小都是一样的,因此根据每一个结点拥有的数据块的个数占所有数据块的比例,来计算该结点所分配的内存空间的大小。
式中,Mi表示集群中的一个结点分配内存的大小,Bi表示集群中的一个结点拥有的数据块数,Btotal表示所有的数据块总数,Mtotal表示中间数据缓存层的总大小
针对前面提到的Q1查询,Lineitem表格的大小为7.2GB,包括60个数据块。Part表格的大小为233MB,包括2个数据块。这些数据块在集群中的分布如图3所示:
在获得了输入数据在集群中的分布状况后,就可以根据步骤1中计算出的缓存层总大小与步骤2中的公式6,计算得到各节点所需分配的内存大小为790*2/62≈25.48MB,790*21/62 ≈267.58MB,790*3/62≈38.22MB,790*20/62≈254.83MB,790*4/62≈50.96MB,790*5/62≈63.71MB。近似于该程序在各节点的实际Shuffle数据量。
在完成Spark Shuffle缓存层在各节点的内存分配后,本实施例选取了几个具有代表性的查询,它们分别为Q1、Q5、Q9、Q18、Q19。其中Q1、Q19为输入数据较大,但是中间数据较少的查询,从图4中可以看到本实施例对这样的查询优化并不明显。但是对于Q5、Q9、 Q18这样的中间数据比输入数据明显较大的查询,本实施例的优化效果就非常明显。
应当指出,上述实施实例仅仅是为清楚地说明所作的举例,而并非对实施方式的限定,这里无需也无法对所有的实施方式予以穷举。本实施例中未明确的各组成部分均可用现有技术加以实现。对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。
Claims (3)
1.一种提高Spark SQL的查询效率的方法,其特征在于,该方法包括如下步骤:
步骤S1:构建查询预分析模块,通过估算模型,计算Shuffle产生的中间数据的大小,从而计算出用于缓存所述中间数据的中间数据缓存层的总大小;
步骤S2:根据步骤1计算出的中间数据缓存层的总大小,结合集群中每个结点输入数据的分布情况,通过缓存层分配模块为每个结点设置合理的内存空间大小;
步骤S1中所述的计算Shuffle产生的中间数据的大小的具体方法是:查询预分析模块通过解析用户输入的查询语句得到Spark下用户输入的查询语句的工作流,根据估算模型计算工作流中每个阶段生成的中间数据大小;
所述工作流包括两个阶段,分别是进行投影、选择、聚集操作的阶段,和进行连接操作的阶段,每个阶段产生的中间数据的大小之后,通过求和即可得到缓存层的总大小Mtotal;
所述的投影、选择、聚集操作的阶段生成的中间数据大小的计算公式是:
投影操作的阶段生成的中间数据大小:
|Dout(pro)|=βpro|Din| (1)
式中,|Dout(pro)|表示投影操作生成中间数据的大小,|Din|表示输入数据的大小,βpro表示做投影操作后的数据占总数据的比例,其中βpro=Lpro/LD,Lpro是投影属性长度,LD是所有属性总长度;
选择操作的阶段生成的中间数据大小:
|Dout(fil)|=βfil|Din| (2)
式中,|Dout(fil)|表示选择操作生成中间数据的大小,βfil表示做选择操作后的数据占总数据的比例,其值由具体的选择条件和原表的数据分布有关;
聚集操作的阶段生成的中间数据大小:
|Dout(agg)|≈0 (3)
式中,|Dout(agg)|表示聚集操作生成的中间数据的大小,聚集操作返回某一属性的和或平均值,因此输出大小可以忽略不计;
所述的连接操作,使用以下规则计算该阶段输出数据的大小:
如果无连接条件C,则变成笛卡尔乘积,γ=1;
如果没有元组满足连接条件C,则γ=0,0≤γ≤1;
如果连接条件为D1.A=D2.B,则有下面三种特殊情况:
(2)如果A不是D1的主键,B也不是D2的主键,而属性A、B在相同的域M上服从均匀分布,则
式中,M表示属性A、B在域M上重叠部分的大小;
(3)如果A不是D1的主键,且B也不是D2的主键,而属性A、B不服从均匀分布,则γ需要根据具体的数据集,参照表结构和数据规模,实际运行采样获取数据,采用直方图方法进行估计。
2.根据权利要求1所述的提高Spark SQL的查询效率的方法,其特征在于,步骤S2中在获得缓存层的总大小后,缓存层分配模块统计输入数据的每一个数据块在集群中的分布情况,按比例为不同的结点开辟不同大小的内存。
3.根据权利要求1所述的提高Spark SQL的查询效率的方法,其特征在于,所述的中间数据缓存层利用分布式内存文件***Alluxio。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810351379.9A CN108710640B (zh) | 2018-04-17 | 2018-04-17 | 一种提高Spark SQL的查询效率的方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201810351379.9A CN108710640B (zh) | 2018-04-17 | 2018-04-17 | 一种提高Spark SQL的查询效率的方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN108710640A CN108710640A (zh) | 2018-10-26 |
CN108710640B true CN108710640B (zh) | 2021-11-12 |
Family
ID=63866678
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201810351379.9A Active CN108710640B (zh) | 2018-04-17 | 2018-04-17 | 一种提高Spark SQL的查询效率的方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN108710640B (zh) |
Families Citing this family (3)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110704336B (zh) * | 2019-09-26 | 2021-10-15 | 绿盟科技集团股份有限公司 | 一种数据缓存方法及装置 |
CN113495679B (zh) * | 2020-04-01 | 2022-10-21 | 北京大学 | 基于非易失存储介质的大数据存储访问与处理的优化方法 |
CN113312381A (zh) * | 2020-07-31 | 2021-08-27 | 阿里巴巴集团控股有限公司 | 数据处理方法和装置 |
Family Cites Families (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US7426915B2 (en) * | 2005-12-08 | 2008-09-23 | Ford Global Technologies, Llc | System and method for reducing vehicle acceleration during engine transitions |
CN107169033B (zh) * | 2017-04-17 | 2020-03-31 | 东北大学 | 基于数据模式转换和并行框架的关系数据查询优化方法 |
CN107391555B (zh) * | 2017-06-07 | 2020-08-04 | 中国科学院信息工程研究所 | 一种面向Spark-Sql检索的元数据实时更新方法 |
CN107612886B (zh) * | 2017-08-15 | 2020-06-30 | 中国科学院大学 | 一种Spark平台Shuffle过程压缩算法决策方法 |
-
2018
- 2018-04-17 CN CN201810351379.9A patent/CN108710640B/zh active Active
Also Published As
Publication number | Publication date |
---|---|
CN108710640A (zh) | 2018-10-26 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
Marcu et al. | Spark versus flink: Understanding performance in big data analytics frameworks | |
Li et al. | A platform for scalable one-pass analytics using mapreduce | |
CN108710640B (zh) | 一种提高Spark SQL的查询效率的方法 | |
CN104778077B (zh) | 基于随机和连续磁盘访问的高速核外图处理方法及*** | |
Punnoose et al. | SPARQL in the cloud using Rya | |
Elsayed et al. | Mapreduce: State-of-the-art and research directions | |
Gates et al. | Apache Pig's Optimizer. | |
Tang et al. | An intermediate data partition algorithm for skew mitigation in spark computing environment | |
US10877973B2 (en) | Method for efficient one-to-one join | |
WO2015168988A1 (zh) | 一种数据索引创建方法、装置及计算机存储介质 | |
US20240232722A1 (en) | Handling system-characteristics drift in machine learning applications | |
AU2019241002B2 (en) | Transaction processing method and system, and server | |
US10558633B1 (en) | Hash-value-based single-pass data store statistics collection | |
Lai et al. | Accelerating multi-way joins on the GPU | |
GB2516501A (en) | Method and system for processing data in a parallel database environment | |
WO2021004266A1 (zh) | 数据***方法、装置、设备和储存介质 | |
CN113157541A (zh) | 面向分布式数据库的多并发olap型查询性能预测方法及*** | |
CN108319604A (zh) | 一种hive中大小表关联的优化方法 | |
Nassar et al. | Chi squared feature selection over Apache Spark | |
CN109558376A (zh) | 一种面向MapReduce框架的有效计算与数据传输重叠执行方法 | |
Wang et al. | Turbo: Dynamic and decentralized global analytics via machine learning | |
Lou et al. | Research on data query optimization based on SparkSQL and MongoDB | |
US11086870B1 (en) | Multi-table aggregation through partial-group-by processing | |
US11386155B2 (en) | Filter evaluation in a database system | |
Munir et al. | A cost-based storage format selector for materialization in big data frameworks |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |