偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

讓我來告訴你列存數(shù)據(jù)倉(cāng)庫(kù)怎樣更高效

開發(fā) 前端
開源數(shù)據(jù)計(jì)算引擎SPL充分利用數(shù)據(jù)有序存儲(chǔ)的特征,在保持低 CPU 消耗的前提下,實(shí)現(xiàn)了較高壓縮率的壓縮算法,大幅減少了物理存儲(chǔ)量,進(jìn)一步提高了性能。SPL還提供倍增分段機(jī)制,解決了列存分段難題,讓列存數(shù)據(jù)也能充分利用并行計(jì)算來提高效率。

很多數(shù)據(jù)倉(cāng)庫(kù)產(chǎn)品都采用了列式存儲(chǔ)。如果數(shù)據(jù)表的總列數(shù)很多而計(jì)算涉及的列很少,采用列存就只讀取需要的列即可,能夠減少硬盤訪問量,提高性能。特別是數(shù)據(jù)量非常大時(shí),硬盤掃描和讀取的時(shí)間占比很大,這時(shí)候列存的優(yōu)勢(shì)會(huì)很明顯。

那么,是不是只要用了列存就一定能做到性能最佳呢?我們來看看,列式存儲(chǔ)在哪些方面還可以做的更高效。

壓縮

結(jié)構(gòu)化數(shù)據(jù)的編碼方式一般都不會(huì)非常緊湊,常常還有一定的可壓縮余地。數(shù)據(jù)倉(cāng)庫(kù)通常會(huì)在列存的基礎(chǔ)上對(duì)數(shù)據(jù)進(jìn)行壓縮,在物理上減少數(shù)據(jù)存儲(chǔ)量,從而減少讀取時(shí)間,提高性能。數(shù)據(jù)表相同字段的數(shù)據(jù)類型一般都是一樣的,甚至有些情況取值都很接近,這樣的一批數(shù)據(jù)通常會(huì)有較好的壓縮率。列存是將相同字段值存儲(chǔ)在一起的,所以比行存更有利于數(shù)據(jù)壓縮。

但是,通用的壓縮算法不能假定數(shù)據(jù)有某種特征,只能將數(shù)據(jù)當(dāng)作隨意的字節(jié)流去編碼,有時(shí)并不能獲得最好的壓縮率。而且,高壓縮率的算法壓縮出來的數(shù)據(jù),解壓縮時(shí)常常會(huì)增加CPU的運(yùn)算量,消耗更多的時(shí)間。這部分多消耗的時(shí)間,甚至?xí)笥趬嚎s節(jié)省的硬盤讀取時(shí)間,得不償失。

如果我們先對(duì)數(shù)據(jù)做一些處理,人為地制造某些數(shù)據(jù)特征來利用,再配合壓縮算法,就可以實(shí)現(xiàn)較高的壓縮率,同時(shí)保持較低的CPU消耗。

將數(shù)據(jù)排序后存儲(chǔ)就是一個(gè)有效的處理方法。數(shù)據(jù)表中常常有許多維度字段,比如地區(qū)、日期等。這些維度的取值基本都在一個(gè)小集合范圍內(nèi),數(shù)據(jù)量大時(shí)會(huì)有很多重復(fù)取值。如果數(shù)據(jù)是按這些列排序的,則相鄰記錄之間取值相同的情況就很常見。這時(shí),使用很輕量級(jí)的壓縮算法也能獲得很好的壓縮率。簡(jiǎn)單來講,可以直接存儲(chǔ)列值及其重復(fù)次數(shù),而不必把同樣的值存儲(chǔ)多遍,少占用的空間是相當(dāng)可觀的。

排序的次序也有講究。要盡量把字段值較長(zhǎng)的列放在前面排序。比如有地區(qū)和性別兩個(gè)列,地區(qū)的值(“北京”、“上海”等)字符數(shù)要大于性別(“男”、“女”),則先地區(qū)、后性別排序的效果就要好于反過來的情況。

我們還可以進(jìn)行數(shù)據(jù)類型的優(yōu)化,比如將字符串、日期等轉(zhuǎn)換為適當(dāng)?shù)臄?shù)值編碼。如果把地區(qū)、性別字段都轉(zhuǎn)換為小整數(shù)編號(hào),字段值的長(zhǎng)度就一樣了。這時(shí),可以選擇重復(fù)情況更多的字段排到前面。例如性別只有兩個(gè)枚舉值,而地區(qū)則相對(duì)較多。所以各條記錄中,性別重復(fù)的會(huì)更多,先性別、后地區(qū)排序所占用空間通常會(huì)更小。

