關(guān)鍵詞: 文件格式 壓縮效率 文件可分片
需要考慮的因素
文件格式對存儲空間利用率, 程序性能都有很大的影響. 具體表現(xiàn)在:
- 文件和壓縮算法的組合是否支持可分片, MapReduce在讀取數(shù)據(jù)的時候需要并行, 這就要求壓縮后的文件可以分片讀取.
在考慮如何壓縮那些將由MapReduce處理的數(shù)據(jù)時岛抄,考慮壓縮格式是否支持分割是很重要的竣况《绕考慮存儲在HDFS中的未壓縮的文件扰柠,其大小為1GB抗悍,HDFS的塊大小為64MB桑李,所以該文件將被存儲為16塊嘲叔,將此文件用作輸入的MapReduce作業(yè)會創(chuàng)建1個輸人分片(split姐扮,也稱為“分塊”。對于block子巾,我們統(tǒng)一稱為“塊”帆赢。)每個分片都被作為一個獨立map任務(wù)的輸入單獨進行處理。
- io讀取性能, 讀取相同信息量的信息, 壓縮后的文件不僅占用的存儲空間低, 而且還會提高磁盤io的讀取效率. 提高程序的運行速度
- CPU資源也是啟用何種壓縮算法不得不考慮的因素, 一般來說壓縮效率越高的算法對io效率和存儲利用率的提升越有促進作用, 但另一方面也會更高的消耗CPU資源. 所以我們需要在這中間尋求一個平衡點.
- 共通性, 文件格式是否支持多種語言, 服務(wù)的讀取. 比如Hadoop主要的序列化格式為Writables, 但是Writables只支持Java, 所以后面衍生出了Avro, Thrift等格式. 還如OrcFile是對Hive設(shè)計的一種列式存儲格式, 但是他不支持Impala, 數(shù)據(jù)的共用性受到了制約.
- 錯誤處理能力, 有的文件的某一部分壞掉之后會影響整個表, 有的只會影響其后的數(shù)據(jù), 有的只會影響壞掉數(shù)據(jù)塊本身(Avro).
- 讀取和載入效率, RCFile的載入速度慢, 但是查詢相應(yīng)速度快, 相對更適合數(shù)據(jù)倉庫一次插入多次讀取的特性.
文件格式
hadoop存儲上沒有既定的標(biāo)準(zhǔn)文件格式和壓縮算法, 它和標(biāo)準(zhǔn)文件系統(tǒng)相同, 可以存儲各種各樣類型的文件, 也支持多種壓縮算法. 使用什么格式和壓縮算法的主動權(quán)在使用者手里. 我們可以根據(jù)具體需求來權(quán)衡使用哪種組合.
標(biāo)準(zhǔn)文件格式
標(biāo)準(zhǔn)文件格式可以分為文本文件(如 CSV, XML, JSON 等)和二進制文件(圖像, 視頻等).
文本數(shù)據(jù)格式
txt, csv等純文本格式是很常見的, 比如日志的存儲和分析. 一般來說, 在大多數(shù)場景中, 使用容器格式(如SequenceFile, Avro)都會帶來很多好處. 后面會介紹容器格式. 文本數(shù)據(jù)有一些不可避免的缺點:
- 存儲空間利用率低
- 會有額外的序列化反序列化開銷: 比如1234存儲在文件中是字符串的形式, 轉(zhuǎn)入程序中又是數(shù)字型的話讀取和寫入都會有額外的不必要的性能開銷, 數(shù)量大的話性能影響就會更加顯著.
結(jié)構(gòu)化文本格式
我們常見的json, xml格式就屬于此類, 他們很難分片, 且沒有hadoop內(nèi)置提供的InputFormat. 使用他們的時候, 一般用第三方的提供的InputFormat, 或者是將數(shù)據(jù)轉(zhuǎn)化成Avro格式的數(shù)據(jù)再進行處理.
二進制數(shù)據(jù)
雖然Hadoop中存儲的大多都是文本, 但是我們也可以存儲圖像等二進制文件. 對于大多數(shù)應(yīng)用場景來說使用SequenceFile等容器格式都是很適用的.
Hadoop文件類型
為了配合MapReduce, 開發(fā)一些專門格式. 基于文件的SequenceFile, 序列化的Avro和列式存儲的RCFile和Parquet. 上面的這些雖然各有不同, 但是有些重要的特性是共有的, 這對MapReduce任務(wù)來說至關(guān)重要. 這些文件都支持通用的壓縮算法, 也支持分片.
基于文件的SequenceFile
以二進制鍵值對的形式存儲數(shù)據(jù), 支持三種記錄存儲方式.
- 無壓縮, io效率較差. 相比壓縮, 不壓縮的情況下沒有什么優(yōu)勢.
- 記錄級壓縮, 對每條記錄都壓縮. 這種壓縮效率比較一般.
- 塊級壓縮, 這里的塊不同于hdfs中的塊的概念. 這種方式會將達(dá)到指定塊大小的二進制數(shù)據(jù)壓縮為一個塊. 相對記錄級壓縮, 塊級壓縮擁有更高的壓縮效率. 一般來說使用SequenceFile都會使用塊級壓縮.
但是SequenceFile只支持Java, SequenceFile一般用來作為小文件的容器使用, 防止小文件占用過多的NameNode內(nèi)存空間來存儲其在DataNode位置的元數(shù)據(jù).
序列化存儲格式
序列化指的是數(shù)據(jù)格式轉(zhuǎn)化為字節(jié)流的過程, 主要用于遠(yuǎn)程傳輸或存儲. hadoop采用的序列化格式主要是Writables. 但是它只能支持Java語言, 所以后來就出現(xiàn)了Thrift, Avro等格式.
Thrift
Facebook開發(fā)的框架, 用于實現(xiàn)跨語言提供服務(wù)和接口, 滿足跨平臺通信. 但是Thrift不支持分片, 且缺少MapReduce的原生支持.
Avro
Avro是一個語言無關(guān)的數(shù)據(jù)序列化的系統(tǒng), 它的出現(xiàn)主要是為了解決Writables缺少跨語言移植的缺陷. Avro將模式存儲在文件頭中, 所以每個文件都是自描述的, 而且Avro還支持模式演進(schema evolution), 也就是說, 讀取文件的模式不需要與寫入文件的模式嚴(yán)格匹配, 當(dāng)有新需求時, 可以在模式中加入新的字段.
- Avro支持分片, 即使是進行Gzip壓縮之后.
- 支持跨語言的支持
列級存儲
ORCFile
ORCFile 可以理解為 Optimized RCFile, 就是RCFile的優(yōu)化版. 尤其是彌補了查詢和存儲效率方面的缺陷. 它同樣不喜歡小文件. 特性如下:
- 支持所有的hive類型, 包括復(fù)合類型: structs, lists, maps 和 unions.
- 支持分片
- 可以僅返回查詢的列, 減少io消耗, 提升性能.
- 可以與Zlib, LZO和Snappy結(jié)合進一步壓縮.
- 不支持其他的查詢引擎, 比如impala.
- 內(nèi)件索引: 其存儲了
壓縮
Snappy
Google開發(fā)的一種壓縮編解碼器, 用于實現(xiàn)高速壓縮, 適當(dāng)兼顧壓縮率, 平衡了壓縮速率和文件大小. 但是有一點, Snappy是不支持分片的, 所以它需要和容器格式相互聯(lián)合使用(如SequenceFile和Avro).
LZO
壓縮率和速度與Snappy相近, 由于許可協(xié)議的原因, LZO不能打包進hadoop中進行分發(fā), 需要單獨安裝. Snappy可以與Hadoop打包分發(fā). 它可以支持分割, 但是要求建立索引.
Gzip
壓縮速率非常好, 平均可以達(dá)到Snappy的2.5倍. 但是相應(yīng)的, 寫入相對較Snappy慢了一倍. Gzip同樣也是不支持分片的, 所以應(yīng)該與容器格式聯(lián)合使用. Gzip更適合將數(shù)據(jù)進行歸檔.
bzip2
壓縮性能比Gzip還要高9%, 但是要消耗更多的讀取, 寫入性能. 一般來說bzip2要比Gzip慢十倍. 所以bzip2應(yīng)該不是hadoop集群上理想的編解碼格式, 除非需求以為了減少空間占用為主. 比如將數(shù)據(jù)進行歸檔, 但是使用的時候也要考慮資源的消耗. 另外的, bzip2是支持?jǐn)?shù)據(jù)分割的.
幾種壓縮算法的簡單對比
壓縮方式 | 壓縮效率 | 壓縮速度 | 是否可分割 |
---|---|---|---|
Gzip | 中高 | 中 | 否 |
bzip2 | 高 | 慢 | 是 |
Snappy | 低 | 快 | 否 |
LZO | 低 | 快 | 是(但是要求建立索引) |
Zlib | 低 | 快 | 是 |
Hive數(shù)據(jù)格式和壓縮
textfile, sequencefile, rcfile, orc
Snappy與Zlib的對比
Disk Usage Comparison:
Hive列式存儲ORC和行式存儲Text
如果經(jīng)常會對存儲的數(shù)據(jù)進行少量列的聚合查詢, 那么使用列式存儲會降低在查詢時所需的磁盤空間, 減少I/O消耗, 更快的得到查詢結(jié)果. 這篇文章里面測試的是列式存儲格式ORC相對行式存儲Text, 在大量列中查詢聚合少量列的情況下的性能提升情況.
- 原始測試數(shù)據(jù)為2200萬條頁面點擊記錄.
- 每行有40列
- 數(shù)據(jù)文件沒有壓縮
-
使用ORC格式時, 減少了52%的空間.
-
減少了97%的I/O消耗
-
提升了21%的查詢時間
-
聚合結(jié)果如下:
- 相對基于Text文件的大量文件的聚合查詢, 使用ORC文件格式并不總是總是顯著的減少內(nèi)存和CPU的消耗. 事實上, 使用ORC文件可能會引起更多的內(nèi)存占用, 你可以通過使用壓縮(例如Zlib或Snappy)來優(yōu)化, 然而, 壓縮和解壓縮會增加CPU的使用時間.
配置
#影響非托管表的建表語句:
hive.default.fileformat=[textfile, sequencefile, rcfile, orc]
#影響托管表的建表語句, 如果不填則繼承hive.default.fileformat
的值.
hive.default.fileformat.managed=[textfile, sequencefile, rcfile, orc]
以O(shè)RC文件為例
格式可以指定到表級/分區(qū)級, 你可以通過形如下面的HiveQL語句指定ORCFile格式:
- CREATE TABLE ... STORED AS ORC
- ALTER TABLE ... [PARTITION partition_spec] SET FILEFORMAT ORC
- SET hive.default.fileformat=Orc
參考:
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+ORC
《hadoop應(yīng)用架構(gòu)》
ORC with Zlib vs ORC with No Compression[大的數(shù)據(jù)更適合使用壓縮]
Performance Comparison b/w ORC SNAPPY and ZLib in hive/ORC files
Hive & Parquet
ORC Creation Best Practices
https://orc.apache.org/docs/indexes.html