知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

關於數據倉庫,早期分享過不少基礎類文章,偶然間看到知乎上這篇關於OLAP的深度解讀,從技術發展,產品選型,執行優化等方面做了詳細的剖析,分享來給大家看看!

一、有哪些類型的OLAP數倉?

1、按數據量劃分

對一件事物或一個東西基於不同角度,可以進行多種分類方式。對數倉產品也一樣。比如我們可以基於數據量來選擇不同類型的數量,如下圖所示:

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

本系列文章主要關注的是數據量處於百萬到百億級別的偏實時的分析型數倉,Cloudera的Impala、Facebook的Presto和Pivotal的GreenPlum均屬於這類系統;

如果超過百億級別數據量,那麼一般選擇離線數倉,如使用Hive或Spark等(SparkSQL3.0看起來性能提升很明顯);對於數據量很小的情況,雖然是分析類應用,也可以直接選擇普通的關係型數據庫,比如MySQL等,“殺雞焉用牛刀”。

2、按建模類型劃分

下面我們主要關注數據量中等的分析型數倉,聚焦OLAP系統。根據維基百科對OLAP的介紹,一般來說OLAP根據建模方式可分爲MOLAP、ROLAP和HOLAP 3種類型,下面分別進行介紹並分析優缺點。

(1)MOLAP

這應該算是最傳統的數倉了。大多數MOLAP產品均對原始數據進行預計算得到用戶可能需要的所有結果,將其存儲到優化過的多維數組存儲中。

由於所有可能結果均已計算出來並持久化存儲,查詢時無需進行復雜計算,且以數組形式可以進行高效的免索引數據訪問,因此用戶發起的查詢均能夠穩定地快速響應。這些結果集是高度結構化的,可以進行壓縮/編碼來減少存儲佔用空間。

但高性能並不是沒有代價的。首先,MOLAP需要進行預計算,這會花去很多時間。如果每次寫入增量數據後均要進行全量預計算,顯然是低效率的,因此支持僅對增量數據進行迭代計算非常重要。其次,如果業務發生需求變更,需要進行預定模型之外新的查詢操作,現有的MOLAP實例就無能爲力了,只能重新進行建模和預計算。

因此,MOLAP適合業務需求比較固定,數據量較大的場景。在開源軟件中,由eBay開發並貢獻給Apache基金會的Kylin即屬於這類OLAP引擎,支持在百億規模的數據集上進行亞秒級查詢。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

其架構圖較直觀地反映了基於cube的預計算模型(build),如下所示:

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

(2)ROLAP

與MOLAP相反,ROLAP無需預計算,直接在構成多維數據模型的事實表和維度表上進行計算。R即表示關係型(Relational)。顯然,這種方式相比MOLAP更具可擴展性,增量數據導入後,無需進行重新計算,用戶有新的查詢需求時只需寫好正確的SQL語句既能完成獲取所需的結果。

但ROLAP的不足也很明顯,尤其是在數據體量巨大的場景下,用戶提交SQL後,獲取查詢結果所需的時間無法準確預知,可能秒回,也可能需要花費數十分鐘甚至數小時。本質上,ROLAP是把MOLAP預計算所需的時間分攤到了用戶的每次查詢上,肯定會影響用戶的查詢體驗。

當然ROLAP的性能是否能夠接受,取決於用戶查詢的SQL類型,數據規模以及用戶對性能的預期。對於相對簡單的SQL,比如TPCH中的Query響應時間較快。但如果是複雜SQL,比如TPC-DS中的數據分析和挖掘類的Query,可能需要數分鐘。

相比MOLAP,ROLAP的使用門檻更低,在完成星型或雪花型模型的構建,創建對應schema的事實表和維度表並導入數據後,用戶只需會寫出符合需求的SQL,就可以得到想要的結果。相比創建“數據立方體”,顯然更加方便。

有分析表明,雖然ROLAP的性能不如MOLAP,但由於其靈活性、擴展性,ROLAP的使用者是MOLAP的數倍。