開源數(shù)據(jù)計(jì)算引擎SPL提供的列存方案,就實(shí)現(xiàn)了這種壓縮算法。把有序數(shù)據(jù)追加進(jìn)SPL的組表時(shí),默認(rèn)會(huì)自動(dòng)執(zhí)行上述方法,只記錄一次值和重復(fù)計(jì)數(shù)。

SPL建立有序列存組表,并完成遍歷計(jì)算的寫法,大致是這樣:

示例代碼1:有序壓縮列存和遍歷計(jì)算


A

1

=file("T_ordinary.ctx").open().cursor(f1,f2,f3,f4,…).sortx(f1,f2,f3)

2

>file("T.ctx").create(#f1,#f2,#f3,f4,…).append@i(A1)

3

=file("T.ctx").open().cursor().groups(…;sum(amt1),avg(amt2),max(amt3+amt4),…)

A1:建立原數(shù)據(jù)的游標(biāo),并按照f1,f2,f3三個(gè)字段排序。

A2:建立新的組表,指定f1,f2,f3三個(gè)字段有序。將已經(jīng)排好序的數(shù)據(jù)寫入組表。

A3:打開已經(jīng)建好的新組表,做分組匯總。

在下面這個(gè)測(cè)試中,SPL采用數(shù)據(jù)類型優(yōu)化和有序壓縮列存后,數(shù)據(jù)存儲(chǔ)量減少了31%,而計(jì)算性能提高了9倍多。測(cè)試結(jié)果見下圖:

這個(gè)測(cè)試更詳細(xì)的信息請(qǐng)參考: 多維分析后臺(tái)實(shí)踐 3:維度排序壓縮

并行

多線程并行可以充分利用多CPU計(jì)算能力,是重要的提速手段。而要并行就需要先把數(shù)據(jù)分段。行存分段比較簡(jiǎn)單,按數(shù)據(jù)量大體平均分段,再找記錄結(jié)束標(biāo)記確定分段點(diǎn)位置即可。但列存不能采用同樣的辦法。由于列存的不同列是分別存儲(chǔ)的,也必須分別分段。又因?yàn)椴欢ㄩL(zhǎng)字段和壓縮數(shù)據(jù)的存在,各個(gè)列相同的分段點(diǎn)位置不一定會(huì)落在同一條記錄上,會(huì)導(dǎo)致讀取錯(cuò)誤。

業(yè)界普遍采用分塊方案解決列存分段同步性問題:塊內(nèi)數(shù)據(jù)用列式存儲(chǔ),分段必須以塊為單位,在塊內(nèi)不再分段并行。實(shí)施這種方法,要先確定每一塊的數(shù)據(jù)量大小。如果數(shù)據(jù)表總數(shù)據(jù)量固定,以后也不再追加數(shù)據(jù),則很容易計(jì)算出一個(gè)合適的塊大小。但數(shù)據(jù)表一般都會(huì)有新增數(shù)據(jù)不斷追加進(jìn)來,這就會(huì)出現(xiàn)塊大小如何確定的矛盾。假如塊較大,在初期總數(shù)據(jù)量較小時(shí),分塊數(shù)會(huì)比較少,無法做到靈活分段。而均勻、靈活的分段是決定并行計(jì)算性能的關(guān)鍵。假如塊較小,在數(shù)據(jù)量增長(zhǎng)后分塊數(shù)會(huì)變得很多,列數(shù)據(jù)在物理上將被拆成很多不連續(xù)的小塊,會(huì)多讀入分塊之間的少量無用數(shù)據(jù)??紤]硬盤的尋道時(shí)間,分塊數(shù)越多這個(gè)問題越嚴(yán)重。很多數(shù)據(jù)倉(cāng)庫(kù)或大數(shù)據(jù)平臺(tái)都無法解決這個(gè)分塊大小和分塊數(shù)的矛盾,所以很難充分利用并行計(jì)算提升性能。

