多維分析的後台效能優化手段

2021-08-18 14:34:34 字數 2977 閱讀 1096

多維分析就是針對乙個事先準備好的資料立方體實施旋轉、切片(切塊)、鑽取等互動操作的過程,經常也被直接稱為olap。它的後台運算在結構上很簡單,如果用sql語法描述,大體形式為:

select d,…, sum(m), … from c where d』=d』 and … group by d,…

即對立方體按某些維度分組彙總某些測度。其中c是資料立方體,d,…是選出維度,m,…是聚合測度,聚合函式也可以不是sum。d』是切片維度,切塊時條件為d in (d,…),where中還可以增加針對某些測度的條件,一般也就是選出某個區間內的值。

olap需要即時響應,對效能要求很高,而這個運算形式雖然很簡單,但資料量大時的計算量也不小,如果不設法優化,效率就可能很差。下面我們介紹多維分析後台建設時幾種經常被採用的效能優化手段。

預先彙總是早期olap產品常用的手段,簡單地就是拿空間換時間。把部分或者全部維度組合(group by子句)的彙總值(select中的聚合測度)先計算出來儲存,以後的計算可以直接取出或從這些中間結果再計算,效能會好很多。

預先彙總占用的空間有點大。如果儲存全部維度組合,一般應用場景下(十幾到幾十個維度,維度取值範圍在幾到幾十之間),簡單計算可知,空間占用會比原始立方體大數倍到數十倍((k1+1)*(k2+1)*…與k1*k2*…之間的比,還要考慮多種聚合函式)。雖然要保證即時響應時立方體都不會太大,但再大幾十倍經常也還是難以接受的。

折衷辦法是只儲存部分維度組合。olap過程中在介面上呈現出來的分組維度(group by子句)不會太多,可以只彙總所有m個維度的組合,在m不太大時(一般不超過5),空間增長還可以容忍,而使用者的大多數操作都可以得到較迅速響應。

麻煩在於,部分彙總解決不了針對其它維度的切片條件,鑽取動作就是以切片為基礎的。而且,即使全量彙總也無法處理測度上的條件(比如銷售額超過1000元的統計),而多維分析時常常允許這些動作,甚至聚合函式也可能帶有條件(只合計100元以下的費用),這些都無法使用預先彙總的結果。

預先彙總只能解決小部分最常見的計算,更多的情況還是要靠硬遍歷。

多維分析本質上是過濾和分組彙總,這種運算很容易並行。只要簡單地資料拆成多段後分別處理,收集到結果再彙總。各個子任務之間沒有依賴關係,無論是單機多執行緒還是集群多機或者綜合有之,都不難實現。

多維分析的結果是要呈現給人看的,而人可以觀察的資料量遠遠小於現代計算機的記憶體。可以放入記憶體的小結果集不需要和外存交換,程式設計複雜度較低,運算效能也好。如果運算時發現結果集太大是可以直接報告給介面相應資訊並中止。

實踐測試表明:多執行緒計算時,不要採用各子任務向同乙個結果集彙總的方案,這樣看起來會減少記憶體占用(各子任務共用乙個最終結果集),但多執行緒搶占同一資源需要的同步動作會嚴重影響效能。

執行緒數也不是越多越好,顯然超過cpu核數就沒有意義了。如果資料在外存,還要考慮硬碟的併發能力,一般會比cpu核數小很多,具體合適的數值需要實際測試才知道。

在資料不再變化時分段也容易,按記錄數切分後設定分段點即可。資料可追加時要做到較平均的分段會有些麻煩,以後再另外撰文陳述。

對於單個計算任務,並行後常常有數倍的效能提公升。但是,olap操作本身就是個併發性事務,即使使用者數不大,也足以抵消平行計算帶來的效能提公升。

還要再想辦法。

沒有切片的彙總運算總是要涉及全量資料,如果不是預先彙總,也沒什麼辦法再減少計算量了。但有切片運算時(鑽取動作),如果資料能合理組織,就未必要遍歷所有資料了。

如果我們為維度d建立索引(即把各記錄的d值及記錄位置按d值排序),那麼涉及d的切片條件就可以迅速定位到相應的記錄上(簡單二分法),不需要遍歷全量資料,計算量常常會有數量級的減少(取決於d的取值範圍)。理論上我們可以為每個維度都建立索引,這個成本並不算高,這樣只要涉及有切片時,效能就會大幅提公升。