二、有哪些常用的開源ROLAP產品?

目前生產環境使用較多的開源ROLAP主要可以分爲兩大類,一個是寬表模型,另一個是多表組合模型(就是前述的星型或雪花型)。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

1、寬表模型

寬表模型能夠提供比多表組合模型更好的查詢性能,不足的是支持的SQL操作類型比較有限,比如對Join等複雜操作支持較弱或不支持。

目前該類OLAP系統包括Druid和ClickHouse等,兩者各有優勢,Druid支持更大的數據規模,具備一定的預聚合能力;ClickHouse部署架構簡單,易用,保存明細數據,依託其向量化查詢、減值等優化能力,具備強勁的查詢性能。兩者均具備較高的數據實時性,在互聯網企業均有廣泛使用。

除了上面介紹的Druid和ClickHouse外,ElasticSearch和Solar也可以歸爲寬表模型。但其系統設計架構有較大不同,這兩個一般稱爲搜索引擎,通過倒排索引,應用Scatter-Gather計算模型提高查詢性能。對於搜索類的查詢效果較好,但當數據量較大或進行掃描聚合類查詢時,查詢性能會有較大影響。

2、多表組合模型

採用星型或雪花型建模是最通用的一種ROLAP系統,常見的包括GreenPlum、Presto和Impala等,他們均基於MPP架構,採用該模型和架構的系統具有支持的數據量大、擴展性較好、靈活易用和支持的SQL類型多樣等優點。

相比其他類型ROLAP和MOLAP,該類系統性能不具有優勢,實時性較一般。通用系統往往比專用系統更難實現和進行優化,這是因爲通用系統需要考慮的場景更多,支持的查詢類型更豐富。而專用系統只需要針對所服務的某個特定場景進行優化即可,相對複雜度會有所降低。

對於ROLAP系統,尤其是星型或雪花型的系統,如果能夠儘可能得縮短響應時間非常重要,這將是該系統的核心競爭力。

三、有哪些黑科技用於優化ROLAP系統性能?

目前生產環境使用的ROLAP系統,均實現了大部分的該領域性能優化技術,包括採用MPP架構、支持基於代價的查詢優化(CBO)、向量化執行引擎、動態代碼生成機制、存儲空間和訪問效率優化、其他cpu和內存相關的計算層優化等。

首先來聊聊系統架構,這是設計OLAP系統的第一次分野,目前生產環境中系統採用的架構包括基於傳統的MapReduce架構加上SQL層組裝的系統;主流的基於MPP的系統;其他非MPP系統等。

1、MR架構及其侷限

在Hadoop生態下,最早在Hive上提供了基於MapReduce框架的SQL查詢服務。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

但基於MR框架侷限性明顯,比如:

  • 每個MapReduce 操作都是相互獨立的,Hadoop不知道接下來會有哪些MapReduce。
  • 每一步的輸出結果,都會持久化到硬盤或者HDFS 上。

第一個問題導致無法進行跨MR操作間的優化,第二個問題導致MR間數據交互需要大量的IO操作。兩個問題均對執行效率產生很大影響,性能較差。

2、MPP優缺點分析

MPP是massively parallel processing的簡稱,即大規模並行計算框架。相比MR等架構,MPP查詢速度快,通常在秒級甚至毫秒級以內就可以返回查詢結果,這也是爲何很多強調低延遲的系統,比如OLAP系統大多采用MPP架構的原因。

下面以Impala爲例,簡單介紹下MPP系統架構。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

3、MPP架構之所以性能比MR好,原因包括:

  • PF之間的數據交互(即中間處理結果)駐留在內存Buffer中不落盤(假設內存夠大);
  • Operator和PF間基於流水線處理,不需要等上一個Operator/PF都完成後才進行下一個處理。上下游之間的關係和數據交互是預先明確的。

