4種提高多維數(shù)據(jù)分析的方法
譯文【51CTO.com快譯】聯(lián)機(jī)分析處理(OLAP)需要有即時(shí)的響應(yīng),因此其性能是至關(guān)重要的。雖然其結(jié)構(gòu)較為簡(jiǎn)單,但是在處理各種大的數(shù)據(jù)立方體(data cubes)時(shí),會(huì)涉及到大量的計(jì)算。
常被稱為OLAP(聯(lián)機(jī)分析處理)的多維分析是一種交互式的數(shù)據(jù)分析過(guò)程,它包括:對(duì)于數(shù)據(jù)立方體(data cube)進(jìn)行旋轉(zhuǎn)(rotation)、切片與切塊(slice and dice)、鉆取(drill-down)等執(zhí)行操作。其后端的計(jì)算結(jié)構(gòu)較為簡(jiǎn)單,如下列SQL語(yǔ)句所示。
- SELECT D,..., SUM(M), ... FROM C WHERE D'=d' AND ... GROUP BY D,...
該語(yǔ)句通過(guò)多個(gè)維度(dimension)聚合了各種量度(measure)。其中C是一個(gè)數(shù)據(jù)立方體,D,…表示所選的維度,而M,…則代表用于聚合的各個(gè)量度。除了SUM,我們也可以使用其他的聚合函數(shù)。D'是一個(gè)切片維度。切塊操作的范圍標(biāo)準(zhǔn),用語(yǔ)句D IN (d,...)來(lái)表示。我們還可以在量度中定義一個(gè)規(guī)則,用WHERE語(yǔ)句來(lái)選擇一定范圍內(nèi)的值。
OLAP分析需要即時(shí)的響應(yīng),因此高性能是至關(guān)重要的。盡管該語(yǔ)句的結(jié)構(gòu)較為簡(jiǎn)單,但是當(dāng)我們處理各種大的數(shù)據(jù)立方體時(shí),則可能會(huì)涉及到大量的計(jì)算。而在我們能夠找到一種優(yōu)化它們的方法之前,其分析過(guò)程一般比較緩慢的。以下我們列出了幾種能夠?yàn)槎嗑S分析提高后端性能的常見(jiàn)方法。
1. 預(yù)聚合(Pre-Aggregation)
早期的OLAP產(chǎn)品通常會(huì)采用預(yù)聚合作為一種有效地交換存儲(chǔ)開(kāi)銷(xiāo)的方法。該方法通過(guò)一些或者所有的維度(在GROUP BY語(yǔ)句中被定義),預(yù)先計(jì)算聚合的值(在SELECT查詢的各種量度中被定義),并且存儲(chǔ)它們。這些中間結(jié)果可以直接被后期的計(jì)算所使用到,或是產(chǎn)生一些新的計(jì)算。通過(guò)這種方式,性能方面能夠大幅地提升。
這些聚合的結(jié)果會(huì)占用大量的空間。通常情況下,可能會(huì)有幾十個(gè)維度,而每個(gè)維度值的范圍則從一位數(shù)到兩位數(shù)不等。簡(jiǎn)單的數(shù)學(xué)運(yùn)算表明:預(yù)聚合的結(jié)果將比原始數(shù)據(jù)立方體大幾倍到幾十倍(也就是說(shuō):如果考慮到各種類型的聚合函數(shù)的話,其比例為(k1+1)*(k2+1)*...到k1*k2*...)。盡管數(shù)據(jù)立方體不會(huì)因?yàn)樘蠖鵁o(wú)法獲得即時(shí)地響應(yīng),但是這個(gè)增大幾十倍的數(shù)據(jù)量還是不可能實(shí)現(xiàn)的。
有一個(gè)折中的方法是僅計(jì)算其中一些維度的聚合值。因?yàn)橹挥猩贁?shù)的分組維度(在GROUP BY語(yǔ)句中被定義)會(huì)被顯示在OLAP的接口中,所以我們能夠以m的維度來(lái)執(zhí)行聚合。如果m的值不大于5,則存儲(chǔ)的開(kāi)銷(xiāo)將在一個(gè)合理的范圍內(nèi),而大部分的用戶操作也將能得到快速地響應(yīng)。
當(dāng)然,部分聚合是不能使用其他維度的切片標(biāo)準(zhǔn)來(lái)處理的。然而,鉆取卻正好是基于切片的。這就糟糕地導(dǎo)致了:即使是那些對(duì)于多維分析來(lái)說(shuō)并非少見(jiàn)的且廣泛使用的聚合,也無(wú)法使用同一個(gè)量度來(lái)處理某個(gè)切片標(biāo)準(zhǔn)(比如說(shuō),要獲得超過(guò)¥1000的銷(xiāo)售額)。因此,一個(gè)聚合函數(shù)很可能僅僅包含一個(gè)標(biāo)準(zhǔn)(比如說(shuō),只是低于¥100的總成本)。可見(jiàn),預(yù)聚合的結(jié)果對(duì)于所有這些場(chǎng)景都是無(wú)用的。
預(yù)聚合只能處理一些最為常見(jiàn)的場(chǎng)景,而這些只在所有類型的多維分析場(chǎng)景中占有一小部分。而全量遍歷(full traversal)則仍然在大多數(shù)的場(chǎng)景中被用到。
2. 基于段的并行處理(Segment-Based Parallel Processing)
從本質(zhì)上講,多維分析就是對(duì)數(shù)據(jù)的過(guò)濾和分組,這就很容易實(shí)現(xiàn)并行處理。它的步驟包括:將數(shù)據(jù)劃分為多個(gè)段,分別處理它們,并收集那些相互獨(dú)立的子任務(wù)(subtask)所處理的結(jié)果,從而進(jìn)行聚合。無(wú)論是在單臺(tái)機(jī)器上,還是在多節(jié)點(diǎn)集群的計(jì)算上,甚至是兩者的結(jié)合,其多線程處理都不難以被實(shí)施。
雖然多維分析的結(jié)果是可視化的,但是我們用肉眼所能看到的數(shù)據(jù)還是遠(yuǎn)低于現(xiàn)代計(jì)算機(jī)內(nèi)存里所能夠保存的數(shù)據(jù)。對(duì)于一個(gè)足夠小的數(shù)據(jù)集,它能夠很容易地被加載到內(nèi)存中,而不需要在內(nèi)存和磁盤(pán)之間進(jìn)行交換。其編程也相對(duì)比較簡(jiǎn)單,且性能優(yōu)秀。不過(guò),在一個(gè)計(jì)算過(guò)程中生成的大數(shù)據(jù)集則會(huì)被直接提交給接口,其計(jì)算隨即被中止掉。
根據(jù)我們的測(cè)試,如果所有在同一個(gè)多線程處理的子任務(wù),合并它們的結(jié)果到一個(gè)相同的結(jié)果集里,其性能則可能會(huì)由于多個(gè)線程使用單一的資源進(jìn)行同步操作,而受到嚴(yán)重的影響。可見(jiàn),通過(guò)使用共享的最終數(shù)據(jù)集,內(nèi)存的占用會(huì)有所減少。
更多的線程并不一定總是更好的,當(dāng)線程超過(guò)CPU內(nèi)核數(shù)時(shí)它就變得無(wú)效了。對(duì)于存放在外部存儲(chǔ)設(shè)備中的數(shù)據(jù)而言,為了獲取多線程處理的實(shí)際結(jié)果,測(cè)試是必要的。因?yàn)橛脖P(pán)的并發(fā)能力(通常會(huì)小于CPU內(nèi)核的數(shù)量),需要被考慮到。
根據(jù)記錄的數(shù)量和每一段結(jié)束處的標(biāo)記,來(lái)劃分靜態(tài)數(shù)據(jù)是很容易的。但是如果要平均地劃分動(dòng)態(tài)數(shù)據(jù)就比較麻煩了。本文將在下面更詳細(xì)地予以討論。
對(duì)于一個(gè)單一的計(jì)算任務(wù)而言,并行處理能夠帶來(lái)性能上的成倍增加。而由于OLAP的操作基本就是一個(gè)并發(fā)的事務(wù),其提高了的性能在用戶的數(shù)量很小的情況下可能會(huì)被抵消掉。因此我們需要有一種更好的方法。
3. 排序索引(Sorted Index)
因?yàn)榉乔衅降木酆喜僮骺倳?huì)牽扯到整體的數(shù)據(jù)立方體,所以我們幾乎無(wú)法通過(guò)執(zhí)行預(yù)聚合來(lái)減少計(jì)算量。但是對(duì)于切片操作(鉆取)來(lái)說(shuō),如果數(shù)據(jù)立方體已經(jīng)被排序,則沒(méi)有必要去做全量遍歷了。
如果我們能為D維度創(chuàng)建一個(gè)索引,這就意味著將它的值與對(duì)應(yīng)的序列號(hào)記錄關(guān)聯(lián)上了,并形成了一定的排列順序。然后我們就能夠快速地定位那些包含在D維度里符合切片標(biāo)準(zhǔn)的記錄了。這是一個(gè)簡(jiǎn)單的二分查找。無(wú)需全量遍歷所有的數(shù)據(jù),其計(jì)算量將能夠降低好幾個(gè)數(shù)量級(jí)(這也取決于D的取值范圍)。理論上說(shuō),我們可以為每個(gè)維度創(chuàng)建一個(gè)索引,因?yàn)槠溟_(kāi)銷(xiāo)并不昂貴。而且在涉及到相應(yīng)的切片時(shí),其性能會(huì)有大幅提升。
不過(guò),那種包含有D1和D2維度的多個(gè)字段索引實(shí)際上卻鮮少被用到。因?yàn)樗荒芸焖俚囟ㄎ坏街话珼2維度的切片,它只是對(duì)同時(shí)包含D1和D2的切片非常有效。在定位到了記錄一個(gè)包含著***取值范圍的維度切片之后,大量的計(jì)算將會(huì)被相應(yīng)地大幅減少。當(dāng)然,我們也可以通過(guò)他們的維度去遍歷其他的切片。
不幸的是,這種原始的方法只適用于處理那些允許頻繁、小額存取的內(nèi)存中的數(shù)據(jù)。在大多數(shù)情況下,我們要處理的數(shù)據(jù)集還是相當(dāng)大的,而且需要存儲(chǔ)在磁盤(pán)之上。但是就算通過(guò)索引,檢索那些大量無(wú)序記錄的操作對(duì)于性能提升影響也不很大。數(shù)據(jù)只有在被真正排序,和切片里的記錄在被連續(xù)存儲(chǔ)時(shí),其性能才會(huì)有明顯的提升。
由于各種數(shù)據(jù)需要根據(jù)特定維度的排序目的來(lái)進(jìn)行復(fù)制,因此其成本還是相當(dāng)高的。
有一個(gè)用來(lái)創(chuàng)建兩份數(shù)據(jù)拷貝的解決方案是:一處的數(shù)據(jù)按照D1,…,Dn維度進(jìn)行排序,而另一處的數(shù)據(jù)則按照Dn,…,D1維度來(lái)排序。由此產(chǎn)生的數(shù)據(jù)量只是原來(lái)的兩倍,這還是可以接受的。通過(guò)該二維序列,就有了一處切片維度總是從首部開(kāi)始降序排列的,確保了此維度的切片數(shù)據(jù)在整體上是連續(xù)的,從而能夠獲得了更好的性能提高。
4. 壓縮列式存儲(chǔ)(Compressed Column Storage)
處理多維分析的一個(gè)強(qiáng)大工具是:列式存儲(chǔ)。
通常情況下,我們?cè)趯?duì)數(shù)據(jù)立方體進(jìn)行多維分析時(shí),會(huì)有大量的字段(維度和測(cè)度),他們從數(shù)十到數(shù)百不等。但是其中真正有用的卻并不多,如果不考慮切片維度的話,通常也就只有5個(gè)或更少。由于切片能夠被索引來(lái)進(jìn)行處理,那么只需要對(duì)某幾個(gè)字段遍歷便可。
基于這個(gè)考慮,列式存儲(chǔ)正好可以發(fā)揮其優(yōu)勢(shì)。在外部存儲(chǔ)的計(jì)算中,I/O的操作是非常耗時(shí)的。因此,與減少計(jì)算的數(shù)量相比,減少要檢索的數(shù)據(jù)以提升性能就顯得更有意義了。比如說(shuō)一個(gè)具有100個(gè)字段的數(shù)據(jù)立方體,如果只檢索五個(gè)字段的話,其I/O消耗將下降到原來(lái)的二十分之一,這會(huì)導(dǎo)致性能的數(shù)量級(jí)飆升。
列式存儲(chǔ)的另一個(gè)優(yōu)點(diǎn)是:它支持?jǐn)?shù)據(jù)的壓縮。在排序和存儲(chǔ)數(shù)據(jù)的D1,…,Dn維度時(shí),我們發(fā)現(xiàn)D1在一連串的記錄中有著相同的值;而D2在一個(gè)較少的連續(xù)記錄中也是如此;以此類推,在越來(lái)越少的連續(xù)記錄中,都會(huì)有這樣的相同值出現(xiàn);直到Dn中幾乎沒(méi)有了這樣的連續(xù)性。考慮我們沒(méi)有必要去存儲(chǔ)那些反復(fù)出現(xiàn)的連續(xù)相同值,我們完全可以一次性存儲(chǔ),并記錄下它們的數(shù)字。通過(guò)這種減少數(shù)據(jù)占用空間的方法,我們就能減少對(duì)外部存儲(chǔ)的I/O訪問(wèn),并提高性能。
在使用列式存儲(chǔ)時(shí),我們還需考慮如下一些問(wèn)題。
由于列式存儲(chǔ)不會(huì)減少計(jì)算的數(shù)量,它對(duì)在內(nèi)存中操作數(shù)據(jù)的幫助并不大。但其壓縮存儲(chǔ)的方案卻能夠有效地減少內(nèi)存的消耗。
列式存儲(chǔ)會(huì)復(fù)雜化基于段的并行處理和索引的創(chuàng)建。列的分割需要保持彼此的一致性,而索引則需要同時(shí)地且準(zhǔn)確地參考所有的列。而當(dāng)使用壓縮的列式存儲(chǔ)時(shí),則會(huì)更加麻煩。雖然有這些繁瑣的問(wèn)題,但是一般來(lái)說(shuō),對(duì)于靜態(tài)數(shù)據(jù)使用列式存儲(chǔ)并不是太難(只是不要忘了對(duì)它們的處理)。
列式存儲(chǔ)的使用會(huì)增加并發(fā)壓力的風(fēng)險(xiǎn)。當(dāng)字段的總數(shù)不多或我們需要檢索太多的字段時(shí),它會(huì)失去本身的優(yōu)勢(shì)。通過(guò)硬盤(pán)來(lái)額外地使用并行處理,將會(huì)進(jìn)一步地增加并發(fā)的壓力,也可能會(huì)導(dǎo)致性能的下降。因此,能夠更好地支持并發(fā)性的SSD會(huì)更適用一些。
原文標(biāo)題:4 Ways to Improve Multidimensional Data Analysis 作者: Buxing JIANG
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】