您好,登錄后才能下訂單哦!
[TOC]
1、Spark 1.0版本以后,Spark官方推出了Spark SQL。其實最早使用的,都是Hadoop自己的Hive查詢引擎;比如MR2,我們底層都是運行的MR2模型,底層都是基于Hive的查詢引擎。
2、后來Spark提供了Shark;再后來Shark被淘汰(Shark制約了Spark SQL的整體發(fā)展),推出了Spark SQL。Shark的性能比Hive就要高出一個數(shù)量級,而Spark SQL的性能又比Shark高出一個數(shù)量級。
3、SparkSQL的前身是Shark,給熟悉RDBMS但又不理解MapReduce的技術人員提供快速上手的工具,Hive應運而生,它是當時唯一運行在Hadoop上的SQL-on-Hadoop工具。但是MapReduce計算過程中大量的中間磁盤落地過程消耗了大量的I/O,降低的運行效率,為了提高SQL-on-Hadoop的效率,大量的SQL-on-Hadoop工具開始產(chǎn)生,其中表現(xiàn)較為突出的是:
MapR的Drill
Cloudera的Impala
Shark
4、但是Hive有個致命的缺陷,就是它的底層基于MR2,而MR2的shuffle又是基于磁盤的,因此導致Hive的性能異常低下。經(jīng)常出現(xiàn)復雜的SQL ETL,要運行數(shù)個小時,甚至數(shù)十個小時的情況。
5、Spark推出了Shark,Shark與Hive實際上還是緊密關聯(lián)的,Shark底層很多東西還是依賴于Hive,但是修改了內(nèi)存管理、物理計劃、執(zhí)行三個模塊,底層使用Spark的基于內(nèi)存的計算模型,從而讓性能比Hive提升了數(shù)倍到上百倍。
1、但是,隨著Spark的發(fā)展,對于野心勃勃的Spark團隊來說,Shark對于Hive的太多依賴(如采用Hive的語法解析器、查詢優(yōu)化器等等),制約了Spark的One Stack Rule Them All的既定方針,制約了Spark各個組件的相互集成,所以提出了SparkSQL項目。SparkSQL拋棄原有Shark的代碼,汲取了Shark的一些優(yōu)點,如內(nèi)存列存儲(In-Memory Columnar Storage)、Hive兼容性等,重新開發(fā)了SparkSQL代碼;由于擺脫了對Hive的依賴性,SparkSQL無論在數(shù)據(jù)兼容、性能優(yōu)化、組件擴展方面都得到了極大的方便,真可謂“退一步,海闊天空”。
2、Spark SQL的特點
1)、支持多種數(shù)據(jù)源:Hive、RDD、Parquet、JSON、JDBC等。
2)、多種性能優(yōu)化技術:in-memory columnar storage、byte-code generation、cost model動態(tài)評估等。
3)、組件擴展性:對于SQL的語法解析器、分析器以及優(yōu)化器,用戶都可以自己重新開發(fā),并且動態(tài)擴展。
數(shù)據(jù)兼容方面 不但兼容Hive,還可以從RDD、parquet文件、JSON文件中獲取數(shù)據(jù),未來版本甚至支持獲取RDBMS數(shù)據(jù)以及cassandra等NOSQL數(shù)據(jù);
性能優(yōu)化方面 除了采取In-Memory Columnar Storage、byte-code generation等優(yōu)化技術外、將會引進Cost Model對查詢進行動態(tài)評估、獲取最佳物理計劃等等;
組件擴展方面 無論是SQL的語法解析器、分析器還是優(yōu)化器都可以重新定義,進行擴展。
2014年6月1日Shark項目和SparkSQL項目的主持人Reynold Xin宣布:停止對Shark的開發(fā),團隊將所有資源放SparkSQL項目上,至此,Shark的發(fā)展畫上了句話,但也因此發(fā)展出兩個直線:SparkSQL和Hive on Spark。
其中SparkSQL作為Spark生態(tài)的一員繼續(xù)發(fā)展,而不再受限于Hive,只是兼容Hive;而Hive on Spark是一個Hive的發(fā)展計劃,該計劃將Spark作為Hive的底層引擎之一,也就是說,Hive將不再受限于一個引擎,可以采用Map-Reduce、Tez、Spark等引擎。
Shark的出現(xiàn),使得SQL-on-Hadoop的性能比Hive有了10-100倍的提高:
那么,擺脫了Hive的限制,SparkSQL的性能又有怎么樣的表現(xiàn)呢?雖然沒有Shark相對于Hive那樣矚目地性能提升,但也表現(xiàn)得非常優(yōu)異:
SparkSQL的表數(shù)據(jù)在內(nèi)存中存儲不是采用原生態(tài)的JVM對象存儲方式,而是采用內(nèi)存列存儲,如下圖所示:
1、該存儲方式無論在空間占用量和讀取吞吐率上都占有很大優(yōu)勢。
對于原生態(tài)的JVM對象存儲方式,每個對象通常要增加12-16字節(jié)的額外開銷,對于一個270MB的數(shù)據(jù),使用這種方式讀入內(nèi)存,要使用970MB左右的內(nèi)存空間(通常是2~5倍于原生數(shù)據(jù)空間);另外,使用這種方式,每個數(shù)據(jù)記錄產(chǎn)生一個JVM對象,如果是大小為200B的數(shù)據(jù)記錄,32G的堆棧將產(chǎn)生1.6億個對象,這么多的對象,對于GC來說,可能要消耗幾分鐘的時間來處理(JVM的垃圾收集時間與堆棧中的對象數(shù)量呈線性相關)。顯然這種內(nèi)存存儲方式對于基于內(nèi)存計算的Spark來說,很昂貴也負擔不起。
? 2、對于內(nèi)存列存儲來說,將所有原生數(shù)據(jù)類型的列采用原生數(shù)組來存儲,將Hive支持的復雜數(shù)據(jù)類型(如array、map等)先序化后并接成一個字節(jié)數(shù)組來存儲。這樣,每個列創(chuàng)建一個JVM對象,從而導致可以快速的GC和緊湊的數(shù)據(jù)存儲;額外的,還可以使用低廉CPU開銷的高效壓縮方法(如字典編碼、行長度編碼等壓縮方法)降低內(nèi)存開銷;更有趣的是,對于分析查詢中頻繁使用的聚合特定列,性能會得到很大的提高,原因就是這些列的數(shù)據(jù)放在一起,更容易讀入內(nèi)存進行計算。
在數(shù)據(jù)庫查詢中有一個昂貴的操作是查詢語句中的表達式,主要是由于JVM的內(nèi)存模型引起的。
Spark SQL在其catalyst模塊的expressions中增加了codegen模塊,對于SQL語句中的計算表達式,比如select num + num from t這種的sql,就可以使用動態(tài)字節(jié)碼生成技術來優(yōu)化其性能。
另外,SparkSQL在使用Scala編寫代碼的時候,盡量避免低效的、容易GC的代碼;盡管增加了編寫代碼的難度,但對于用戶來說,還是使用統(tǒng)一的接口,沒受到使用上的困難。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。