天天看點

【資料蔣堂】多元分析的背景性能優化手段

“ 

開篇辭

《資料蔣堂》的作者蔣步星,從事資訊系統建設和資料處理長達20多年的時間。他豐富的工程經驗與深厚的理論功底互相融合、創新思想與傳統觀念的互相碰撞,虛拟與現實的互相交織,産生出了一篇篇的瀝血之作。此連載的内容涉及從資料呈現、采集到加工計算再到存儲以及挖掘等各個方面。大可觀資料世界之遠景、小可看技術疑難之細節。針對資料領域一些技術難點,站在研發人員的角度從淺入深,進行全方位、360度無死角深度剖析;對于一些業内觀點,站在技術人員角度闡述自己的思考和了解。蔣步星還會對大資料的發展,站在業内專家角度給予預測和推斷。靜下心來認真研讀你會發現,《資料蔣堂》的文章,有的會讓使用者避免重複前人走過的彎路,有的會讓攻城獅面對紮心的難題茅塞頓開,有的會為初入行業的讀者提供一把開啟資料世界的鑰匙,有的甚至會讓業内專家大跌眼鏡,産生思想交鋒。

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

【資料蔣堂】多元分析的背景性能優化手段

即對立方體按某些次元分組彙總某些測度。其中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通路量,進而提高性能。

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

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

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

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

專欄作者簡介

蔣步星,潤乾軟體創始人、首席科學家

清華大學計算機碩士,著有《非線性報表模型原理》等,1989年,中國首個國際奧林匹克數學競賽團體冠軍成員,個人金牌;2000年,創立潤乾公司;2004年,首次在潤乾報表中提出非線性報表模型,完美解決了中國式複雜報表制表難題,目前該模型已經成為報表行業的标準;2014年,經過7年開發,潤乾軟體釋出不依賴關系代數模型的計算引擎——集算器,有效地提高了複雜結構化大資料計算的開發和運算效率;2015年,潤乾軟體被福布斯中文網站評為“2015福布斯中國非上市潛力企業100強”;2016年,榮獲中國電子資訊産業發展研究院評選的“2016年中國軟體和資訊服務業十大領軍人物”;2017年, 自主創新研發新一代的資料倉庫、雲資料庫等産品即将面世。

原文釋出時間為:2017-04-07

本文作者:蔣步星

本文來自雲栖社群合作夥伴“資料派THU”,了解相關資訊可以關注“資料派THU”微信公衆号