這樣可以充分利用CPU資源,減少IO資源消耗。但事情往往是兩面的,MPP並不完美,主要問題包括:

  • 中間結果不落盤,在正常情況下是利好,但在異常情況下就是利空,這意味着出現節點宕機等場景下,需要重新計算產生中間結果,拖慢任務完成時間;
  • 擴展性沒有MR等架構好,或者說隨着MPP系統節點增多到一定規模,性能無法線性提升。有個原因是“木桶效應”,系統性能瓶頸取決於性能最差的那個節點。另一個原因是規模越大,出現節點宕機、壞盤等異常情況就會越頻繁,故障率提高會導致SQL重試概率提升;

基於上述分析,MPP比較適合執行時間不會太久的業務場景,比如數小時。因爲時間越久,故障概率越大。

4、其他非MPP架構

基於MR系統侷限性考慮,除了採用MPP架構外,Hive和Spark均使用不同方式進行了優化,包括Hive的Tez,SparkSQL基於DAG(Directed Acyclic Graph)等。

不同架構有不同優缺點,重要的是找到其適用的場景,並進行靠譜的優化,充分發揮其優勢。

四、什麼是基於代價的查詢優化?

有了適合的系統架構並不一定能夠帶來正向收益,“好馬配好鞍”,執行計劃的好壞對最終系統的性能也有着決定性作用。執行計劃及其優化,就筆者的理解來說,其來源於關係型數據庫領域。這又是一門大學問,這裏僅簡單介紹。

分佈式架構使得執行計劃能夠進行跨節點的並行優化,通過任務粒度拆分、串行變並行等方式大大縮短執行時間。除此之外,還有2個更重要的優化方式,就是傳統的基於規則優化以及更高級的基於代價優化。

1、基於規則優化

通俗來說,基於規則的優化指的是不需要額外的信息,通過用戶下發的SQL語句進行的優化,主要通過改下SQL,比如SQL子句的前後執行順序等。比較常見的優化包括謂語下推、字段過濾下推、常量摺疊、索引選擇、Join優化等等。

2、基於代價優化

基於規則的優化器簡單,易於實現,通過內置的一組規則來決定如何執行查詢計劃。與之相對的是基於代價優化(cost based optimization,CBO)。

CBO的實現依賴於詳細可靠的統計信息,比如每個列的最大值、最小值、平均值、區分度、記錄數、列總和,表大小分區信息,以及列的直方圖等元數據信息。

CBO的一大用途是在Join場景,決定Join的執行方式和Join的順序。這裏所說的Join我們主要是討論Hash Join。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

Join執行方式

根據參與Join的驅動表(Build Table)和被驅動表(Probe Table)的大小,Hash Join一般可分爲broadcast和partition兩種。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

廣播方式適用於大表與小表進行Join,在並行Join時,將小表廣播到大表分區數據所在的各個執行節點,分別與大表分區數據進行Join,最後返回Join結果並彙總。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

而分區方式是最爲一般的模式,適用於大表間Join或表大小未知場景。分別將兩表進行分區,每個分區分別進行Join。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

顯然,判斷大小表的關鍵就看是否能夠通過某種方式獲取表的記錄數,如果存儲層保存了記錄數,那麼可從元數據中直接獲取。

五、爲什麼需要向量化執行引擎?其與動態代碼生成有何關係?

查詢執行引擎 (query execution engine) 是數據庫中的一個核心組件,用於將查詢計劃轉換爲物理計劃,並對其求值返回結果。

查詢執行引擎對系統性能影響很大,在一項針對Impala和Hive的對比時發現,Hive在某些簡單查詢上(TPC-H Query 1)也比Impala慢主要是因爲Hive運行時完全處於CPU bound的狀態中,磁盤IO只有20%,而Impala的IO至少在85%。

什麼原因導致這麼大的差別呢?

1、向量化執行引擎

向量化執行以列存爲前提,主要思想是每次從磁盤上讀取一批列,這些列以數組形式組織。每次next都通過for循環處理列數組。這麼做可以大幅減少next的調用次數。相應的CPU的利用率得到了提高,另外數據被組織在一起。

