對於OLAP的話題本號曾經談論過很多次,期間也有一些觀點有失偏頗,例如對基於Brute Force掃描方案的否認態度,包含Impala,Stinger/Tez,Presto等諸多手段。站在一個新的高度來看待OLAP,暴力掃描並不必定老是慢,而基於索引的方案也並不必定就真得快,由於一個大型的數據倉庫,面臨PB級的數據分析,數據加載速度是重要的評測指標,基於索引的方案,單純索引自己所佔據的體積就已經達到原始數據同等規模,所以並不表明在任何狀況下都會更快。從另外一方面來講,基於Brute Force的方案,也能夠經過設計優良的查詢優化器來大力提高性能,從而變Brute Force爲Linear Scan,在不少狀況下的確能夠表現良好。正如Impala,Presto,Stringer/Tez等能夠比Hive快十多倍,而HAWQ能夠比它們再快上數倍同樣。html
那麼,如何打造一個爲內部作大數據分析的統一服務平臺呢?AWS的RedShift是一個好的參考,它的查詢性能跟基於內存的Spark SQL相似,高於Impala,Presto,Stinger/Tez[1],但RedShift是構建在低廉的S3分佈式存儲之上的。咱們無從得知RedShift的設計細節,僅有的材料顯示RedShift的技術來源於Amazon收購的ParAccel,一家獨立的MPP數據庫技術提供商。從官方透露的材料,以及一些民間分析[2]來看,RedShift基於列存(顯然須要如此),任何查詢分解爲子任務並行執行,掃描結束後合併結果。除了較高的查詢性能以外,RedShift是服務化的,能夠無運維介入地在雲端使用,所以,相似的統一數據分析服務是企業大數據的剛需。以AWS官方的部署爲例,在一個公司內部給多個數據團隊提供一站式的獨立數據管道以及分析服務,可讓不一樣團隊無干擾的工做。算法
然而,在AWS上的大數據公司中,有兩家Airbnb/Netflix並無採用RedShift,而是採用了Presto做爲它們的統一大數據分析平臺,這是出於什麼考慮呢?數據庫
對於Airbnb來講,它認爲在S3和HDFS之間的ETL任務是很是耗時的操做,所以選擇全部任務都在HDFS上進行而放棄了S3,沒有選擇Impala是由於在當時(2014年末)它還不夠穩定(現在Impala穩定性如何還須要使用者自行評估,也歡迎留言反饋),此外,Impala對內存消耗太高,在進行一些大表的Join時,經常會引起內存溢出錯誤而掛掉。而對於Netflix,這是家技術基因更強的公司,它從一開始就放棄了HDFS而選擇讓Hadoop跑在S3上,在13年的時候就以此爲基礎提供Hadoop As A Service[3],這樣就避免了Airbnb在S3和HDFS之間的ETL任務浪費時間,至於採用Presto,是由於他們想在S3上直接查詢數據,而且可以和Hadoop一塊兒工做,而不是把天天更新的巨量數據再導入RedShift(這個緣由解釋得有些牽強,由於RedShift原本就直接工做在S3上,我以爲可能仍是一種對基礎架構可以絕對控制的潔癖致使的選擇,也歡迎留言評論具體可能的緣由)。爲此,他們聯合Facebook讓Presto能夠運行在S3上[4]。
安全
由此,能夠看到Presto,是目前開源界最接近RedShift的方案——主要的差距在於性能。那麼,有沒有可能作到讓查詢性能也接近RedShift呢?看看基於掃描的MPP數據庫路線圖:架構
最新出現的商業產品Vertica和BigSQL其核心設計思路跟HAWQ都相似。HAWQ是GreenPlum將查詢優化層獨立出來,而且以HDFS做爲數據載體的OLAP方案。GreenPlum的數據庫層在HAWQ裏只做爲執行引擎,而再也不負責存儲,所以能夠方便得引入GreenPlum的其餘特性,好比標準SQL,ACID事務,以及查詢優化器。GreenPlum的負責人仍然公開宣稱HAWQ比GreenPlum慢,可是利用HDFS存儲數據的優點,可讓HAWQ更適合做爲統一數據分析平臺的基礎組件。今年的2月和10月,HAWQ和GreenPlum分別前後開源,所以這是一個值得深刻研究的平臺。
運維
下面看看HAWQ/GreenPlum性能優點的最主要組件:基於成本模型的並行查詢執行計劃Cost Based Parallel Query Optimizer and Planner[5]。 HAWQ/GreenPlum的查詢執行跟數據存儲是個分離的子系統,所以也便於修改底層數據存儲。查詢優化器跟數據庫之間經過自定義的DXL(一種XML)交互。
數據庫設計
圖中的memo表明查詢計劃的執行單元,分紅多組表示。以一個簡單的查詢爲例:SELECT T1.a FROM T1,T2 WHERE T1.a=T2.b ORDER BY T1.a,其執行單元分組以下圖所示:分佈式
前圖中的Transformation表明等價的邏輯表達式轉換規則,好比InnerJoin(A,B)等價於InnerJoin(B,A),Join(A,B)轉換爲HashJoin(A,B)。圖中的Property Enforcement用來描述查詢以及執行計劃的特性。在查詢優化器中,Property分爲幾類:邏輯屬性(輸出的數據列),物理屬性(例如排序方式,數據分佈)以及標量屬性(Join操做須要的列)。在查詢優化中,每一個操做樹的子節點,它的優化結果多是自己已經知足自身要求,也可能須要Enforcement,例如增長Sort操做等。
oop
當得到執行單元分組以後,查詢優化器須要統計各單元的統計數據,這一般由查詢各列(維度)的直方圖來得到,產生的基數估計值在查詢進行期間還能夠增量更新,它們就是HAWQ/GreenPlum基於Cost的查詢優化模型的基礎數據。
性能
基礎數據得到後,接下來進行Transformation步驟,把不一樣單元邏輯操做轉化爲對應的表達式規則,例如Get2Scan用於執行邏輯操做Get時生成物理表Scan(這表示進行線性掃描),InnerJoin2HashJoin以及InnerJoin2NLJoin分別表示進行Hash Join和Nested Loop Join(兩種通用的Join算法)。Transformation完成後就進入優化階段,在該步驟,須要以Memo的分組爲單位對執行計劃作Cost估計,對屬性添加必要的Enforcement,而後生成最佳執行計劃。論文中對優化的具體算法沒有過多描述,須要深刻代碼才能瞭解其具體優化設計思路。
整個查詢優化器的任務包含:
Exp(g) 產生組g內全部表達式對應的邏輯等價表達式
Exp(gexpr) 產生表達式gexpr對應的邏輯等價表達式
Imp(g) 產生組g的表達式
Opt(g, req) 返回最小估計開銷的執行計劃,根節點在組g的操做,而且知足請求req
Opt(gexpr, req) 返回根節點在表達式gexpr的最小估計開銷的執行計劃
對於每一個查詢,以上任務可能會多達上百個甚至上千,所以並行執行很是必要。HAWQ/GreenPlum內部有一個調度器根據任務的DAG圖來並行調度。
查詢優化器工做在數據庫存儲系統以外,所以須要一個組件用來在優化器和數據庫之間交換數據,例如優化器須要知道查詢計劃所依賴的數據是否具備索引等,以下圖所示,所以,給HAWQ/GreenPlum添加其餘數據存儲系統是容易作到的。
HAWQ/GreenPlum的另外一個重要特性是並行數據加載。從Airbnb/Netflix的故事中咱們已經能夠看到,大型數據倉庫的構建中,數據加載的速度是多麼重要的因素,而由於沒有過多索引的限制,它們能夠達到單個Rack 1小時10T數據的加載速度。
還有一些特性,跟OLAP不很相關,好比事務的支持等,它們的存在是讓不一樣節點的數據段Segment自己的提交和回滾更安全,因此不是說有了事務就能夠拿它作OLTP用。
所以,HAWQ/GreenPlum是咱們能夠獲取到的最好的MPP數據庫設計(穩定與否還但願能獲得更多留言反饋),在面對大型數據倉庫構建時,這多是咱們本身來攢RedShift的又一個選擇。
[1] https://amplab.cs.berkeley.edu/benchmark/
[2] http://www.kbartocha.com/2013/02/25/amazon-redshift-a-peek-at-its-internal-organs/
[3] http://techblog.netflix.com/2013/01/hadoop-platform-as-service-in-cloud.html
[4] http://techblog.netflix.com/2014/10/using-presto-in-our-big-data-platform.html
[5] Orca: A Modular Query Optimizer Architecture for Big Data,ACM SIGMOD 2014