大數(shù)據(jù)時(shí)代,中大型企業(yè)數(shù)據(jù)的爆發(fā)式增長(zhǎng),幾乎每天都能產(chǎn)生約 100GB 到 10TB 的數(shù)據(jù)。而企業(yè)數(shù)據(jù)分系統(tǒng)構(gòu)建與擴(kuò)張,導(dǎo)致不同應(yīng)用場(chǎng)景下大數(shù)據(jù)冗余嚴(yán)重。行業(yè)亟需一個(gè)高效、統(tǒng)一的融合數(shù)倉(cāng),從海量數(shù)據(jù)中快速獲取有效信息,從而洞察機(jī)遇、規(guī)避風(fēng)險(xiǎn)。
在這樣的現(xiàn)狀下,CarbonData 誕生了,作為首個(gè)由中國(guó)貢獻(xiàn)給Apache社區(qū)的頂級(jí)開(kāi)源項(xiàng)目,CarbonData 提供了一種新的融合數(shù)據(jù)存儲(chǔ)方案,以一份數(shù)據(jù)同時(shí)支持多種大數(shù)據(jù)應(yīng)用場(chǎng)景,并通過(guò)豐富的索引技術(shù)、字典編碼、列存等特性提升了 IO 掃描和計(jì)算性能,實(shí)現(xiàn)了PB數(shù)據(jù)級(jí)的秒級(jí)響應(yīng)。
為了幫助開(kāi)發(fā)者深入了解并學(xué)習(xí)這項(xiàng)大數(shù)據(jù)開(kāi)源技術(shù),華為 CarbonData PMC 陳亮牽頭,攜手技術(shù)社區(qū)的核心開(kāi)發(fā)者及合作伙伴,舉辦了一場(chǎng)Apache CarbonData+Spark 主題的技術(shù)交流會(huì),就 CarbonData+Spark 的重要特性和使用介紹,做了全面而細(xì)致的分享,本文簡(jiǎn)單整理了其中的部分精彩內(nèi)容,同時(shí),作為本次活動(dòng)的承辦方,InfoQ整理上傳了所有講師的演講PPT+演講視頻,感興趣的同學(xué)可以免費(fèi)獲取現(xiàn)場(chǎng)完整資料 。
Spark SQL的發(fā)展史概述(講師PPT下載)來(lái)自美國(guó)Databricks公司的范文臣首先講述了Spark SQL的發(fā)展史,范文臣同時(shí)也是Apache Spark PMC member,主導(dǎo) Spark SQL 一些主要功能的設(shè)計(jì)和研發(fā),定期審計(jì)項(xiàng)目代碼質(zhì)量等?,F(xiàn)場(chǎng),他將Spark SQL過(guò)去的發(fā)展分為四個(gè)階段:
2009年,著名的Spark框架誕生。它是一個(gè)圍繞速度、易用性和復(fù)雜分析構(gòu)建的大數(shù)據(jù)處理框架,由伯克AMP實(shí)驗(yàn)室創(chuàng)建。相比于當(dāng)時(shí)流行的Hadoop,Spark提供了更高效的MapReduce模型,減少數(shù)據(jù)落地,也降低了編程難度。2011年,Spark團(tuán)隊(duì)將Hive的底層物理執(zhí)行模塊從Hadoop切換成Shark,啟動(dòng)了Shark項(xiàng)目。然而,由于Hive自身的代碼復(fù)雜性以及和Hadoop MapReduce的耦合,Shark的開(kāi)發(fā)舉步維艱,進(jìn)展緩慢。2014年,Spark團(tuán)隊(duì)舍棄Shark,重新建立了一套完整的查詢(xún)框架Catalyst。Catalyst利用了函數(shù)式風(fēng)格的不可變特性,使Query Plan不可變,優(yōu)化器通過(guò)遍歷優(yōu)化策略生成新的 Query Plan。這樣優(yōu)化規(guī)則之間的影響更容易理解,提升了代碼的可讀性和可維護(hù)性,也方便了新特性的開(kāi)發(fā)。下圖為Spark SQL控制框架: 2015年,Spark團(tuán)隊(duì)提出了鎢絲計(jì)劃,通過(guò)建立Tungsten格式、后端優(yōu)化、代碼生成等手段,將Spark的查詢(xún)性能和執(zhí)行速度提升到了一個(gè)新的臺(tái)階。2017年,持續(xù)探索中……那么,沿著查詢(xún)性能這條路,Spark的未來(lái)還會(huì)有哪些優(yōu)化方向?范文臣在最后的演講中總結(jié)到:Spark的愿景是管理各種不同性質(zhì)數(shù)據(jù)集和數(shù)據(jù)源的大數(shù)據(jù)處理的需求。Spark這樣一個(gè)角色,只關(guān)注于計(jì)算層,快速查詢(xún)處理是Spark唯一的衡量標(biāo)準(zhǔn),也是未來(lái)不變的發(fā)展方向。也因此,在之后的Spark2.3里面,在計(jì)算框架下如何更快的和儲(chǔ)存系統(tǒng)橋接、Spark代碼生成都是未來(lái)著重關(guān)注的方向。
CarbonData應(yīng)用實(shí)踐+2.0新技術(shù)規(guī)劃介紹 (講師PPT下載)CarbonData誕生之初是希望以一份數(shù)據(jù)去滿(mǎn)足企業(yè)各種各樣的場(chǎng)景需求,包括詳單過(guò)濾和海量數(shù)倉(cāng)以及數(shù)據(jù)集式操作等。那么,開(kāi)發(fā)者該如何正確使用CarbonData技術(shù)?華為CarbonData總設(shè)計(jì)師李昆結(jié)合實(shí)際案例,詳細(xì)講解了CarbonData應(yīng)用實(shí)踐+2.0新技術(shù)規(guī)劃。
CarbonData大數(shù)據(jù)生態(tài)Carbondata在數(shù)據(jù)查詢(xún)方面選擇和Spark結(jié)合,據(jù)李昆現(xiàn)場(chǎng)介紹,Carbondata+Spark可以打造一個(gè)相對(duì)于傳統(tǒng)系統(tǒng)來(lái)說(shuō),更好的交互分析體驗(yàn),目前Carbondata和Spark1.5、1.6、2.1,Hive,Presto都做了集成,未來(lái)還將對(duì)Spark2.2做支持;在接口方面,Carbondata提供SQL接口,也支持Spark DataFrame API;在操作方面,支持查詢(xún)、數(shù)據(jù)管理如批量入庫(kù)、更新、刪除等操作。
隨后,李昆就CarbonData索引建立、CarbonData表格與物理存儲(chǔ)、SQL引擎對(duì)接、數(shù)據(jù)管理過(guò)程等技術(shù)內(nèi)容做了詳細(xì)介紹。由于篇幅限制,本文不在此介紹,感興趣的讀者可以下載講師PPT對(duì)CarbonData的存儲(chǔ)原理進(jìn)行深入了解。
成功案例介紹隨后,李昆通過(guò)電信詳單分析場(chǎng)景的舉例介紹,詳細(xì)說(shuō)明CarbonData如何以一份數(shù)據(jù)支持多種應(yīng)用場(chǎng)景的。李昆表示,在電信跟金融領(lǐng)域經(jīng)常需要明細(xì)數(shù)據(jù)分析,優(yōu)化之前,老的系統(tǒng)需要用Impala和Hbase兩個(gè)系統(tǒng),建立4個(gè)二級(jí)索引才可以完成業(yè)務(wù)需要的性能。這其中,Impala用來(lái)做報(bào)表輸出,Hbase做關(guān)鍵維度查詢(xún)。這兩個(gè)系統(tǒng)有各自存在不足:Impala沒(méi)有辦法很好的擴(kuò)展,HBase要做很多二級(jí)索引,無(wú)法使用yarn統(tǒng)一資源管理,只能是一個(gè)個(gè)集群?jiǎn)为?dú)維護(hù)。
用Carbondata+Spark數(shù)據(jù)優(yōu)化后,可以解決既要點(diǎn)查又要處理報(bào)表的情況。下圖是一個(gè)從2000億到1萬(wàn)億的性能測(cè)試數(shù)據(jù),Q1是過(guò)濾查詢(xún),Q2也是過(guò)濾查詢(xún),Q1跟Q2數(shù)據(jù)查詢(xún)因?yàn)橛昧薈arbondata索引,需要掃描的數(shù)據(jù)不會(huì)增長(zhǎng)很多,數(shù)據(jù)量增長(zhǎng)5倍,查詢(xún)時(shí)間增長(zhǎng)不到1倍。第三個(gè)查詢(xún)是full scan查詢(xún),主要考察的是spark和carbon的可擴(kuò)展性,測(cè)試過(guò)程中發(fā)現(xiàn)擴(kuò)展性是非常線(xiàn)性的,scalability很好。
CarbonData2.0未來(lái)規(guī)劃現(xiàn)在,Carbondata的主要特性是對(duì)多場(chǎng)景的支持,不過(guò)在大數(shù)據(jù)時(shí)代,更多的場(chǎng)景正撲面而來(lái)。包括SQL分析、時(shí)間序列分析、位置軌跡、文本檢索、圖查詢(xún)和機(jī)器學(xué)習(xí)等。這就需要Carbondata2.0在各領(lǐng)域的應(yīng)用上有更多的準(zhǔn)備。包括:
入庫(kù)方面,需要考慮實(shí)時(shí)事件的流式入庫(kù)、歷史事件的批量入庫(kù)等;存儲(chǔ)方面分三層,一層是界面,每一個(gè)領(lǐng)域有自己的術(shù)語(yǔ),會(huì)針對(duì)領(lǐng)域常見(jiàn)操作做些SQL上的擴(kuò)展;二是數(shù)據(jù)組織層,對(duì)不同領(lǐng)域做不同的分區(qū)、索引和預(yù)處理等,以便于它更高效地存儲(chǔ)領(lǐng)域數(shù)據(jù);三是存儲(chǔ)格式層,Carbondata目前是列存,為了支撐更多查詢(xún)和分析,數(shù)據(jù)格式本身也需要具有擴(kuò)展能力,比如行存、時(shí)序、面向AI的格式等;Spark 2.2 核心特性CBO介紹(講師PPT下載)在Spark SQL的Catalyst優(yōu)化器中,許多基于規(guī)則的優(yōu)化技術(shù)已經(jīng)實(shí)現(xiàn),但優(yōu)化器本身仍然有很大的改進(jìn)空間。Spark 2.2在Spark SQL引擎內(nèi)添加了一個(gè)基于成本的優(yōu)化器框架,此框架通過(guò)可靠的統(tǒng)計(jì)和精確的估算,能夠在以下領(lǐng)域做出好的判定:選擇散列連接操作的正確構(gòu)建端,選擇正確的連接算法,調(diào)整連接的順序等等,這個(gè)基于成本的優(yōu)化器就是CBO。據(jù)華為研究工程師王振華介紹,CBO的目標(biāo)是希望優(yōu)化器能夠自動(dòng)為用戶(hù)選擇最優(yōu)的執(zhí)行計(jì)劃,要達(dá)到這件事情,需要以下三個(gè)步驟:
第一步收集、推斷和傳播關(guān)于源/中間數(shù)據(jù)的表/列統(tǒng)計(jì)信息。用戶(hù)運(yùn)行 ANALYZE TABLE 命令會(huì)收集表格信息比如表的行數(shù)、大小,列的統(tǒng)計(jì)信息比如最大值、最小值、不同值個(gè)數(shù)等,并將這些信息存儲(chǔ)到metastore里面。
第二步Cardinality Estimation,根據(jù)收集到的信息,計(jì)算每個(gè)操作符的成本,包括輸出行數(shù)、輸出大小等。如做filter時(shí)寫(xiě)一個(gè)過(guò)濾條件,給定的條件會(huì)基于條件里面涉及列的統(tǒng)計(jì)信息,估算過(guò)濾條件執(zhí)行完了以后,Operator有多少數(shù)據(jù)。
如下圖,為一個(gè)A小于等于某數(shù)字的估算,如果A的value比A的最小值更小,或者是比A的最大值更大,那么過(guò)濾率肯定是0或者100%,當(dāng)落在定義域中間的時(shí)候,假設(shè)是均勻分布,概率則是A.min到B的區(qū)間所占A的定義域的百分比,這個(gè)是Filter條件最終的selectivity,有了selectivity,即可再相應(yīng)的更新filter以后的統(tǒng)計(jì)信息。
第三步根據(jù)成本計(jì)算,選擇最優(yōu)的查詢(xún)執(zhí)行計(jì)劃。通過(guò)建造方選擇(Build Side Selection)、散列連接實(shí)現(xiàn):廣播與洗牌(Hash Join Implementation: Broadcast vs. Shuffle)、多路連接重新排序(Multi-way Join Reorder)、連接成本計(jì)算公式(Join Cost Formula)四個(gè)方面闡述了最優(yōu)計(jì)劃的選擇過(guò)程。
其中,在多路連接重新排序方法上,采用了動(dòng)態(tài)規(guī)劃算法。以四表連接為例,首先,將所有項(xiàng)(基本連接節(jié)點(diǎn))放到0級(jí);然后,從第0級(jí)的計(jì)劃中構(gòu)建所有的兩表連接;第三,從以前的層級(jí)(單節(jié)點(diǎn)和兩表連接)中構(gòu)建出可能的三表連接;最后,構(gòu)建所有的4路連接,并在其中選出最優(yōu)的計(jì)劃。而在構(gòu)建m-路徑連接時(shí),只需保留同一組m項(xiàng)的最佳計(jì)劃(最優(yōu)子解決方案)。如,對(duì)于A、B、C的三表連接順序,只保留三個(gè)候選計(jì)劃:(A J B)J C,(A J C)J B和(B J C)J A 當(dāng)中最優(yōu)的計(jì)劃。
Join cost計(jì)算方式如下,首先Cost一般來(lái)說(shuō)傳統(tǒng)的數(shù)據(jù)庫(kù)里是基于CPU和IO,這兩個(gè)Cost是線(xiàn)性加合。在Spark中,用Cardinality模擬CPU的開(kāi)銷(xiāo),用size模擬IO的開(kāi)銷(xiāo)。
王振華最后介紹到,華為在2016年7月份開(kāi)始將CBO貢獻(xiàn)給Spark社區(qū),并建立了umbrella ticket - SPARK-16026。截至目前為止,創(chuàng)建了超過(guò)40個(gè)sub-tasks、提交了50余個(gè)pull requests并被合入,同時(shí)吸引了十余個(gè)社區(qū)貢獻(xiàn)者的參與。
CBO的第一個(gè)版本已經(jīng)在Spark 2.2中發(fā)布,感興趣的開(kāi)發(fā)者和使用者,如要使用CBO,可以在收集統(tǒng)計(jì)信息之后,打開(kāi)spark.sql.cbo.enable來(lái)使用CBO。
Partition 功能詳解+上汽實(shí)踐分享(講師PPT下載)CarbonData的partition特性將在Apache CarbonData 1.2.0版本里正式發(fā)布,此特性將顯著提升大數(shù)據(jù)查詢(xún)性能。上汽集團(tuán)大數(shù)據(jù)將CarbonData作為平臺(tái)基礎(chǔ)組件,以應(yīng)對(duì)迅猛增長(zhǎng)的數(shù)據(jù)量,那么上汽集團(tuán)在使用CarbonData過(guò)程中遇到了哪些問(wèn)題?上汽集團(tuán)大數(shù)據(jù)平臺(tái)開(kāi)發(fā)經(jīng)理曹魯就CarbonData的partition特性以及上汽集團(tuán)在CarbonData項(xiàng)目的實(shí)踐和測(cè)試數(shù)據(jù)做了分享。
曹魯首先介紹了文件結(jié)構(gòu),索引生成過(guò)程,初次性能測(cè)試等主題內(nèi)容,引出Partition特性帶來(lái)改變,主要包括兩點(diǎn):1、數(shù)據(jù)將基于Partition列更為集中存儲(chǔ),查詢(xún)時(shí)可過(guò)濾掉大量block,減少spark task數(shù)量;2、可以使其他列在排序中更靠前,提升查詢(xún)性能。
Partition Table的數(shù)據(jù)加載及查詢(xún)過(guò)程詳解隨后,曹魯詳細(xì)介紹了CarbonData Partition相關(guān)的DDL語(yǔ)法,如Create Partition Table、Show Partition等,以及CarbonData Partition Table的數(shù)據(jù)加載以及查詢(xún)過(guò)程。下圖可以很清晰的看到CarbonData Partition的整個(gè)數(shù)據(jù)加載過(guò)程。
關(guān)于CarbonData Partition Table查詢(xún)過(guò)程,大概分為兩個(gè)部分:
根據(jù)SQL中的過(guò)濾條件=, <=, <, >, >=, in, not in以及表達(dá)式右值確定命中的partitionId如果有其他在排過(guò)序的維度列有過(guò)濾條件,則在driver端根據(jù)B-tree索引獲取blocklet 所在的文件名,如沒(méi)有則獲取全部,再根據(jù)文件名中的partitionId,篩選得到需要讀取的文件,最后再下發(fā)spark task進(jìn)行讀??;之后,曹魯就Partition的新增(add)、拆分(split)及刪除(drop)功能的語(yǔ)法和實(shí)現(xiàn)過(guò)程展開(kāi)了分析,其中重點(diǎn)區(qū)分了Drop Partition但保留數(shù)據(jù)RangePartition/ListPartition兩種Drop Partition類(lèi)型的不同語(yǔ)法與實(shí)現(xiàn),感興趣的讀者可以下載講師PPT深入了解。
上汽在CarbonData項(xiàng)目的實(shí)踐分享在案例分享環(huán)節(jié),曹魯以上汽的數(shù)據(jù)作為測(cè)試數(shù)據(jù),分析了CarbonData Partition table和非Partition table條件下的加載性能和查詢(xún)性能對(duì)比。并給出了CarbonData Partition的性能調(diào)優(yōu)建議。本文為大家展示其中的無(wú)排序維度列作為過(guò)濾條件,有partition列上的范圍過(guò)濾條件的聚合查詢(xún)情況的對(duì)比結(jié)果,如圖不難看出,原始查詢(xún)方式的耗時(shí)是添加partition性能查詢(xún)方式耗時(shí)的25倍。
曹魯給出的CarbonData Partition的性能調(diào)優(yōu)建議:1、 選擇最合適的Partition列;2、盡可能的使用Partition列作為過(guò)濾條件,例如Partition列為A,開(kāi)發(fā)者根據(jù)業(yè)務(wù)需求在Column B上有篩選條件,但注意到A與B列之間存在某種固定的mapping關(guān)系,這時(shí)就可以根據(jù)B列的過(guò)濾條件再新增一個(gè)partition列的過(guò)濾條件,以提高查詢(xún)效率。
現(xiàn)場(chǎng)精彩問(wèn)答整理Q: 客戶(hù)在使用Spark時(shí)不愿意編寫(xiě)代碼,更喜歡給他一個(gè)頁(yè)面能能夠直接生成SQL,Spark后面會(huì)不會(huì)更多的偏向于業(yè)務(wù)人員做一些更易應(yīng)用的東西出來(lái),比如可以直接出來(lái)一個(gè)頁(yè)面?
A:Spark本身不會(huì)往這方面走,因?yàn)镾park只專(zhuān)注于做計(jì)算這層,這個(gè)模式一般是另外一個(gè)項(xiàng)目,比如有項(xiàng)目zpplin是專(zhuān)門(mén)做供應(yīng)GIU的,可以在zpplin上面調(diào)Spark的一些接口,這些會(huì)單獨(dú)立項(xiàng),而不是在Spark里面做。
Q:剛才提到carbon有一個(gè)目標(biāo),能夠盡量多的支持各種場(chǎng)景,目前我們也做過(guò)一些測(cè)試,某些特定情況下,不同的場(chǎng)景可能在響應(yīng)速度和并發(fā)性上有比較大的差距,這一點(diǎn)后面有沒(méi)有改善?
A:這方面需要跟Spark一起聯(lián)合做優(yōu)化,因?yàn)镾park是端到端的,從元數(shù)據(jù)查詢(xún)到SQL優(yōu)化到DAG調(diào)度執(zhí)行,有很多中間過(guò)程處理會(huì)耗時(shí),建議你做一下打點(diǎn)分析,看主要瓶頸是哪一塊,同時(shí)carbon和spark我們也可以做一些聯(lián)合優(yōu)化,相信基于社區(qū)的努力后面會(huì)有改善。
Q:如果有新的數(shù)據(jù)添加進(jìn)來(lái),CarbonData統(tǒng)計(jì)信息如何更新?
A:有兩種方式,一種是比較簡(jiǎn)單的,每次數(shù)據(jù)表更新重新計(jì)算增量,這樣比較精確但是會(huì)比較慢,另外一種方式是增量的更新統(tǒng)計(jì)信息,這種方式較前一種可能會(huì)稍微復(fù)雜一些。
Q:在用Spark寫(xiě)Carbondata Partition的時(shí)候,并行比較高,導(dǎo)致每個(gè)分區(qū)下出現(xiàn)很多小文件,這樣有什么好的解決辦法?
A:在CarbonData中每一個(gè)Block的大小是可以設(shè)置的,Blocklet也可以設(shè)置的,在load數(shù)據(jù)的時(shí)候,寫(xiě)滿(mǎn)一個(gè)block的默認(rèn)大小就會(huì)重新再寫(xiě)一個(gè)文件,所以可以設(shè)置Block大小來(lái)解決這個(gè)問(wèn)題。另外定期使用CarbonData的compaction功能也可以合并一些小文件,當(dāng)然后面我們也會(huì)考慮開(kāi)發(fā)merge partition的功能來(lái)給用戶(hù)提供更多選擇。