SPL提供了倍增分段方式,將固定(物理)分塊改為動(dòng)態(tài)(邏輯)分塊,可以很好的解決這個(gè)矛盾。具體做法是:為每列數(shù)據(jù)建立固定大?。ɡ?1024 個(gè)索引位)的索引區(qū),每個(gè)索引位存儲(chǔ)一條記錄的起始位置,相當(dāng)于一條記錄為一塊。追加記錄到索引位填滿后,重寫索引區(qū),丟棄偶數(shù)索引位,奇數(shù)位向前移動(dòng),空出索引區(qū)后一半位置。相當(dāng)于將分塊數(shù)縮減為 512 個(gè),兩條記錄為一塊。依次類推,重復(fù)追加數(shù)據(jù)、填滿、重寫索引區(qū)的過程。隨著數(shù)據(jù)量的增加,塊的大?。▔K內(nèi)記錄數(shù))不斷翻倍。所有列的索引區(qū)要同步填充,且填滿后同步重寫,始終保持一致。這種辦法實(shí)質(zhì)上是以記錄數(shù)作為分段依據(jù)的,而不是字節(jié)數(shù),所以可以保證各個(gè)列即使分別分段也是同步的,不會(huì)出現(xiàn)錯(cuò)位的情況。

以動(dòng)態(tài)塊為單位分段時(shí),塊個(gè)數(shù)保持在 512 到 1024 之間(記錄數(shù)小于 512 除外),可以滿足分段靈活的要求。各列的動(dòng)態(tài)塊對(duì)應(yīng)記錄數(shù)完全相同,也可以滿足分段均勻的要求。數(shù)據(jù)量無論大小,都可以獲得良好的分段效果。倍增分段原理的詳細(xì)介紹參見這里:SPL 的倍增分段。

示例代碼1中生成的組表T,缺省采用了倍增分段方案。要用T做并行計(jì)算,只要將A3代碼做簡(jiǎn)單修改:

=file("T.ctx").open().cursor@m().groups(;sum(amt1),avg(amt2),max(amt3+amt4),)

cursor函數(shù)加上@m選項(xiàng),就可以做并行計(jì)算了。

后續(xù)再追加數(shù)據(jù)時(shí),不需要重新生成一遍組表。打開組表直接追加即可,代碼大致是這樣的:

> file("T.ctx").open().append@i(cs)

這里要保證游標(biāo)cs中的待追加數(shù)據(jù),按照f1,f2,f3三個(gè)字段繼續(xù)有序。實(shí)際應(yīng)用中,待追加數(shù)據(jù)不一定滿足這個(gè)條件。對(duì)于這種情況,SPL也給出了高性能的解決方案,具體方法請(qǐng)參考:SPL 的有序存儲(chǔ)。

查找

列存比較適合遍歷計(jì)算,比如分組匯總等。對(duì)于大多數(shù)查找任務(wù)來講,列存卻會(huì)導(dǎo)致更差的性能。在不用索引的時(shí)候,通常的列存即使已經(jīng)有序存儲(chǔ),也無法使用二分法查找。這個(gè)原因,和上面并行分段介紹的一樣,還是因?yàn)榱写娌荒鼙WC各列的同步性,可能會(huì)出現(xiàn)錯(cuò)位,導(dǎo)致讀取錯(cuò)誤。這時(shí)列存數(shù)據(jù)只能用遍歷法來查找了,性能會(huì)很差。

列存數(shù)據(jù)表上也可以建立索引來避免遍歷,但非常麻煩。理論上講,要在索引中把各個(gè)字段的物理位置都記錄下來,索引容量就會(huì)比行存時(shí)的索引大很多,甚至可能和原數(shù)據(jù)表一樣大(因?yàn)槊總€(gè)字段都有個(gè)物理位置,索引中的數(shù)據(jù)量和原數(shù)據(jù)相同,僅是數(shù)據(jù)類型簡(jiǎn)單)。而且,讀取時(shí)也要分別到各個(gè)字段的數(shù)據(jù)區(qū)去讀,而硬盤有個(gè)最小讀取單位,這會(huì)導(dǎo)致各列的總讀取量遠(yuǎn)遠(yuǎn)超過行存,表現(xiàn)出來就是查找性能差很多。

SPL采用倍增分段機(jī)制后,可以較迅速按記錄序號(hào)在列存格式中找到各字段值,就可以執(zhí)行二分法了。同時(shí),索引中記錄整條記錄的序號(hào)即可,容量就能小得多,和行存時(shí)差不多。不過,使用二分法或索引查找的時(shí)候,仍然需要到各個(gè)字段的數(shù)據(jù)塊分別讀取,性能還是趕不上行存。所以,如果要追求極致的查找性能,還是要采用行存。實(shí)際應(yīng)用中,最好是讓程序員根據(jù)計(jì)算的需要來選擇是否列存。但是,有些數(shù)據(jù)倉(cāng)庫(kù)做成了透明機(jī)制,不允許用戶自由選擇行存和列存,就很難達(dá)到最佳效果了。

SPL則將這個(gè)自由度留給了開發(fā)人員,可以根據(jù)實(shí)際需要來決定是否采用列存、哪些數(shù)據(jù)采用列存,從而獲得極致性能。

