【數據蔣堂】多維分析的後台性能優化手段 | 第1期

數據蔣堂 | 每周一期,作者:潤乾軟體創始人、首席科學家蔣步星

第一期分享 多維分析的後台性能優化手段

多維分析就是針對一個事先準備好的數據立方體實施旋轉、切片(切塊)、鑽取等交互操作的過程,經常也被直接稱為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訪問量,從而提高性能。

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

因為不減少計算量,列存對於內存數據用處不大。不過壓縮存儲方式仍然有意義,可以減少內存佔用。

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

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

(全文完,蔣步星 潤乾軟體創始人、首席科學家)

編後語:天善智能在2017年3月注意到潤乾官方發布了一則消息:潤乾報表5,2.8W 10套! 這則消息讓天善智能和一些業內人士震驚不已,我們深知這個產品價格意味著什麼 —— 完全零利潤。若非內部發生大的產品調整,潤乾實在沒有理由選擇這條路 —— 一個本已在國內市場深耕十幾年的報表產品放棄百分之百的產品利潤,價格戰? 但面對激烈的市場競爭,以價格戰的方式死切一片比較本已成熟的市場,無疑是殺敵一千自損八百。帶著不解我們幾經周折聯繫上了潤乾官方,了解到了整個事情的原委。電視劇《潛伏》中有一句台詞:有一種勝利叫撤退,有一種失敗叫佔領。這句話從某種程度上可以算是這件事情的一個註解,在下一期天善智能公眾號文章中,天善智能將帶大家了解潤乾自我變革之壯士斷腕、向死而生的內幕!

( 點擊圖片了解或直接訪問潤乾官網 潤乾軟體-創新的數據計算引擎)

本文轉自天善智能公眾號,ID:tianshansoft。 可以加下微信:tianshanliangyong,一起探討BI,大數據那點知識。

推薦閱讀:

360 金融集團運營總監黃天文:驅動用戶增長的 7 大要素
「數據分析」在現實生活中的應用:用數據智斗偷車賊
你有多久沒吃泡麵了?速食麵銷量下滑真因「不尋常」
第八章:回歸

TAG:大数据分析 | 性能优化 | 数据分析 |