天天看點

Facebook資料倉庫揭秘:RCFile高效存儲結構

本文介紹了facebook公司資料分析系統中的rcfile存儲結構,該結構集行存儲和列存儲的優點于一身,在mapreduce環境下的大規模資料分析中扮演重要角色。

facebook曾在2010 icde(ieee international conference on data engineering)會議上介紹了資料倉庫hive。hive存儲海量資料在hadoop系統中,提供了一套類資料庫的資料存儲和處理機制。它采用類sql語言對資料進行自動化管理和處理,經過語句解析和轉換,最終生成基于hadoop的mapreduce任務,通過執行這些任務完成資料處理。圖1顯示了hive資料倉庫的系統結構。 

Facebook資料倉庫揭秘:RCFile高效存儲結構

圖1 hive資料倉庫的系統結構

基于mapreduce的資料倉庫在超大規模資料分析中扮演了重要角色,對于典型的web服務供應商,這些分析有助于它們快速了解動态的使用者行為及變化的使用者需求。資料存儲結構是影響資料倉庫性能的關鍵因素之一。hadoop系統中常用的檔案存儲格式有支援文本的textfile和支援二進制的sequencefile等,它們都屬于行存儲方式。facebook工程師發表的rcfile: a fast and spaceefficient data placement structure in mapreducebased warehouse systems一文,介紹了一種高效的資料存儲結構——rcfile(record columnar file),并将其應用于facebook的資料倉庫hive中。與傳統資料庫的資料存儲結構相比,rcfile更有效地滿足了基于mapreduce的資料倉庫的四個關鍵需求,即fast data loading、fast query processing、highly efficient storage space utilization和strong adaptivity to highly dynamic workload patterns。

資料倉庫的需求

基于facebook系統特征和使用者資料的分析,在mapreduce計算環境下,資料倉庫對于資料存儲結構有四個關鍵需求。

fast data loading

對于facebook的産品資料倉庫而言,快速加載資料(寫資料)是非常關鍵的。每天大約有超過20tb的資料上傳到facebook的資料倉庫,由于資料加載期間網絡和磁盤流量會幹擾正常的查詢執行,是以縮短資料加載時間是非常必要的。

fast query processing

為了滿足實時性的網站請求和支援高并發使用者送出查詢的大量讀負載,查詢響應時間是非常關鍵的,這要求底層存儲結構能夠随着查詢數量的增加而保持高速的查詢處理。

highly efficient storage space utilization

高速增長的使用者活動總是需要可擴充的存儲容量和計算能力,有限的磁盤空間需要合理管理海量資料的存儲。實際上,該問題的解決方案就是最大化磁盤空間使用率。

strong adaptivity to highly dynamic workload patterns

同一份資料集會供給不同應用的使用者,通過各種方式來分析。某些資料分析是例行過程,按照某種固定模式周期性執行;而另一些則是從中間平台發起的查詢。大多數負載不遵循任何規則模式,這需要底層系統在存儲空間有限的前提下,對資料進行中不可預知的動态資料具備高度的适應性,而不是專注于某種特殊的負載模式。

mapreduce存儲政策

要想設計并實作一種基于mapreduce資料倉庫的高效資料存儲結構,關鍵挑戰是在mapreduce計算環境中滿足上述四個需求。在傳統資料庫系統中,三種資料存儲結構被廣泛研究,分别是行存儲結構、列存儲結構和pax混合存儲結構。上面這三種結構都有其自身特點,不過簡單移植這些資料庫導向的存儲結構到基于mapreduce的資料倉庫系統并不能很好地滿足所有需求。

行存儲

如圖2所示,基于hadoop系統行存儲結構的優點在于快速資料加載和動态負載的高适應能力,這是因為行存儲保證了相同記錄的所有域都在同一個叢集節點,即同一個hdfs塊。不過,行存儲的缺點也是顯而易見的,例如它不能支援快速查詢處理,因為當查詢僅僅針對多清單中的少數幾列時,它不能跳過不必要的列讀取;此外,由于混合着不同資料值的列,行存儲不易獲得一個極高的壓縮比,即空間使用率不易大幅提高。盡管通過熵編碼和利用列相關性能夠獲得一個較好的壓縮比,但是複雜資料存儲實作會導緻解壓開銷增大。 

Facebook資料倉庫揭秘:RCFile高效存儲結構

圖2 hdfs塊内行存儲的例子

列存儲