在前面的介紹中,組表缺省使用列存,但也提供行存模式,可以在創(chuàng)建時(shí)用選項(xiàng) @r 指明。

示例代碼1中的A2可以改為:

=file("T_r.ctx").create@r(#f1,#f2,#f3,f4,).append@i(A1)

這樣生成的就是行存組表。有了列存和行存兩個(gè)組表,程序員即可根據(jù)需要自由選擇使用。

對(duì)遍歷和查找性能要求都很高的場(chǎng)景,就只能用存儲(chǔ)空間來換計(jì)算時(shí)間。也就是將數(shù)據(jù)冗余存儲(chǔ)兩遍,列存用于遍歷,行存用于查找。不過,這種共存方案的數(shù)據(jù)要冗余兩遍,且行存還要再建立索引,所以整體占用的硬盤空間會(huì)比較大。

SPL 還提供了一種帶值索引,在建立索引時(shí)把其它字段值一起復(fù)制過來。原組表繼續(xù)采用列存用于遍歷,而索引本身已經(jīng)保存了字段值并使用行存,在查找時(shí)一般不再訪問原表,能獲得更好的性能。帶值索引和行列共存方案一樣,都能兼顧遍歷、查找的性能。而且,帶值索引相當(dāng)于行存加上索引,比行列共存方案占用的空間更小。

示例代碼2:帶值索引


A

1

=file("T.ctx").open()

2

=A1.index(IDS;f1;f4,amt1,amt2)

3

=A1.icursor(f1,f4;f1==123456).fetch()

4

=A1.icursor(f4,amt2;f1>=123456 && f2<=654321)

A2 建立索引IDS時(shí),把要引用的字段f4,amt1,amt2抄在參數(shù)中,就可以在索引中復(fù)制這些字段值。以后取出目標(biāo)值時(shí),只要涉及字段在這部分內(nèi),就不必再讀取原表。

回顧與總結(jié)

采用列存可以只讀取需要的列,在總列數(shù)較多、計(jì)算涉及的列較少時(shí),能減少硬盤訪問量,提高性能。但僅此還不夠,列存數(shù)據(jù)倉(cāng)庫(kù)還要在數(shù)據(jù)壓縮、多線程并行和查找計(jì)算等方面做優(yōu)化以將列存的效果做到最佳。

開源數(shù)據(jù)計(jì)算引擎SPL充分利用數(shù)據(jù)有序存儲(chǔ)的特征,在保持低 CPU 消耗的前提下,實(shí)現(xiàn)了較高壓縮率的壓縮算法,大幅減少了物理存儲(chǔ)量,進(jìn)一步提高了性能。SPL還提供倍增分段機(jī)制,解決了列存分段難題,讓列存數(shù)據(jù)也能充分利用并行計(jì)算來提高效率。并且,SPL能夠自由建立行存、列存數(shù)據(jù)表,允許開發(fā)者自主選擇使用,且提供了帶值索引機(jī)制,可以同時(shí)實(shí)現(xiàn)高性能遍歷和查找計(jì)算。

SPL資料

SPL下載

SPL源代碼

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2022-04-29 08:00:36

web3區(qū)塊鏈比特幣

2025-04-08 09:40:00

DWD數(shù)據(jù)倉(cāng)庫(kù)大數(shù)據(jù)

2019-04-19 08:47:00

前端監(jiān)控數(shù)據(jù)

2010-12-23 15:55:00

上網(wǎng)行為管理

2017-08-25 09:18:04

2011-08-29 09:33:48

2024-08-19 00:35:00

Pythondict遍歷列表推導(dǎo)式

2018-05-08 14:58:07

戴爾

2019-07-04 15:57:16

內(nèi)存頻率DDR4

2011-03-07 09:44:09

赤裸的密碼密碼

2024-11-08 08:34:59

RocketMQ5.Remoting通信

2015-09-30 14:22:44

Qlik數(shù)據(jù)

2023-11-24 11:20:04

functoolsPython

2016-06-30 16:54:49

UCloud愛數(shù)云計(jì)算

2022-02-15 20:08:41

JDKJavaWindows

2018-06-20 11:00:06

云應(yīng)用開發(fā)PaaS

2015-09-02 11:44:39

視頻云華為

2023-11-07 08:25:34

API接口參數(shù)驗(yàn)證

2025-04-24 08:40:00

JavaScript代碼return語句

2016-11-14 10:23:08

Hadoop工具大數(shù)據(jù)數(shù)據(jù)倉(cāng)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)