<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          關于OLAP數倉,從百萬到百億級數據量實時分析

          共 11282字,需瀏覽 23分鐘

           ·

          2020-11-02 06:55



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


          1.按數據量劃分


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



          本系列文章主要關注的是數據量處于百萬到百億級別的偏實時的分析型數倉,Cloudera的Impala、Facebook的Presto和Pivotal的GreenPlum均屬于這類系統;如果超過百億級別數據量,那么一般選擇離線數倉,如使用Hive或Spark等(SparkSQL3.0看起來性能提升很明顯);對于數據量很小的情況,雖然是分析類應用,也可以直接選擇普通的關系型數據庫,比如MySQL等,“殺雞焉用牛刀”。


          2.按建模類型劃分


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


          (1)MOLAP


          這應該算是最傳統的數倉了,1993年Edgar F. Codd提出OLAP概念時,指的就是MOLAP數倉,M即表示多維(Multidimensional)。大多數MOLAP產品均對原始數據進行預計算得到用戶可能需要的所有結果,將其存儲到優(yōu)化過的多維數組存儲中,可以認為這就是上一篇所提到的“數據立方體”。


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


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


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



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


          (2)ROLAP


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

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

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

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

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

          (3)HOLAP


          MOLAP和ROLAP各有優(yōu)缺點,而且是互斥的。如果能夠將兩者的優(yōu)點進行互補,那么是個更好的選擇。而HOLAP的出現就是這個目的,H表示混合型(Hybrid),這個想法很樸素直接。對于查詢頻繁而穩(wěn)定但又耗時的那些SQL,通過預計算來提速;對于較快的查詢、發(fā)生次數較少或新的查詢需求,像ROLAP一樣直接通過SQL操作事實表和維度表。

          目前似乎沒有開源的OLAP系統屬于這個類型,一些大數據服務公司或互聯網廠商,比如HULU有類似的產品。相信未來HOLAP可能會得到進一步發(fā)展,并獲得更大規(guī)模的使用。

          (4)HTAP


          從另一個維度看,HTAP也算是一種OLAP類型的系統,是ROLAP的一個擴展,具備了OLAP的能力。最新發(fā)展顯示,有云廠商在HTAP的基礎上做了某種妥協,將T(transaction)弱化為S(Serving),朝HSAP方向演進。關于HTAP/HSAP,本文不做進一步展開,可自主查詢其他資料。

          主流的OLAP數倉系統很多,包含上面所述的各種類型,下圖是Gartner 2019 年發(fā)布的數據分析市場排名:


          可以發(fā)現,傳統的商業(yè)廠商和閉源的云服務廠商占據了絕大部分市場。大部分系統筆者只聽過而沒有研究過。作為屁股在互聯網公司的數據庫/數據倉庫開發(fā)者,本文后續(xù)主要聚焦在基于Hadoop生態(tài)發(fā)展的開源OLAP系統(SQL on Hadoop)。



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

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



          1.寬表模型


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


          目前該類OLAP系統包括Druid和ClickHouse等,兩者各有優(yōu)勢,Druid支持更大的數據規(guī)模,具備一定的預聚合能力,通過倒排索引和位圖索引進一步優(yōu)化查詢性能,在廣告分析場景、監(jiān)控報警等時序類應用均有廣泛使用;ClickHouse部署架構簡單,易用,保存明細數據,依托其向量化查詢、減枝等優(yōu)化能力,具備強勁的查詢性能。兩者均具備較高的數據實時性,在互聯網企業(yè)均有廣泛使用。


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


          2.多表組合模型


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


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


          對于ROLAP系統,尤其是星型或雪花型的系統,如果能夠盡可能得縮短響應時間非常重要,這將是該系統的核心競爭力。這塊內容,我們放在下一節(jié)著重進行介紹。



          三、有哪些黑科技可優(yōu)化ROLAP系統性能


          目前生產環(huán)境使用的ROLAP系統,均實現了大部分的該領域性能優(yōu)化技術,包括采用MPP架構、支持基于代價的查詢優(yōu)化(CBO)、向量化執(zhí)行引擎、動態(tài)代碼生成機制、存儲空間和訪問效率優(yōu)化、其他cpu和內存相關的計算層優(yōu)化等。下面逐一進行介紹。


          什么是MPP架構?


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


          1.MR架構及其局限


          在Hadoop生態(tài)下,最早在Hive上提供了基于MapReduce框架的SQL查詢服務。

          但基于MR框架局限性明顯,比如:

          • 每個MapReduce 操作都是相互獨立的,Hadoop不知道接下來會有哪些MapReduce。

          • 每一步的輸出結果,都會持久化到硬盤或者HDFS 上。


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


          2.MPP優(yōu)缺點分析


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


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



          上圖即為Impala架構圖,展示了Impala各個組件及一個查詢的執(zhí)行流程。

          1. 用戶通過Impala提供的impala-shell或beeline等客戶端/UI工具向Impala節(jié)點下發(fā)查詢SQL;接收該SQL的Impala節(jié)點即為Coordinator節(jié)點,該節(jié)點負責進行SQL解析;

          2. 首先產生基于單節(jié)點的執(zhí)行計劃;再對執(zhí)行計劃進行分布式處理,比如將Join、聚合(aggregation)等并行化到各Impala Executor節(jié)點上。執(zhí)行計劃被切分為多個Plan Fragment(PF),每個PF又由一到多個Operator組成;

          3. 接著,下發(fā)經過優(yōu)化后的執(zhí)行計劃的PF到對應的Executor節(jié)點,多個執(zhí)行節(jié)點并行處理任務,縮短整個任務所需時間;

          4. 執(zhí)行節(jié)點掃描HDFS/Hbase等存儲上的數據,并逐層進行處理,比如進行跨節(jié)點的數據shuffe,Join等操作;

          5. 執(zhí)行節(jié)點完成任務并將輸出結果統一發(fā)送到Coordinator節(jié)點;

          6. Coordinator節(jié)點匯總各個執(zhí)行節(jié)點數據,做最后處理,最終返回給用戶想要的結果集。


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

          • PF之間的數據交互(即中間處理結果)駐留在內存Buffer中不落盤(假設內存夠大);

          • Operator和PF間基于流水線處理,不需要等上一個Operator/PF都完成后才進行下一個處理。上下游之間的關系和數據交互式預先明確的。


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

          • 中間結果不落盤,在正常情況下是利好,但在異常情況下就是利空,這意味著出現節(jié)點宕機等場景下,需要重新計算產生中間結果,拖慢任務完成時間;

          • 擴展性沒有MR等架構好,或者說隨著MPP系統節(jié)點增多到一定規(guī)模,性能無法線性提升。有個原因是“木桶效應”,系統性能瓶頸取決于性能最差的那個節(jié)點。另一個原因是規(guī)模越大,出現節(jié)點宕機、壞盤等異常情況就會越頻繁,故障率提高會導致SQL重試概率提升;


          基于上述分析,MPP比較適合執(zhí)行時間不會太久的業(yè)務場景,比如數小時。因為時間越久,故障概率越大。


          4、其他非MPP架構


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


          不同架構有不同優(yōu)缺點,重要的是找到其適用的場景,并進行靠譜地優(yōu)化,充分發(fā)揮其優(yōu)勢。



          四、什么是基于代價的查詢優(yōu)化?

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

          分布式架構使得執(zhí)行計劃能夠進行跨節(jié)點的并行優(yōu)化,通過任務粒度拆分、串行變并行等方式大大縮短執(zhí)行時間。除此之外,還有2個更重要的優(yōu)化方式,就是傳統的基于規(guī)則優(yōu)化以及更高級的基于代價優(yōu)化。

          1.基于規(guī)則優(yōu)化


          通俗來說,基于規(guī)則的優(yōu)化(rule based optimization,RBO)指的是不需要額外的信息,通過用戶下發(fā)的SQL語句進行的優(yōu)化,主要通過改下SQL,比如SQL子句的前后執(zhí)行順序等。比較常見的優(yōu)化包括謂語下推、字段過濾下推、常量折疊、索引選擇、Join優(yōu)化等等。

          謂語下推,即PredicatePushDown,最常見的就是where條件等,舉MySQL為例,MySQL Server層在獲取InnoDB表數據時,將Where條件下推到InnoDB存儲引擎,InnoDB過濾where條件,僅返回符合條件的數據。在有數據分區(qū)場景下,謂語下推更有效;

          字段過濾下推,即ProjectionPushDown,比如某個SQL僅需返回表記錄中某個列的值,那么在列存模式下,只需讀取對應列的數據,在行存模式下,可以選擇某個索引進行索引覆蓋查詢,這也是索引選擇優(yōu)化的一種場景;

          常量或函數折疊也是一種常見的優(yōu)化方式,將SQL語句中的某些常量計算(加減乘除、取整等)在執(zhí)行計劃優(yōu)化階段就做掉;

          Join優(yōu)化有很多方法,這里說的基于規(guī)則優(yōu)化,主要指的是Join的實現方式,比如最傻瓜式的Join實現就是老老實實得讀取參與Join的2張表的每條記錄進行Join條件比對。而最普遍的優(yōu)化方式就是Hash Join,顯然效率很高。不要認為這是想當然應該有的功能,其實MySQL直到8.0版本才具備。另外Join的順序及合并,有部分也可以直接通過SQL來進行判斷和選擇。

          2.基于代價優(yōu)化


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

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

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

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


          廣播方式適用于大表與小表進行Join,在并行Join時,將小表廣播到大表分區(qū)數據所在的各個執(zhí)行節(jié)點,分別與大表分區(qū)數據進行Join,最后返回Join結果并匯總。

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

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

          如果Join的兩表都是大表,但至少有個表是帶Where過濾條件的,那么在決定走分區(qū)方式前還可進一步看滿足條件的記錄數,這時候,物理上進行分區(qū)的表存儲方式可發(fā)揮作用,可以看每個分區(qū)的最大值和最小值及其記錄數來估算過濾后的總記錄數。當然,還有種更精確的方式是列直方圖,能夠直接而直觀得獲取總記錄數。

          如果上述的統計信息都沒有,要使用CBO還有另一種方式就是進行記錄的動態(tài)采樣來決定走那種Join方式。

          (2)Join順序

          如果一個查詢的SQL中存在多層Join操作,如何決定Join的順序對性能有很大影響。這塊也已是被數據庫大佬們充分研究過的技術。



          一個好的CBO應該能夠根據SQL 語句的特點,來自動選擇使用Left-deep tree(LDT,左圖)還是 bushy tree(BYT,右圖)執(zhí)行join。

          兩種Join順序沒有好壞之分,關鍵看進行Join的表數據即Join的字段特點

          對于LDT,如果每次Join均能夠過濾掉大量數據,那么從資源消耗來看,顯然是更優(yōu)的。對于給每個列都構建了索引的某些系統,使用LDT相比BYT更好。

          一般來說,選擇BYT是效率更高的模式,通過串行多層Join改為并行的更少層次Join,可以發(fā)揮MPP架構的優(yōu)勢,盡快得到結果,在多表模式ROLAP場景常采用。

          為什么需要向量化執(zhí)行引擎?其與動態(tài)代碼生成有何關系?


          查詢執(zhí)行引擎 (query execution engine)?是數據庫中的一個核心組件,用于將查詢計劃轉換為物理計劃,并對其求值返回結果。查詢執(zhí)行引擎對系統性能影響很大,在一項針對Impala和Hive的對比時發(fā)現,Hive在某些簡單查詢上(TPC-H Query 1)也比Impala慢主要是因為Hive運行時完全處于CPU bound的狀態(tài)中,磁盤IO只有20%,而Impala的IO至少在85%。

          什么原因導致這么大的差別呢?首先得簡單說下火山模型的執(zhí)行引擎。

          (3)火山模型及其缺點


          火山模型(Volcano-style execution)是最早的查詢執(zhí)行引擎,也叫做迭代模型 (iterator model),或 one-tuple-at-a-time。在這種模型中,查詢計劃是一個由operator組成的DAG,其中每一個operator 包含三個函數:open,next,close。Open 用于申請資源,比如分配內存,打開文件,close 用于釋放資源,next方法遞歸的調用子operator的 next方法生成一個元組(tuple,即行row在物理上的表示)。

          下圖描述了“select sum(C1) from T1 where C2 > 15”的查詢計劃,該查詢計劃包含Project,HashAgg,Scan等operator,每個 operator的next方法遞歸調用子節(jié)點的 next,一直遞歸調用到葉子節(jié)點Scan operator,Scan operator的next 從文件中返回一個元組。


          其缺點主要在于:
          • 大量虛函數調用:火山模型的next方法通常實現為一個虛函數,在編譯器中,虛函數調用需要查找虛函數表, 并且虛函數調用是一個非直接跳轉 (indirect jump), 會導致一次錯誤的CPU分支預測 (brance misprediction), 一次錯誤的分支預測需要十幾個周期的開銷。火山模型為了返回一個元組,需要調用多次next 方法,導致昂貴的函數調用開銷

          • 類型裝箱:對于a + 2 * b之類表達式,由于需要對不同數據類型的變量做解釋,所以在Java中需要把這些本來是primitive(如int等類型)的變量包裝成Object,但執(zhí)行時又需要調用具體類型的實現函數,這本質上也是虛函數調用的效率問題;

          • CPU Cache利用效率低:next方法一次只返回一個元組,元組通常采用行存儲,如果僅需訪問第一列而每次均將一整行填入CPU Cache,將導致Cache Miss;

          • 條件分支預測失敗:現在的CPU都是有并行流水線的,但是如果出現條件判斷會導致無法并行。比如判斷數據的類型(是string還是int),或判斷某一列是否因為其他字段的過濾條件導致本行不需要被讀取等場景;

          • CPU與IO性能不匹配:每次從磁盤讀取一個行數據,經過多次調用交給CPU進行處理,顯然,大部分時間都是CPU等待數據就緒,導致CPU空轉。


          通過上述描述,可以得出解決問題的基本方法??梢詫栴}分為2大類,分別用下述的向量化引擎和動態(tài)代碼生成技術來解決。

          (4)向量化執(zhí)行引擎


          向量化執(zhí)行以列存為前提,主要思想是每次從磁盤上讀取一批列,這些列以數組形式組織。每次next都通過for循環(huán)處理列數組。這么做可以大幅減少next的調用次數。相應的CPU的利用率得到了提高,另外數據被組織在一起。可以進一步利用CPU硬件的特性,如SIMD,將所有數據加載到CPU的緩存當中去,提高緩存命中率,提升效率。在列存儲與向量化執(zhí)行引擎的雙重優(yōu)化下,查詢執(zhí)行的速度會有一個非常巨大的飛躍。

          動態(tài)代碼生成


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

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

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

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

          都有哪些存儲空間和訪問效率優(yōu)化方法?


          存儲和IO模塊的優(yōu)化方法很多,這里我們還是在Hadoop生態(tài)下來考慮,當然,很多優(yōu)化方法不是Hadoop特有的,而是通用的。OLAP場景下,數據存儲最基礎而有效的優(yōu)化是該行存儲為列存儲,下面討論的優(yōu)化措施均基于列存。

          (5)數據壓縮和編碼


          數據壓縮是存儲領域常用的優(yōu)化手段,以可控的CPU開銷來大幅縮小數據在磁盤上的存儲空間,一來可以節(jié)省成本,二來可以減小IO和數據在內存中跨線程和跨節(jié)點網絡傳輸的開銷。目前在用的主流壓縮算法包括zlib、snappy和lz4等。壓縮算法并不是壓縮比越高越好,壓縮率越高的算法壓縮和解壓縮速度往往就越慢,需要根據硬件配置和使用場景在cpu 和io之間進行權衡。

          數據編碼可以理解為輕量級壓縮,包括RLE和數據字典編碼等。

          上圖截至Presto論文,展示了RLE編碼和數據字典編碼的使用方式。RLE用在各列都是重復字符的情況,比如page0中6行記錄的returnflag都是"F"。數據字典可高效使用在區(qū)分度較低的列上,比如列中只有幾種字符串的場景。考慮到同個表的列的值相關性,數據字典可以跨page使用。

          與數據壓縮相比,數據編碼方式在某些聚合類查詢場景下,無需對數據進行解碼,直接返回所需結果。比如假設T1表的C1列為某個字符,RLE算法將16個C1列的值“aaaaaabbccccaaaa”編碼為6a2b4c4a,其中6a表示有連續(xù)6個字符a。當執(zhí)行 select count(*) from T1 where C1=’a’時,不需要解壓6a2b4c4a,就能夠知道這16行記錄對應列值為a有10行。

          在列存模式下,數據壓縮和編碼的效率均遠高于行存。

          (6)數據精細化存儲


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

          • 數據分區(qū):數據分區(qū)可用于將表中數據基于hash或range打散到多個存儲節(jié)點上,配合多副本存儲。可以提高數據容災和遷移效率。除此之外,在查詢時可以快速過濾掉不符合where條件要求的數據分區(qū),無需逐列讀取數據進行判斷。

          • 行組:與數據分區(qū)類似,Hadoop中常用的parquet和orcfile還將表數據分為多個行組(row group),每個行組內的記錄按列存儲。這樣即達到列存提高OLAP查詢效率,同時能夠兼顧查詢多行的需求;

          • 局部索引:在數據分區(qū)或行組上創(chuàng)建索引,可以提高查詢效率。如下圖所示,orcfile在每個行組的頭部維護了Index Data來,保存最大值和最小值等元數據,基于這些信息可以快速決定是否需掃描該行組。某些OLAP系統進一步豐富了元數據信息,比如建立該行組記錄的倒排索引或B+樹索引,進一步提高掃描和查詢效率。


          • 富元數據:除了提供最大值和最小值信息外,還可進一步提供平均值、區(qū)分度、記錄數、列總和,表大小分區(qū)信息,以及列的直方圖等元數據信息。


          (7)數據本地化訪問


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

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

          對于Impala等OLAP系統,可以通過HDFS本地訪問模式進行優(yōu)化,直接讀取磁盤上的HDFS文件數據。HDFS這個特性稱為"Short Circuit Local Reads",其相關的配置項(在hdfs-site.xml中)如下:
              dfs.client.read.shortcircuit    true        dfs.domain.socket.path    /var/lib/hadoop-hdfs/dn_socket  br

          其中:dfs.client.read.shortcircuit是打開這個功能的開關,dfs.domain.socket.path是Datanode和DFSClient之間溝通的Socket的本地路徑。

          (8)運行時數據過濾


          這是少部分OLAP系統才具有的高級功能,比如Impala的RunTime Filter(RF)運行時過濾,和SparkSQL 3.0的 Dynamic Partition Pruning動態(tài)分區(qū)裁剪,可以將驅動表的bloomfilter(BF)或過濾條件作用在被驅動表的數據掃描階段,從而極大減少需掃描/返回的數據量。下面分別用一個圖進行簡述,在后續(xù)分析具體OLAP系統時再詳述。
          上圖直觀得展示了Impala runtime filter的實現。流程如下:
          1. 同時下發(fā)兩個表的SCAN操作。左邊是大表,右邊是小表(相對而言,也有可能是同等級別的),但是左表會等待一段時間(默認是1s),因此右表的SCAN會先執(zhí)行;

          2. 右表的掃描的結果根據join鍵哈希傳遞掃不同的Join節(jié)點,由Join節(jié)點執(zhí)行哈希表的構建和RF的構建;

          3. Join節(jié)點讀取完全部的右表輸入之后也完成了RF的構建,它會將RF交給Coordinator節(jié)點(如果是Broadcast Join則會直接交給左表的Scan節(jié)點);

          4. Coordinator節(jié)點將不同的RF進行merge,也就是把Bloom Filter進行merge,merge之后的Bloom Filter就是一個GLOBAL RF,它將這個RF分發(fā)給每一個左表Scan;

          5. 左表會等待一段時間(默認1s)再開啟數據掃描,為了是盡可能的等待RF的到達,但是無論RF什么時候到達,RF都會在到達那一刻之后被應用;

          6. 左表使用RF完成掃描之后同樣以Hash方式交給Join節(jié)點,由Join節(jié)點進行apply操作,以完成整個Join過程。


          sparksql圖1(官方這個圖有誤,右邊應該是Scan Date)
          sparksql圖2
          上面2幅圖是SparkSQL 3.0的動態(tài)分區(qū)裁剪示意圖。將右表的掃描結果(hashtable of table Date after filter)廣播給左表的Join節(jié)點,在進行左表掃描時即使用右表的hashtable進行條件數據過濾。


          除了上面這些,還有其他優(yōu)化方法嗎?


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

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

          目前的優(yōu)化方法主要包括讓AppMaster啟動后長期駐守,container復用等方式。讓資源在需要用時已經就位,查詢無需等待即可馬上開始。


          五、最后做個總結

          本文主要是想闡述下自己對數倉和OLAP系統的理解,之所以采用問答形式,是因為筆者就是帶著這些問題去google網上或公司內部的資料,或者直接請教在這個領域的大佬。
          由于水平有限,難免有所錯誤,非常歡迎大家看后能夠指出。



          專業(yè)的數據分析軟件旨在幫助企業(yè)提供從內外部數據源整合、數據治理到探索式分析,以及最終實現智能化決策的大數據分析能力,助力企業(yè)構建數據生態(tài)系統,幫助企業(yè)降本增收和實現數據資產的變現。


          文章來源:知乎 溫正湖

          瀏覽 21
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  香蕉女人毛片 | 深爱五月网 | 亚洲插逼色| 色色影院精品 | 亚洲中文娱乐 |