解析四種大數(shù)據(jù)文件格式
譯文【51CTO.com快譯】眾所周知,Apache Spark支持許多種不同的數(shù)據(jù)格式,其中包括:無處不在的CSV格式、對于Web友好的JSON格式、以及常被用于大數(shù)據(jù)分析的Apache Parquet和Apache Avro。
在本文中,我們將通過Apache Spark,來向您介紹上述四種大數(shù)據(jù)文件格式的各種屬性,及其優(yōu)缺點比較。
1、CSV
CSV(Comma-Separated Values,逗號分隔值)文件,通常被用于在使用純文本的系統(tǒng)之間,交換表格類型的數(shù)據(jù)。CSV是一種基于行的文件格式。也就是說,此類文件中的每一行都對應到數(shù)據(jù)表中的具體某一行。通常,CSV文件里包含有一個標題行,該標題行提供了數(shù)據(jù)的列名。如果沒有標題行的話,該文件將被視為已部分完成了結構化工作。
單個CSV文件往往無法顯示層次化的結構、或數(shù)據(jù)關系。而具體的數(shù)據(jù)連接關系往往需要通常多個CSV文件進行組織。各種外鍵(Foreign key)一般被存儲在一個或多個文件的多個列中。不過這些文件之間的鏈接并非由其格式本身來表示。此外,由于并未完全標準化,因此在CSV格式文件中,您可以使用逗號以外的界定符,例如:制表符(tabs)或空格。
CSV文件的另一個特性是:只有處于未壓縮的原始文件狀態(tài)、或是運用諸如bzip2(https://en.wikipedia.org/wiki/Bzip2)或lzo(https://ru.wikipedia.org/wiki/LZO)之類的解壓縮工具時,CSV文件才能夠被拆分(注意:lzo需要進行索引之后,方可執(zhí)行拆分)。
優(yōu)點:
- CSV易于人工閱讀,也易于手動編輯。
- CSV提供了一種簡單明了的信息模式(schema)。
- 幾乎所有現(xiàn)有的應用程序都能夠處理CSV文件。
- CSV文件比較易于實現(xiàn)和解析。
- 對于XML而言,您需要在每一行的每一列中分別添加開始與結束標簽;而CSV比較簡約,您只需一次性寫入列標題即可。
缺點:
- 由于處置的是平面數(shù)據(jù),因此需要事先對復雜的數(shù)據(jù)結構進行格式上的轉換。
- 由于不支持列的類型,因此在文本列和數(shù)字列之間并無區(qū)別。
- 并無表示二進制數(shù)據(jù)的標準方法。
- 由于NULL和引號之間并無區(qū)別,因此導入CSV時可能會出現(xiàn)問題。
- 對于特殊字符的支持性較差。
- 缺乏通用的標準。
盡管存在著一定的局限性,但CSV文件仍然是數(shù)據(jù)共享領域的上乘之選。它經(jīng)常被廣泛地用于各類業(yè)務應用、消費者行業(yè)、以及科學分析程序中。當前,大多數(shù)批處理和流數(shù)據(jù)處理模塊(如Spark和Hadoop),都能夠支持CSV文件的序列化與反序列化。它們在讀取時提供了添加schema的方法。
2、JSON格式
JSON數(shù)據(jù)(JavaScript object notation,對象表示法)是以部分結構化的格式,表示各種鍵值(key-value)對。與XML不同,JSON通??梢园凑辗謱拥母袷酱鎯?shù)據(jù),即:子數(shù)據(jù)可以由父數(shù)據(jù)來顯示。而與XML相同的是,它們在格式上都具有自我描述性(self-describing),可以被用戶直接讀取。不過,JSON文檔通常要小得多。隨著基于REST的Web服務的大量出現(xiàn),JSON文檔被頻繁地使用在網(wǎng)絡通信中。
由于許多類型的數(shù)據(jù)傳輸都已經(jīng)用到了JSON格式,因此目前大多數(shù)的Web編程語言都能夠支持JSON,或者通過使用外部庫,來對JSON數(shù)據(jù)進行序列化和反序列化。正是有了這種支持,JSON能夠通過顯示數(shù)據(jù)結構,幫助用戶實現(xiàn)熱數(shù)據(jù)(hot data)的格式轉換、以及冷數(shù)據(jù)(cold data)存儲所涉及到的各種邏輯格式。
目前,許多批處理與流數(shù)據(jù)處理模塊,都能夠原生地支持JSON的序列化和反序列化。JSON文檔中包含的數(shù)據(jù),不但最終能夠以性能更為優(yōu)化的格式(如Parquet或Avro)予以存儲,而且JSON所提供的原始數(shù)據(jù)類型,對于按需進行數(shù)據(jù)重新處理的任務也是非常重要的。
JSON文件具有如下優(yōu)點:
- JSON支持分層式結構,簡化了文檔中有關數(shù)據(jù)的存儲,以及復雜關系的表示問題。
- 大多數(shù)編程語言都能夠提供簡化的JSON序列化庫,并且能夠對JSON序列化/反序列化提供內(nèi)置的支持。
- JSON支持對象列表,能夠有助于避免將對象列表錯誤地轉換為關系型數(shù)據(jù)模型。
- 諸如MongoDB、Couchbase和Azure Cosmos DB等NoSQL數(shù)據(jù)庫,都能夠支持JSON文件格式。
- 目前大多數(shù)工具都內(nèi)置了對于JSON的支持。
3、Parquet
Cloudera和Twitter于2013年開發(fā)出了Parquet。它可以被用作基于列的存儲格式,并針對多列數(shù)據(jù)集進行了適當?shù)貎?yōu)化。由于其數(shù)據(jù)是按列進行存儲的,因此它可以對數(shù)據(jù)進行高度壓縮(其壓縮算法對于那些包含在列中的、信息熵值較低的數(shù)據(jù),效果會更好),以及拆分操作。Parquet的開發(fā)者號稱:此類存儲格式非常適合于處理大數(shù)據(jù)的相關問題。
與CSV和JSON不同,Parquet是一種二進制文件,其中包含了各種針對其內(nèi)容的元數(shù)據(jù)(metadata)。因此,在無需讀取與解析文件內(nèi)容的情況下,Spark可以僅依靠元數(shù)據(jù)來確定文件中的列名稱、壓縮/編碼方式、數(shù)據(jù)類型、乃至一些基本的統(tǒng)計類信息。另外,由于Parquet文件的列相關元數(shù)據(jù)通常被存儲在文件的末尾,因此方便了用戶一次性快速地寫入信息。同時,Parquet針對WORM(Write Once Read Many,一次寫入多次讀取,請參見)的范例也進行了優(yōu)化。雖然在寫入文件其速度較慢,但是用戶在讀取時,尤其是僅訪問某個列的子集時,速度卻快得驚人??梢姡瑢τ谀切┬枰罅窟M行讀取操作的工作負載而言,Parquet是一種不錯的選擇。而對于需要操作整行數(shù)據(jù)的用例而言,用戶則應當使用CSV或AVRO之類的格式。
Parquet在數(shù)據(jù)存儲方面的優(yōu)點包括:
- 由于是一種柱狀結構的形式,因此Parquet只會讀取所需的列信息,進而減少了對于磁盤I/O的消耗。這個概念被稱為投影下推(projection pushdown)。
- 由于schema是隨著數(shù)據(jù)一起移動的,因此數(shù)據(jù)能夠自我描述(self-describing)。
- 雖然主要是為HDFS而創(chuàng)建的,但是其數(shù)據(jù)完全可以被存儲在GlusterFs或NFS之類的其他文件系統(tǒng)中。
- 作為一個文件,您可以輕松地對Parquet進行移動、備份、復制、以及使用。
- 能夠對Spark提供開箱即用式的原生支持,能夠對于用戶存儲中的文件直接進行讀取與保存。
- 當采用諸如snappy之類的壓縮格式時,Parquet可以達到75%的高壓縮比。
- 在實際運用中,與同類其他文件格式相比,該格式讀取工作流的速度最快。
- Parquet非常適合于那些需要對大量數(shù)據(jù)進行列匯總的數(shù)據(jù)倉庫類應用。
- 可以通過Avro API和Avro Schema來讀取和寫入Parquet。
- 通過提供謂詞下推(predicate pushdown),Parquet可以進一步降低磁盤I/O的成本。
謂詞下推/過濾下推
謂詞下推的基本思想是:將查詢的某些部分(如:謂詞)“推送”到數(shù)據(jù)的存儲位置。例如,當我們提供一些過濾條件時,數(shù)據(jù)存儲將會以過濾記錄的方式,再從磁盤中讀取數(shù)據(jù)。
謂詞下推的優(yōu)點:由于不再需要將整個數(shù)據(jù)讀入內(nèi)存并進行過濾,因此它并不需要大量的內(nèi)存,也不會產(chǎn)生過多的磁盤I/O。顯然整體性能得到了顯著提升。
可見,此類方法可以通過較早地過濾掉無關數(shù)據(jù)的方式,來大幅減少查詢與處理的時間。根據(jù)處理框架的不同,謂詞下推可以通過執(zhí)行不同的操作來優(yōu)化查詢。例如:在通過網(wǎng)絡傳輸之前便過濾數(shù)據(jù),在將數(shù)據(jù)加載到內(nèi)存之前過濾數(shù)據(jù),或是跳過讀取整個文件(文件塊)等操作。
目前,大多數(shù)RDBMS,包括Parquet和ORC等大數(shù)據(jù)存儲格式,都能夠遵循謂詞下推的相關概念。
投影下推
投影下推的基本思想是:在對存儲進行數(shù)據(jù)查詢與讀取時,并非讀取所有字段,而只是讀取那些必需的列。通常,Parquets和ORC之類的列格式都能夠通過遵循此概念,以產(chǎn)生更好的I/O性能。
4、Avro
由Hadoop工作組于2009年發(fā)布的Apache Avro,是一種基于行的、可高度拆分的數(shù)據(jù)格式。Avro能夠支持多種編程語言。通常,它也被描述為類似于Java序列化的數(shù)據(jù)序列化系統(tǒng)。為了最大程度地減小文件大小、并提高效率,它將schema存儲為JSON格式,而將數(shù)據(jù)存儲為二進制格式。
Avro通過管理各種添加、丟失、以及已更改的字段,來為schema的演化提供強大的支持。這使得舊的軟件可以讀取新的數(shù)據(jù),而新的軟件也可以讀取那些舊的數(shù)據(jù)。而這對于那些經(jīng)常發(fā)生變更的數(shù)據(jù)而言,是非常重要的。
Avro通過schema架構的管理能力,可以在不同的時段獨立地更新不同的組件,從而降低了不兼容性所帶來的風險。同時,開發(fā)人員既不必在應用程序中編寫if-else語句,來應對不同的架構版本,也不必通過查看舊的代碼,來理解那些舊的架構。而且,所有版本的schema都存儲在可讀的JSON標頭中,以方便開發(fā)人員理解所有可用的字段。
如前文所述,由于schema是以JSON格式存儲的,而數(shù)據(jù)是以二進制形式存儲的,因此Avro是持久性數(shù)據(jù)存儲和電傳(wire transfer)的簡約之選。另外,由于用戶能夠輕松地向Avro附加新的數(shù)據(jù)行,因此它通常是那些大量寫入工作負載的首選格式。
優(yōu)點:
- Avro是一種與語言無關的數(shù)據(jù)序列化。
- Avro將schema存儲在文件的標題中,因此數(shù)據(jù)具有自描述性。
- Avro格式的文件既可以被拆分、又可以被壓縮,因此非常適合于在Hadoop生態(tài)系統(tǒng)中進行數(shù)據(jù)的存儲。
- 由于Avro文件將負責讀取的schema與負責寫入的schema區(qū)分開來,因此它可以獨立地添加新的字段。
- 與序列文件(Sequence Files)相同,為了實現(xiàn)高度可拆分性,Avro文件也包含了用于分隔不同塊(block)的同步標記。
- 可以使用諸如snappy之類的壓縮格式,來壓縮不同的目標塊。
總結
下表是上述四種文件格式的綜合比較。
上表中的*號為:當作為CSV被壓縮時,JSON具有可拆分性方面的類似問題。也就是說:當“wholeFile”選項被設置為true時(請參閱SPARK-18352),JSON是不可拆分的。
- CSV有著最快的寫入速度;JSON方便了人工閱讀和理解;Parquet在讀取列的子集方面速度最快;而Avro在一次性讀取所有列方面速度最快。
- JSON是Web通信方面的標準。通過定義良好的schema,各種API和網(wǎng)站可以持續(xù)使用JSON進行通信。
- 針對大數(shù)據(jù)的需求,Parquet和Avro進行了可拆分性方面的優(yōu)化,可支持各種壓縮,以及復雜數(shù)據(jù)結構。不過,它們的可讀性和寫入速度非常差。
原文標題:Big Data File Formats Explained,作者:luminousmen
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】