圖3顯示了在hdfs上按照列組存儲表格的例子。在這個例子中,列a和列b存儲在同一列組,而列c和列d分别存儲在單獨的列組。查詢時列存儲能夠避免讀不必要的列,并且壓縮一個列中的相似資料能夠達到較高的壓縮比。然而,由于元組重構的較高開銷,它并不能提供基于hadoop系統的快速查詢處理。列存儲不能保證同一記錄的所有域都存儲在同一叢集節點,例如圖2的例子中,記錄的4個域存儲在位于不同節點的3個hdfs塊中。是以,記錄的重構将導緻通過叢集節點網絡的大量資料傳輸。盡管預先分組後,多個列在一起能夠減少開銷,但是對于高度動态的負載模式,它并不具備很好的适應性。除非所有列組根據可能的查詢預先建立,否則對于一個查詢需要一個不可預知的列組合,一個記錄的重構或許需要2個或多個列組。再者由于多個組之間的列交疊,列組可能會建立多餘的列資料存儲,這導緻存儲使用率的降低。 

Facebook資料倉庫揭秘:RCFile高效存儲結構

圖3 hdfs塊内列存儲的例子

pax混合存儲

pax存儲模型(用于data morphing存儲技術)使用混合存儲方式,目的在于提升cpu cache性能。對于記錄中來自不同列的多個域,pax将它們放在一個磁盤頁中。在每個磁盤頁中,pax使用一個迷你頁來存儲屬于每個列的所有域,并使用一個頁頭來存儲迷你頁的指針。類似于行存儲,pax對多種動态查詢有很強的适應能力。然而,它并不能滿足大型分布式系統對于高存儲空間使用率和快速查詢處理的需求,原因在于:首先,pax沒有資料壓縮的相關工作,這部分與cache優化關系不大,但對于大規模資料處理系統是非常關鍵的,它提供了列次元資料壓縮的可能性;其次,pax不能提升i/o性能,因為它不能改變實際的頁内容,該限制使得大規模資料掃描時不易實作快速查詢處理;再次,pax用固定的頁作為資料組織的基本機關,按照這個大小,在海量資料處理系統中,pax将不會有效存儲不同大小類型的資料域。本文介紹的是rcf i l e 資料存儲結構在hadoop系統上的實作。該結構強調:第一,rcfile存儲的表是水準劃分的,分為多個行組, 每個行組再被垂直劃分, 以便每列單獨存儲;第二,rcfile在每個行組中利用一個列次元的資料壓縮,并提供一種lazy解壓(decompression)技術來在查詢執行時避免不必要的列解壓;第三,rcfile支援彈性的行組大小,行組大小需要權衡資料壓縮性能和查詢性能兩方面。

rcfile的設計與實作

rcfile(record columnar file)存儲結構遵循的是“先水準劃分,再垂直劃分”的設計理念,這個想法來源于pax。它結合了行存儲和列存儲的優點:首先,rcfile保證同一行的資料位于同一節點,是以元組重構的開銷很低;其次,像列存儲一樣,rcfile能夠利用列次元的資料壓縮,并且能跳過不必要的列讀取。圖4是一個hdfs塊内rcfile方式存儲的例子。 

Facebook資料倉庫揭秘:RCFile高效存儲結構

圖4 hdfs塊内rcfile方式存儲的例子

資料格式

rcfile在hdfs分布式檔案系統之上設計并實作,如圖4所示,rcfile按照下面的資料格式來存儲一張表。

rcfile基于hdfs架構,表格占用多個hdfs塊。

每個hdfs塊中,rcfile以行組為基本機關來組織記錄。也就是說,存儲在一個hdfs塊中的所有記錄被劃分為多個行組。對于一張表,所有行組大小都相同。一個hdfs塊會有一個或多個行組。

一個行組包括三個部分。第一部分是行組頭部的同步辨別,主要用于分隔hdfs塊中的兩個連續行組;第二部分是行組的中繼資料頭部,用于存儲行組單元的資訊,包括行組中的記錄數、每個列的位元組數、列中每個域的位元組數;第三部分是表格資料段,即實際的列存儲資料。在該部分中,同一列的所有域順序存儲。從圖4可以看出,首先存儲了列a的所有域,然後存儲列b的所有域等。

壓縮方式

rcfile的每個行組中,中繼資料頭部和表格資料段分别進行壓縮。

對于所有中繼資料頭部,rcfile使用rle(run length encoding)算法來壓縮資料。由于同一列中所有域的長度值都順序存儲在該部分,rle算法能夠找到重複值的長序列,尤其對于固定的域長度。