可以進一步利用CPU硬件的特性,如SIMD,將所有數據加載到CPU的緩存當中去,提高緩存命中率,提升效率。在列存儲與向量化執行引擎的雙重優化下,查詢執行的速度會有一個非常巨大的飛躍。

2、動態代碼生成

向量化執行減少CPU等待時間,提高CPU Cache命中率,通過減少next調用次數來緩解虛函數調用效率問題。而動態代碼生成,則是進一步解決了虛函數調用問題。

動態代碼生成技術不使用解釋性的統一代碼,而是直接生成對應的執行語言的代碼並直接用primitive type。對於判斷數據類型造成的分支判斷,動態代碼的效果可以消除這些類型判斷,使用硬件指令來進一步提高循環處理效率。

具體實現來說,JVM系如Spark SQL,Presto可以用反射,C++系的Impala則使用了llvm生成中間碼。相對來說,C++的效率更高。

向量化和動態代碼生成技術往往是一起工作達到更好的效果。

六、都有哪些存儲空間和訪問效率優化方法?

存儲和IO模塊的優化方法很多,這裏我們還是在Hadoop生態下來考慮,當然,很多優化方法不是Hadoop特有的,而是通用的。OLAP場景下,數據存儲最基礎而有效的優化是該行存儲爲列存儲,下面討論的優化措施均基於列存。

1、數據精細化存儲

所謂數據精細化存儲,是通過儘可能多得提供元數據信息來減少不必要的數據掃描和計算,常用的方法包括但不限於如下幾種:

  • 數據分區:數據分區可用於將表中數據基於hash或range打散到多個存儲節點上,配合多副本存儲。可以提高數據容災和遷移效率。除此之外,在查詢時可以快速過濾掉不符合where條件要求的數據分區,無需逐列讀取數據進行判斷。
  • 行組:與數據分區類似,Hadoop中常用的parquet和orcfile還將表數據分爲多個行組(row group),每個行組內的記錄按列存儲。這樣即達到列存提高OLAP查詢效率,同時能夠兼顧查詢多行的需求;
  • 局部索引:在數據分區或行組上創建索引,可以提高查詢效率。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

2、數據本地化訪問

數據本地化讀寫是常見的優化方法,在Hadoop下也提供了相應的方式。

一般來說,讀HDFS上的數據首先需要經過NameNode獲取數據存放的DataNode信息,再去DataNode節點讀取所需數據。

對於Impala等OLAP系統,可以通過HDFS本地訪問模式進行優化,直接讀取磁盤上的HDFS文件數據。HDFS這個特性稱爲"Short Circuit Local Reads",其相關的配置項(在hdfs-site.xml中)如下:

3、運行時數據過濾

這是少部分OLAP系統才具有的高級功能。

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

sparksql圖1(官方這個圖有誤,右邊應該是Scan Date)

知乎爆贊乾貨:頂級大公司的OLAP數據倉庫,這是全網最好的總結

 

上面2幅圖是SparkSQL 3.0的動態分區裁剪示意圖。將右表的掃描結果(hashtable of table Date after filter)廣播給左表的Join節點,在進行左表掃描時即使用右表的hashtable進行條件數據過濾。

除了上面這些,還有其他優化方法嗎?

還有個極爲重要的技術是集羣資源管理和調度。Hadoop使用YARN進行資源調度,雖然帶來了很大便利,但對性能要求較高的OLAP系統卻有些不適合。

如啓動AppMaster和申請container會佔用不少時間,尤其是前者,而且container的供應如果時斷時續,會極大的影響時效性。

目前的優化方法主要包括讓AppMaster啓動後長期駐守,container複用等方式。讓資源在需要用時已經就位,查詢無需等待即可馬上開始。

最後做個總結

本文主要是想闡述下自己對數倉和OLAP系統的理解,由於水平有限,難免有所錯誤,非常歡迎大家看後能夠指出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章