1.數(shù)據(jù)存儲(chǔ)格式數(shù)據(jù)的布局結(jié)構(gòu)深刻的影響著數(shù)據(jù)處理的效率與性能,在底層的存儲(chǔ)系統(tǒng)之中如何組織數(shù)據(jù)。如何對(duì)數(shù)據(jù)進(jìn)行布局會(huì)直接影響數(shù)據(jù)查詢引擎的設(shè)計(jì)與實(shí)現(xiàn),并且也影響著存儲(chǔ)空間的利用效率。好的數(shù)據(jù)存儲(chǔ)與布局能夠更好的利用好存儲(chǔ)空間,并且契合業(yè)務(wù)應(yīng)用場(chǎng)景的查詢實(shí)踐。接下來,我們來看看存儲(chǔ)數(shù)據(jù)的格式是如何隨著數(shù)據(jù)需求的不同進(jìn)行變遷的。 在傳統(tǒng)的數(shù)據(jù)庫系統(tǒng)之中,衍生出了一下幾種數(shù)據(jù)的布局結(jié)構(gòu):
這幾種數(shù)據(jù)布局方式各有優(yōu)點(diǎn)與缺陷,我們來一步一步梳理看看: 2.水平的行存儲(chǔ)結(jié)構(gòu)行存儲(chǔ)在傳統(tǒng)的的數(shù)據(jù)庫之中占據(jù)主導(dǎo)地位,例如MySQL的MyISAM的MYD文件,innodb的idb文件,Hive之中的Sequence文件,都是通過行存儲(chǔ)來實(shí)現(xiàn)的。如下圖所示,各個(gè)數(shù)據(jù)記錄被組織在一個(gè)n元存儲(chǔ)模型之中,數(shù)據(jù)記錄是一個(gè)接一個(gè)地按順序排列的: 當(dāng)然,這樣的存儲(chǔ)布局方式的優(yōu)點(diǎn)是:因?yàn)槊啃械臄?shù)據(jù)都共同存放,所以單行的數(shù)據(jù)加載快速,很適合OLTP數(shù)據(jù)庫的增刪改查。
所以行存儲(chǔ)并不適用于海量數(shù)據(jù)的分析查詢,由行存儲(chǔ)便衍生出新的存儲(chǔ)模式。 3.垂直的列存儲(chǔ)結(jié)構(gòu)列存儲(chǔ)結(jié)構(gòu)可以避免行存儲(chǔ)結(jié)構(gòu)的缺點(diǎn):在實(shí)際的數(shù)據(jù)讀取過程中可以避免讀取不必要的列。而且由于同一列的數(shù)據(jù)時(shí)共同存儲(chǔ)的,可以輕松地實(shí)現(xiàn)高的壓縮比例來達(dá)到節(jié)省空間的目的。 天下沒有免費(fèi)的午餐,既然列存儲(chǔ)提供了許多優(yōu)秀的特性,它自然也帶來了它自身的缺點(diǎn),如上圖所示:當(dāng)需要對(duì)單行進(jìn)行查詢處理時(shí),列存儲(chǔ)不能保證所有字段都存在同一個(gè)datanode之上,通常對(duì)于一個(gè)大表來說也是不可能的事情。在上圖之中,同一條記錄的四個(gè)字段,分別位于不同的三個(gè)HDFS塊之中,這些塊很可能就分布在不同的datanode之上,因此,對(duì)于行的讀取將會(huì)占用集群大量的帶寬資源。 更加麻煩的地方在于:當(dāng)數(shù)據(jù)刪除時(shí),由于不同的數(shù)據(jù)列分布在不同的數(shù)據(jù)節(jié)點(diǎn),所以需要同步多個(gè)數(shù)據(jù)節(jié)點(diǎn)之上的數(shù)據(jù),由此引發(fā)的一致性問題是十分棘手的. 所以盡管列存儲(chǔ)適用于單機(jī)的數(shù)據(jù)分析查詢,但是當(dāng)海量數(shù)據(jù)存放在分布式存儲(chǔ)系統(tǒng)之上時(shí),列存儲(chǔ)似乎也要付出更多的代價(jià)。 4.混合PAX存儲(chǔ)結(jié)構(gòu)
好吧,你倆都不錯(cuò),那就結(jié)合一下試一試,所以就引申出下文要聊的:混合PAX存儲(chǔ)結(jié)構(gòu) PAX最早是一種改進(jìn)CPU緩存的混合布局結(jié)構(gòu),通過對(duì)于具有多個(gè)不同字段的記錄進(jìn)行優(yōu)化來提高緩存的性能。PAX利用一個(gè)緩存頁面來存儲(chǔ)屬于每個(gè)字段的所有字段,并且布局它們的分布。(相當(dāng)于元數(shù)據(jù)) 同樣的,我們也可以利用這種混合布局的思路,來結(jié)合行存儲(chǔ)與列存儲(chǔ)的優(yōu)點(diǎn),由Facebook設(shè)計(jì)的Record Columnar File(RCFile)就借鑒了PAX存儲(chǔ)模型,通過先進(jìn)行水平分區(qū),再垂直分區(qū)的方式保證了同一行的數(shù)據(jù)一定在同一個(gè)datanode,同時(shí)在單個(gè)datanode之上又利用行存儲(chǔ)來優(yōu)化數(shù)據(jù)的查詢與存儲(chǔ)性能。 如上圖所示,在RCFile之中,在每個(gè)HDFS的數(shù)據(jù)塊之上,數(shù)據(jù)Row Group進(jìn)行排列。每個(gè)Row Group包含了三部分:
寫到這里想必大家都對(duì)RCFile有充分的了解了,我們接下來借著RCFile論文的部分再談兩個(gè)細(xì)節(jié)的問題:
懶解壓意味著列不一定在內(nèi)存中解壓縮,直到執(zhí)行單元確定列中的數(shù)據(jù)需要處理才會(huì)對(duì)數(shù)據(jù)進(jìn)行解壓。懶解壓十分適合條件查詢的應(yīng)用場(chǎng)景,如果有條件不能滿足行組中的所有記錄,則不需要進(jìn)行數(shù)據(jù)解壓,這樣可以大大減少內(nèi)存和CPU的占用。 例如,在上述查詢中,如果該Row Group之中所有的a都小于或等于1,則沒必要對(duì)Row Group的內(nèi)容進(jìn)行解壓,可以直接跳過。當(dāng)然,這里就需要依賴元數(shù)據(jù)的內(nèi)容了。
5.小結(jié):本文主要是從數(shù)據(jù)的布局角度梳理了由行存儲(chǔ)到RCFile的演變,分析了各種存儲(chǔ)布局模式所合適的場(chǎng)景。下一篇我們將繼續(xù)探討這個(gè)問題,來看看ORCFile與Parquet的是如何更進(jìn)步來解決大規(guī)模OLAP應(yīng)用的數(shù)據(jù)存儲(chǔ)格式的。 |
|