前言
大數(shù)據(jù)平臺(tái)中Hadoop的分布式文件系統(tǒng)(HDFS)之上形成了一種極具特色的技術(shù)群體譬重,那就是SQL查詢(xún)引擎腕巡。這就包括了Hive玄坦、Impala、Presto、Spark SQL等煎楣;在分布式數(shù)據(jù)庫(kù)HBase也具有Impala豺总、phoenix這樣的SQL外觀,可以通過(guò)SQL與HBase交互择懂;另外分布式關(guān)系模型數(shù)據(jù)庫(kù)(NewSQL)喻喳,例如:cockroachdb的sql layer、TiDB的tidb模塊等在自身架構(gòu)體系中不僅是查詢(xún)引擎困曙,也是SQL插入表伦、更新和刪除的SQL執(zhí)行引擎。
作為海量數(shù)據(jù)計(jì)算存儲(chǔ)平臺(tái)慷丽,特別容易提出的一個(gè)概念就是NoSQL蹦哼,可是從上面的發(fā)展看,不像No SQL么要糊,感覺(jué)像是:這個(gè)世界沒(méi)法NoSQL纲熏,以前我有篇文章,深入分析了關(guān)系模型的真正價(jià)值锄俄。
我把這篇文章中的一小段摘錄出來(lái)局劲,回顧一下關(guān)系模型是什么:
關(guān)系型模型之父Edgar F. Codd,在1970年發(fā)表了《大型共享數(shù)據(jù)庫(kù)數(shù)據(jù)的關(guān)系模型》
原始的關(guān)系模型:
(1)結(jié)構(gòu)(structure)
(2)完整性(integrity)
(3)操作(manipulation)
原始理論具體到實(shí)現(xiàn)再翻譯成我們好理解的描述:
結(jié)構(gòu):就是我們經(jīng)常要先對(duì)數(shù)據(jù)庫(kù)預(yù)先定義的表名和字段(名稱(chēng)奶赠、類(lèi)型)
完整性:就是表的主鍵不能為空鱼填,表與表之間的主外鍵關(guān)聯(lián)必須保證是完整的,外鍵一定是能找到主鍵的毅戈。
操作:那就是SQL表達(dá)式啦苹丸,SQL的子查詢(xún)就是典型的閉包(Closure),可以形成嵌套表達(dá)式苇经。
引用自:傳世的關(guān)系模型谈跛,巧奪天工的分布式數(shù)據(jù)庫(kù)設(shè)計(jì)
因此SQL只是關(guān)系模型的一種具體實(shí)現(xiàn)。我們只是在大數(shù)據(jù)領(lǐng)域需要替換關(guān)系型數(shù)據(jù)庫(kù)的存儲(chǔ)邏輯塑陵,使得數(shù)據(jù)庫(kù)更分布式化,更容易實(shí)現(xiàn)存儲(chǔ)架構(gòu)的擴(kuò)展蜡励。因?yàn)檫@是單機(jī)存儲(chǔ)與計(jì)算到了天花板后令花,必須橫向擴(kuò)展的硬需求,但這也并不是說(shuō)關(guān)系模型過(guò)時(shí)了凉倚!
實(shí)際上Hadoo的HDFS兼都、HBase提供的Java接口也好,Spark提供的Java稽寒、Scala扮碧、Python接口也好,這都需要使用者至少懂一門(mén)編程語(yǔ)言才行,Python雖然易學(xué)易懂慎王,但也只限于Spark的原生支持蚓土,而且Python好歹也是個(gè)面向?qū)ο缶幊陶Z(yǔ)言正規(guī)軍,至少也得讓使用者明白什么是面向?qū)ο蟀衫涤伲磕菍?duì)于科學(xué)家蜀漆、科研人員、數(shù)據(jù)分析師咱旱、數(shù)據(jù)運(yùn)維工程師确丢,學(xué)生,基本都是大數(shù)據(jù)的主要使用者吐限,編程接口的方式對(duì)于他們就極為不友好了鲜侥。這時(shí)候再看SQL,老少皆宜诸典,不分階層描函,大家好,才是真的好搂赋!對(duì)吧赘阀。
Hive-ON-Hadoop
在SQL-ON-Hadoop架構(gòu)中,Hive依然是成熟度最高SQL引擎脑奠,有些文章也把它叫做數(shù)倉(cāng)工具基公,總之Hive已經(jīng)從SQL解釋器發(fā)展成為獨(dú)立性很高的SQL引擎層,仍依賴(lài)Hadoop HDFS存儲(chǔ)層宋欺,但擺脫了執(zhí)行層Mapreduce計(jì)算引擎的束縛轰豆,形成可替換的計(jì)算引擎層,可以將MapReduce引擎替換成Tez齿诞、Spark酸休。
為什么要替換MapReduce呢?就是因?yàn)镸apReduce對(duì)數(shù)據(jù)寫(xiě)進(jìn)寫(xiě)出的方式太過(guò)生硬祷杈,直接用磁盤(pán)作為計(jì)算中間過(guò)程的數(shù)據(jù)存儲(chǔ)斑司,導(dǎo)致分布式并行處理的性能很差。并行計(jì)算在磁盤(pán)上進(jìn)行但汞,其實(shí)也是一把雙刃劍宿刮,不能一味地認(rèn)為Mapreduce性能差,對(duì)于超大規(guī)模數(shù)據(jù)量的批處理私蕾,內(nèi)存是放不下的僵缺,所有基于內(nèi)存模型的并行處理引擎,都會(huì)因?yàn)閮?nèi)存不夠踩叭,將需要處理的數(shù)據(jù)吐到磁盤(pán)上磕潮,這反而加重了I/O的吞吐翠胰,導(dǎo)致不佳的性能。但是在足夠的內(nèi)存條件下自脯,中小數(shù)據(jù)量的批處理上之景,基于內(nèi)存的計(jì)算引擎會(huì)非常快的給出結(jié)果冤今,所以這是必然趨勢(shì)闺兢。
Tez的性能比起MR很快,我在實(shí)際環(huán)境中也測(cè)試過(guò)戏罢,不僅是內(nèi)存計(jì)算帶來(lái)的性能提升屋谭,它在執(zhí)行數(shù)據(jù)處理前比MR引擎有自動(dòng)的優(yōu)化策略,以后會(huì)成為Hive的默認(rèn)執(zhí)行引擎龟糕,Hive 執(zhí)行引擎也可以替換成Spark桐磁,既Hive-on-Spark。但是我認(rèn)為在新項(xiàng)目中直接就是Spark-SQL就夠了讲岁,沒(méi)必要再搞個(gè)Hive我擂,因?yàn)榈讓佣际荢park。Hive-on-Spark的主要目標(biāo)是那些已經(jīng)部署實(shí)施的Hive系統(tǒng)缓艳,通過(guò)Spark對(duì)Mr的替換校摩,極大提升查詢(xún)分析速度。
如下圖所示:Hive依賴(lài)Hadoop阶淘,左邊是Hive SQL查詢(xún)過(guò)程衙吩,右邊是Hadooop協(xié)作過(guò)程。
第一階段:Hive接收UI的SQL查詢(xún)溪窒,進(jìn)入Driver和Compiler進(jìn)行SQL解析并生成執(zhí)行計(jì)劃坤塞。并發(fā)送執(zhí)行計(jì)劃給Hive執(zhí)行引擎(Execution engine)。
第二階段:主要是在Hive執(zhí)行引擎將執(zhí)行計(jì)劃形成階段DAG澈蚌,調(diào)度進(jìn)Hadoop摹芙。
第三階段:Hadoop的MR執(zhí)行引擎中實(shí)現(xiàn)Map和Reduce的任務(wù)執(zhí)行,并且將過(guò)程產(chǎn)生的臨時(shí)數(shù)據(jù)保留在HDFS宛瞄。
第四階段:最終計(jì)算結(jié)果由Hive執(zhí)行引擎從HDFS中取出浮禾,并發(fā)送結(jié)果到Driver,再由Driver返回結(jié)果給UI份汗。
Impala
曾經(jīng)Google公開(kāi)了兩篇論文伐厌,一篇涉及F1支持容錯(cuò)的分布式SQL數(shù)據(jù)庫(kù),在此篇論文的指引下裸影,出現(xiàn)了像PingCAP公司的開(kāi)源分布式關(guān)系數(shù)據(jù)庫(kù)TiDB,這都源自于Spanner/F1容錯(cuò)設(shè)計(jì)的簡(jiǎn)描述军熏。
另一篇關(guān)于Dremel的可擴(kuò)展的交互式即時(shí)查詢(xún)引擎轩猩,在此篇論文的啟發(fā)下,2012年發(fā)布了Hadoop之上的開(kāi)源、低延遲SQL查詢(xún)引擎Impala均践。
Impala有幾個(gè)特點(diǎn):
支持HDFS晤锹、HBase作為數(shù)據(jù)源。
復(fù)用HiveSQL方言彤委,使用Hive元數(shù)據(jù)服務(wù)鞭铆,因此Hive表一次定義,Hive焦影、Impala皆可使用车遂。
Impala的查詢(xún)延遲比Hive+mapreduce要低得多。
Impala架構(gòu)是無(wú)共享模式斯辰,因此支持系統(tǒng)級(jí)容錯(cuò)性和強(qiáng)大的可擴(kuò)張性舶担。
Impala也是基于內(nèi)存的計(jì)算引擎,多個(gè)處理階段的中間過(guò)程彬呻,數(shù)據(jù)會(huì)保存在內(nèi)存中衣陶,2.0版本之后支持大數(shù)據(jù)量?jī)?nèi)存與磁盤(pán)I/O數(shù)據(jù)交換。
Impala是以后臺(tái)服務(wù)的形成長(zhǎng)期運(yùn)行闸氮,一般推薦Impala服務(wù)在HDFS的DataNode節(jié)點(diǎn)上運(yùn)行剪况,保證計(jì)算盡量在本地讀取數(shù)據(jù),減少網(wǎng)絡(luò)傳輸蒲跨。
Impala是C++語(yǔ)言實(shí)現(xiàn)译断,可以充分利用機(jī)器內(nèi)存,單個(gè)Impala進(jìn)程不用像Java程序那樣财骨,受限于JVM垃圾回收機(jī)制的延遲影響镐作。
Impala具有一項(xiàng)高性能的查詢(xún)黑科技:底層虛擬機(jī)(Low Level Virtual Machine, LLVM)編譯查詢(xún)隆箩,可以將查詢(xún)方法編譯成優(yōu)化的機(jī)器碼该贾,提高CPU對(duì)代碼的執(zhí)行性能。
Impala架構(gòu)如下圖所示:impala后臺(tái)服務(wù)(Impalad)盡量在數(shù)據(jù)節(jié)點(diǎn)上運(yùn)行(HDFS的Datanode捌臊,DD杨蛋、HBase);每個(gè)Impalad包含了查詢(xún)規(guī)劃器(Query Planner)理澎、查詢(xún)規(guī)劃器(Query Coordinator)和查詢(xún)執(zhí)行器(Query Exec Engine)
第一步查詢(xún)規(guī)劃器用于解析由JDBC逞力、ODBC、impala-shell或者Thrift等客戶(hù)端請(qǐng)求的SQL語(yǔ)句糠爬,產(chǎn)生執(zhí)行計(jì)劃規(guī)劃器
第二步連接到當(dāng)前客戶(hù)端的查詢(xún)規(guī)劃器將執(zhí)行計(jì)劃將不同執(zhí)行部分分配到各個(gè)Impalad中寇荧。
第三部各個(gè)Impalad將獲取到的部分執(zhí)行計(jì)劃,并交給查詢(xún)執(zhí)行引擎执隧,訪問(wèn)本地HDFS DD或HBase數(shù)據(jù)揩抡,實(shí)現(xiàn)大規(guī)模并行處理(MPP)户侥,完成查詢(xún)處理后返回結(jié)果,由原計(jì)劃分發(fā)點(diǎn)實(shí)現(xiàn)匯聚與回應(yīng)客戶(hù)端結(jié)果峦嗤。
Impala VS Presto
架構(gòu)對(duì)比
2013年Facebook開(kāi)源了Presto蕊唐,支持標(biāo)準(zhǔn)ANSI SQL。Presto的特點(diǎn)特別適合與Impala做一個(gè)比較烁设。
首先如果把Impala比喻成一位用情專(zhuān)一的君子替梨,那么Presto就是處處留情的公子。Impala用于查詢(xún)的主要基礎(chǔ)存儲(chǔ)系統(tǒng)就是Hadoop HDFS與HBase装黑,我們?cè)倏纯碢resto都設(shè)計(jì)了多少種存儲(chǔ)連接:
Accumulo Connector |基于HDFS的K-V存儲(chǔ)
BigQuery Connector? |Google的大數(shù)據(jù)查詢(xún)引擎云服務(wù)
Cassandra Connector
Druid Connector | 實(shí)時(shí)分析型數(shù)據(jù)庫(kù)
Elasticsearch Connector
Hive Connector
Kafka Connector
Kudu Connector? ? |基于HDFS的列式快速分析存儲(chǔ)系統(tǒng)
Local File Connector
Memory Connector |直接在內(nèi)存中建立數(shù)據(jù)表進(jìn)行操作
MongoDB Connector
MySQL Connector
Oracle Connector
PostgreSQL Connector
Redis Connector
SQL Server Connector
Thrift Connector? ? |遠(yuǎn)程過(guò)程調(diào)用RPC框架
......
但是有一點(diǎn)我感到很不解副瀑,Presto都支持那么多存儲(chǔ)系統(tǒng)和框架了,而且最早的設(shè)計(jì)初衷就是為了Hadoop HDFS的高效查詢(xún)曹体,既然Impala都是直接支持HBase了俗扇,為什么Presto不支持HBase呢?有了解情況的朋友還希望給予指點(diǎn)箕别。如下圖所示:
其次铜幽,Impala更像是一個(gè)傳統(tǒng)的大規(guī)模并行處理(MPP)數(shù)倉(cāng)工具,每個(gè)進(jìn)程都是獨(dú)立接受客戶(hù)端請(qǐng)求的串稀,客戶(hù)端連接到哪個(gè)服務(wù)除抛,該服務(wù)就作為分布式調(diào)度者,大家可以看看上篇中的Impala架構(gòu)圖母截。
但是Presto就是一個(gè)標(biāo)準(zhǔn)的主從架構(gòu)了到忽,客戶(hù)端要先與主節(jié)點(diǎn)打交道,主節(jié)點(diǎn)再將SQL解釋后的執(zhí)行計(jì)劃分配到不同的work節(jié)點(diǎn)去執(zhí)行清寇,并由一個(gè)work節(jié)點(diǎn)作為結(jié)果匯聚返回節(jié)點(diǎn)喘漏,如下圖所示:
最后,我們?cè)倏纯碔mpala和Presto在SQL解釋华烟、優(yōu)化和調(diào)度之間的對(duì)比翩迈。如下圖所示:左邊是Impala架構(gòu),右邊是Presto架構(gòu)盔夜。
上篇已經(jīng)描述過(guò)Impala主要是任意連接客戶(hù)端的Impalad后臺(tái)服務(wù)负饲,接收SQL請(qǐng)求,解析SQL并制定執(zhí)行計(jì)劃后喂链,由當(dāng)前節(jié)點(diǎn)在Query Coordinator階段對(duì)執(zhí)行計(jì)劃各個(gè)部分進(jìn)行調(diào)度分配返十,再由集群其他Impalad后臺(tái)服務(wù)根據(jù)調(diào)度進(jìn)入Query Exec Engine階段實(shí)現(xiàn)并行處理。最終結(jié)果還是匯聚到調(diào)度節(jié)點(diǎn)反饋客戶(hù)端椭微。
Presto獲取用戶(hù)提交的SQL查詢(xún)洞坑,首先進(jìn)行SQL語(yǔ)句解析( Parser),接著形成邏輯計(jì)劃相關(guān)對(duì)象(Planner)放入線程池蝇率,最后由調(diào)度器(Scheduler)對(duì)邏輯計(jì)劃生成的SubPlan提交到多個(gè)Work節(jié)點(diǎn)上執(zhí)行迟杂。
其他特性對(duì)比
Presto也是完全基于內(nèi)存的并行計(jì)算匈仗,注意內(nèi)存保護(hù),根據(jù)數(shù)據(jù)量情況逢慌,為每個(gè)節(jié)點(diǎn)設(shè)置合適的內(nèi)存大小,否則大數(shù)據(jù)量情況下间狂,內(nèi)存溢出就是家常便飯攻泼;Impala2.0之后支持內(nèi)存不夠情況,數(shù)據(jù)吐給磁盤(pán)鉴象,雖然有了可靠性保護(hù)忙菠,但是內(nèi)存與磁盤(pán)的I/O交換會(huì)帶來(lái)更慢的吞吐。
Presto由調(diào)度節(jié)點(diǎn)(Coordinator)和注冊(cè)與發(fā)現(xiàn)節(jié)點(diǎn)(Discovery Service)實(shí)現(xiàn)SQL執(zhí)行的集群調(diào)度管理纺弊,由于Coordinator和Discovery Service都是單節(jié)點(diǎn)部署牛欢,可能會(huì)因?yàn)镃oordinator故障,產(chǎn)生多個(gè)Coordinator服務(wù)淆游,導(dǎo)致集群的腦裂問(wèn)題傍睹,因此一般建議都是Coordinator和Discovery Service放在一個(gè)節(jié)點(diǎn)上部署,形成Discovery對(duì)Coordinator的唯一性指定犹菱,然后再做成一主一備兩個(gè)節(jié)點(diǎn)形成HA拾稳,這樣主節(jié)點(diǎn)服務(wù)掛掉,備集群Work都連接到備節(jié)點(diǎn)上腊脱,實(shí)現(xiàn)主備節(jié)點(diǎn)的熱替換访得。
Impala的后臺(tái)服務(wù)因?yàn)槭菬o(wú)共享的架構(gòu)模式,非常適合集群節(jié)點(diǎn)的無(wú)限擴(kuò)張陕凹,但往往需要在Impala集群之上安裝一個(gè)客戶(hù)端請(qǐng)求負(fù)載均衡器悍抑,實(shí)現(xiàn)對(duì)Impalad服務(wù)的負(fù)載調(diào)度。
最后就是Impala的架構(gòu)更適合于計(jì)算與存儲(chǔ)放在一起的就近讀取原則杜耙,有效防止網(wǎng)絡(luò)傳輸數(shù)據(jù)的損耗搜骡;但是Presto的架構(gòu)更傾向于計(jì)算與存儲(chǔ)分離,存儲(chǔ)系統(tǒng)多樣化的支持泥技,雖然使自身變得靈活浆兰,適配性高,但是默認(rèn)讀數(shù)據(jù)源并不是采用就近讀取原則珊豹,導(dǎo)致計(jì)算訪問(wèn)數(shù)據(jù)都是遠(yuǎn)程操作簸呈,例如:在復(fù)雜的大數(shù)據(jù)集Join操作,會(huì)導(dǎo)致嚴(yán)重的網(wǎng)絡(luò)傳輸?shù)男阅軗p耗店茶。
Spark SQL
Spark架構(gòu)
作為大數(shù)據(jù)處理計(jì)算的大一統(tǒng)軟件棧Spark蜕便,或?qū)⑹谴髷?shù)據(jù)處理領(lǐng)域里面的Spring framework。我們從下圖中可以看到Spark core之上具有了四種面向不同計(jì)算領(lǐng)域或方式的Spark模塊贩幻,Spark streaming模塊面向?qū)崟r(shí)流計(jì)算轿腺,具體方式采用微批處理两嘴;MLlib模塊面向Spark的機(jī)器學(xué)習(xí)庫(kù),尤其是Spark默認(rèn)對(duì)Python的支持憔辫,成為Python開(kāi)發(fā)者接入Hadoop生態(tài)平臺(tái)的絕佳入口;GraphX面向圖處理仿荆,有了GraphX,對(duì)于社交網(wǎng)絡(luò)锦亦、知識(shí)庫(kù)杠园、超文本關(guān)聯(lián)度分析栖茉、傳染病傳播預(yù)測(cè)等應(yīng)用領(lǐng)域亲配,都可以使用Spark來(lái)處理。
我們本次主要分析了解到是Spark SQL,一個(gè)將不同來(lái)源數(shù)據(jù)進(jìn)行關(guān)系結(jié)構(gòu)化再進(jìn)行計(jì)算處理的模塊。
DataFrame
示例
Spark SQL可以支持從很多種數(shù)據(jù)源的結(jié)構(gòu)化抽象领跛,Spark SQL從數(shù)據(jù)源中抽取數(shù)據(jù)集后抽象成一種具有schema結(jié)構(gòu)的rdd對(duì)象:DataFrame胧瓜,有點(diǎn)類(lèi)似拿到了一個(gè)Hibernate的Session與實(shí)體對(duì)象的合體(類(lèi)似劫拢,可能不太恰當(dāng)),可以執(zhí)行類(lèi)似下面例子中DataFrame(df)的查詢(xún)操作玄窝。
大家可以看到DataFrame實(shí)際上就是將數(shù)據(jù)源結(jié)構(gòu)化為SQL表列。因?yàn)镈ataFreame也需要進(jìn)行schema定義。類(lèi)似下圖:
支持的數(shù)據(jù)源
Spark SQL可以從哪些數(shù)據(jù)源建立DataFrame結(jié)構(gòu)化模型呢盲厌?
json:Spark自動(dòng)推斷數(shù)據(jù)結(jié)構(gòu)和類(lèi)型
Parquet? ? Spark的默認(rèn)數(shù)據(jù)源屡限,自動(dòng)保存schema
Hive table? Spark支持直接讀取Hive數(shù)據(jù)
JDBC? Spark通過(guò)Jdbc驅(qū)動(dòng)拉取Rdbms數(shù)據(jù)表數(shù)據(jù)
CSV? ? 可根據(jù)CSV行頭定義列
等等......
架構(gòu)
如下圖所示:
1.客戶(hù)端根據(jù)自己的目標(biāo)語(yǔ)言啊央,Java、Python趣苏、Scala進(jìn)行Spark SQL操作食磕。
2.Spark SQL訪問(wèn)上述的各種數(shù)據(jù)源,創(chuàng)建DataFrame對(duì)象喳挑。
3.通過(guò)對(duì)DataFrame API的調(diào)用彬伦,實(shí)現(xiàn)SQL方式操作數(shù)據(jù)(查詢(xún)、聚合伊诵、分組等媚朦、連接等)。
4.Spark SQL將SQL操作語(yǔ)句調(diào)入Catalyst Optimizer引擎形成執(zhí)行計(jì)劃日戈。
5.執(zhí)行計(jì)劃進(jìn)入Spark處理引擎询张,由分布在不同節(jié)點(diǎn)的Spark集群任務(wù)并行處理SchemaRDD(DataFrame)。
Catalyst優(yōu)化器
Spark SQL執(zhí)行的SQL語(yǔ)句在Catalyst優(yōu)化器中經(jīng)歷了邏輯計(jì)劃浙炼、物理計(jì)劃兩個(gè)過(guò)程份氧,邏輯計(jì)劃過(guò)程主要依賴(lài)Antlr。首先SQL語(yǔ)句在unresolved logical plan階段由antlr轉(zhuǎn)換成抽象語(yǔ)法樹(shù)弯屈,這時(shí)候會(huì)根據(jù)Catalog中(存儲(chǔ)了所有的表信息蜗帜、DataFrame信息)的元數(shù)據(jù),對(duì)unresolved logical plan進(jìn)行表達(dá)式解析资厉,確定表厅缺、列都存在后,才會(huì)形成真正的resolved logical plan,最后交付Catalyst優(yōu)化器進(jìn)行優(yōu)化邏輯計(jì)劃(Optimized logical plan)湘捎。如下圖所示:
轉(zhuǎn)換成功的邏輯計(jì)劃將進(jìn)入物理計(jì)劃階段诀豁,Optimized logical plan會(huì)分解為多個(gè)物理計(jì)劃(Physical Plans),最終進(jìn)入代價(jià)模型(Cost Model)窥妇,根據(jù)資源開(kāi)銷(xiāo)成本舷胜,去選擇最佳的物理計(jì)劃(Best Physical Plan),最終進(jìn)入到集群中運(yùn)行活翩。如下圖所示:
Dataset
在Dataframe之后Spark推出了一個(gè)新的數(shù)據(jù)抽象:DataSet烹骨,DataSet可以理解為DataFrame的擴(kuò)展,對(duì)象類(lèi)型更為顯性材泄,這種優(yōu)勢(shì)就是在開(kāi)發(fā)起來(lái)具有更友好的API風(fēng)格沮焕,更適合工程化管理。
例如:我們定義了一個(gè)叫Flight的Dataset實(shí)體類(lèi)
我們可以將DataFrame轉(zhuǎn)換成Flight class類(lèi)型的Dataset拉宗,這時(shí)候的變量flights就是Dataset[Flight]強(qiáng)類(lèi)型了遇汞,即具有類(lèi)型安全檢查,也具有Dataframe的查詢(xún)優(yōu)化特性簿废。
Dataset在編譯時(shí)就會(huì)檢查類(lèi)型是否符合規(guī)范。Dataset僅適合用于基于JVM的Scala络它、Java族檬,通過(guò)case類(lèi)或Javabeans指定類(lèi)型。
當(dāng)調(diào)用DataFrame的API時(shí)化戳,返回的結(jié)果結(jié)構(gòu)就是Row類(lèi)型单料;當(dāng)使用DatasetAPI時(shí),就可以將將Row格式的每一行轉(zhuǎn)換為指定的業(yè)務(wù)領(lǐng)域?qū)ο螅╟ase類(lèi)或Java類(lèi))
Spark集群架構(gòu)
我們可以將Hive点楼、Impala扫尖、Presto理解為比較獨(dú)立的數(shù)倉(cāng)工具,在上一篇中Impala和Presto的對(duì)比掠廓,我們甚至可以看到它們倆具有獨(dú)立的分布式架構(gòu)换怖。Hive則是Hadoop生態(tài)獨(dú)立性很高SQL解析與執(zhí)行工具,插接Mapreduce蟀瞧、Spark沉颂、Tez計(jì)算引擎,高度依賴(lài)HDFS存儲(chǔ)系統(tǒng)悦污。
反觀Spark SQL铸屉,它并不獨(dú)立,應(yīng)是Spark平臺(tái)上的一組模塊切端,徹底與Spark糅合在一起彻坛,因此談Spark SQL的分布式架構(gòu),其實(shí)就是在講Spark架構(gòu)。我們從下圖可以看到Spark架構(gòu)的特征昌屉,在集群計(jì)算資源調(diào)度方面與Spark無(wú)關(guān)钙蒙,主要依賴(lài)Hadooop Yarn或者M(jìn)esos實(shí)現(xiàn)分布式集群計(jì)算資源的調(diào)度管理。
同理Spark SQL解析完成物理計(jì)劃后就完成交由Spark集群進(jìn)行并行任務(wù)處理怠益,Spark集群中Driver提交作業(yè)仪搔、實(shí)現(xiàn)調(diào)度,Executor具體執(zhí)行任務(wù)蜻牢、返回結(jié)果烤咧。
Executor中通過(guò)多線程方式運(yùn)行任務(wù)(Task),而且Executor通過(guò)堆內(nèi)內(nèi)存抢呆、堆外內(nèi)存管理煮嫌,實(shí)現(xiàn)高性能的內(nèi)存計(jì)算,這點(diǎn)是Spark性能上優(yōu)于Mapreduce將中間過(guò)程數(shù)據(jù)寫(xiě)入磁盤(pán)導(dǎo)致性能慢的關(guān)鍵原因之一抱虐。