需要指明的是,為多個維度d1,d2建立的多字段索引用處並不大,它不能用於迅速定位只有d2的切片,只能用於對d1,d2都有切片條件的情況。在選擇取值範圍最大的那個切片維度用於定位後,計算量減少已經很多了,其它維度的切片可以仍用遍歷手段。

不幸的是,這種原始方案只適用於可以頻繁小量訪問的記憶體資料。如果資料量大到必須放在外存中(而這是經常發生的),按索引大量取出實際上並未連續儲存的資料時,效能並不會有明顯提高。外存資料必須被真實排序、保證相應切片的資料是連續儲存的,效能提公升才會有效。

如果對每個維度都做排序,那相當於資料要被複製若干倍,這個成本就有點高了。

乙個折衷的辦法是把做兩個,按維度d1,…,dn排序一次,再按dn,…,d1排序一次,資料量只是翻倍,還能容忍。總能找到乙個切片維度在兩個維度排序列的前半部分,這樣該維度切片的資料還是基本連續的,效能提公升仍會較為明顯。

對付多維分析還有個大殺器:列式儲存。

多維分析的立方體中欄位(維度和測度)常常都很多,幾十個上百個都很正常,但同時需要取用的字段並不多,如果不算切片維度,通常也就5個左右或更少。而切片可以用上面的索引方案解決,實際要遍歷的字段也仍然不多。

這時候列存就會有巨大優勢了。外存計算的io時間佔比相當大,減少資料讀取量比減少運算量常常能更有效地提高效能。乙個100個字段的立方體,如果只取5個字段時,io開銷只有1/20,這會帶來數量級的效能提公升。

列存還有個優勢是可以壓縮資料量。如果按前述所說將資料按維度d1,…,dn排序儲存,我們會發現d1在連續許多記錄中取值都相同,d2也是類似,但程度會弱一些,越往後的維度連續相同的程度越弱,dn就會幾乎沒有相同連續值。連續相同的值沒必要重複儲存,可以只存一次並記錄個數,這樣將可以進一步減少儲存量,也就是減少外存io訪問量,從而提高效能。

當然,列存也並不全是好處。

因為不減少計算量,列存對於記憶體資料用處不大。不過壓縮儲存方式仍然有意義,可以減少記憶體占用。

使用列存會使分段並行及建立索引的處理變得更複雜,各個列需要同步分段才能並行處理,索引也需要同步指向所有列,而使用壓縮機制後同步更為麻煩。不過,總得來講,在資料已經確定不再變化時,雖然麻煩,但難度並不算大,只是別忘處理了就行。

列存還會加大硬碟的併發壓力,在總欄位數不多或取用欄位較多時並沒有優勢。對於機械硬碟,如果再使用並行手段進一步加劇併發壓力,很可能導致效能不公升反降的結果,對於易於併發的固態硬碟使用列存較為合適。

技術調研 資料質量管理 效能量化 多維分析

如何做效能量化?根據使用者自己劃分效能量化。hive查詢效能量化 例如使用tpc ds來測試集群某些元件的查詢能行hive on spark presto tez impala等 spark任務提交量化 基於現有的集群可以並行跑多少個任務 以及對應的是使用多少資源?還是80 剩餘20 不可使用 每s...

常用的效能優化手段(記憶體優化方法)

1.使用 arc 進行記憶體管理,arc 是 ios 提供的採用自動引用計數方式進行管理記憶體的一種手法,它避免了最常見的忘記釋放物件記憶體而引起的記憶體洩漏問題。它的工作原理是編譯器會自動的為你管理 retain 和 release 過程。2.復用 reuseidentifier,在使用單元格時應...

多維分析模型頻繁變動的解決方案有哪些?

大寬表是之前常用的解決方案之一。寬表是指把業務主題相關的指標 維度 屬性關聯在一起的一張資料庫表,這樣使用者的需求都在乙個表中了,也就不需要跟著需求做變更了。這種方式的優點在於 結構簡單 模型容易理解。但是缺點也很明顯 1 有資料和表結構變動時需要重算寬表,成本較高 2 冗餘較多 3 效能無法保證 ...