表格資料段不會作為整個單元來壓縮;相反每個列被獨立壓縮,使用gzip壓縮算法。rcfile使用重量級的gzip壓縮算法,是為了獲得較好的壓縮比,而不使用rle算法的原因在于此時列資料非排序。此外,由于lazy壓縮政策,當處理一個行組時,rcfile不需要解壓所有列。是以,相對較高的gzip解壓開銷可以減少。

盡管rcfile對表格資料的所有列使用同樣的壓縮算法,不過如果使用不同的算法來壓縮不同列或許效果會更好。rcfile将來的工作之一可能就是根據每列的資料類型和資料分布來自适應選擇最好的壓縮算法。

資料追加

rcfile不支援任意方式的資料寫操作,僅提供一種追加接口,這是因為底層的hdfs目前僅僅支援資料追加寫檔案尾部。資料追加方法描述如下。

rcfile為每列建立并維護一個記憶體column holder,當記錄追加時,所有域被分發,每個域追加到其對應的column holder。此外,rcfile在中繼資料頭部中記錄每個域對應的中繼資料。

rcfile提供兩個參數來控制在刷寫到磁盤之前,記憶體中緩存多少個記錄。一個參數是記錄數的限制,另一個是記憶體緩存的大小限制。

rcfile首先壓縮中繼資料頭部并寫到磁盤,然後分别壓縮每個column holder,并将壓縮後的column holder刷寫到底層檔案系統中的一個行組中。

資料讀取和lazy解壓

在mapreduce架構中,mapper将順序處理hdfs塊中的每個行組。當處理一個行組時,rcfile無需全部讀取行組的全部内容到記憶體。

相反,它僅僅讀中繼資料頭部和給定查詢需要的列。是以,它可以跳過不必要的列以獲得列存儲的i/o優勢。例如,表tbl(c1, c2, c3, c4)有4個列,做一次查詢“select c1 from tbl where c4 = 1”,對每個行組,rcfile僅僅讀取c1和c4列的内容。在中繼資料頭部和需要的列資料加載到記憶體中後,它們需要解壓。中繼資料頭部總會解壓并在記憶體中維護直到rcfile處理下一個行組。然而,rcfile不會解壓所有加載的列,相反,它使用一種lazy解壓技術。

lazy解壓意味着列将不會在記憶體解壓,直到rcfile決定列中資料真正對查詢執行有用。由于查詢使用各種where條件,lazy解壓非常有用。如果一個where條件不能被行組中的所有記錄滿足,那麼rcfile将不會解壓where條件中不滿足的列。例如,在上述查詢中,所有行組中的列c4都解壓了。然而,對于一個行組,如果列c4中沒有值為1的域,那麼就無需解壓列c1。

行組大小

i/o性能是rcfile關注的重點,是以rcfile需要行組夠大并且大小可變。行組大小和下面幾個因素相關。

行組大的話,資料壓縮效率會比行組小時更有效。根據對facebook日常應用的觀察,當行組大小達到一個門檻值後,增加行組大小并不能進一步增加gzip算法下的壓縮比。

行組變大能夠提升資料壓縮效率并減少存儲量。是以,如果對縮減存儲空間方面有強烈需求,則不建議選擇使用小行組。需要注意的是,當行組的大小超過4mb,資料的壓縮比将趨于一緻。

盡管行組變大有助于減少表格的存儲規模,但是可能會損害資料的讀性能,因為這樣減少了lazy解壓帶來的性能提升。而且行組變大會占用更多的記憶體,這會影響并發執行的其他mapreduce作業。考慮到存儲空間和查詢效率兩個方面,facebook選擇4mb作為預設的行組大小,當然也允許使用者自行選擇參數進行配置。

小結

本文簡單介紹了rcfile存儲結構,其廣泛應用于facebook公司的資料分析系統hive中。首先,rcfile具備相當于行存儲的資料加載速度和負載适應能力;其次,rcfile的讀優化可以在掃描表格時避免不必要的列讀取,測試顯示在多數情況下,它比其他結構擁有更好的性能;再次,rcfile使用列次元的壓縮,是以能夠有效提升存儲空間使用率。

為了提高存儲空間使用率,facebook各産品線應用産生的資料從2010年起均采用rcfile結構存儲,按行存儲(sequencefile/textfile)結構儲存的資料集也轉存為rcfile格式。此外,yahoo公司也在pig資料分析系統中內建了rcfile,rcfile正在用于另一個基于hadoop的資料管理系統howl(http://wiki.apache.org/pig/howl)。而且,根據hive開發社群的交流,rcfile也成功整合加入其他基于mapreduce的資料分析平台。有理由相信,作為資料存儲标準的rcfile,将繼續在mapreduce環境下的大規模資料分析中扮演重要角色。

繼續閱讀