第5章:Hadoop I/O

Hadoop有一些數(shù)據(jù)I/O方面操作的工具欢摄,其中一些比Hadoop使用的都更普遍。例如數(shù)據(jù)完整性和壓縮笋粟。但是當(dāng)使用這些工具處理多達(dá)幾TB數(shù)據(jù)的時(shí)候怀挠,仍然需要特別注意。其它的一些工具或APIs構(gòu)建成了模塊用于開(kāi)發(fā)分布式系統(tǒng)害捕,例如:序列化框架和硬盤(pán)上的數(shù)據(jù)結(jié)構(gòu)化绿淋。

數(shù)據(jù)完整性

Hadoop的使用者肯定都希望數(shù)據(jù)在存儲(chǔ)或處理的過(guò)程中不會(huì)丟失或損壞。然而尝盼,由于硬盤(pán)或網(wǎng)絡(luò)的每一次I/O操作都有可能在讀或?qū)懙倪^(guò)程中出錯(cuò)吞滞,Hadoop經(jīng)常處理的數(shù)據(jù)量都相當(dāng)大,當(dāng)這樣地大量數(shù)據(jù)在系統(tǒng)中傳輸時(shí)盾沫,數(shù)據(jù)損壞的概率還是挺高的裁赠。

通常用于判斷數(shù)據(jù)是否損壞所使用的方法是當(dāng)數(shù)據(jù)第一次進(jìn)入系統(tǒng)時(shí)候計(jì)算一個(gè)校驗(yàn)和,并不管在任何時(shí)候赴精,數(shù)據(jù)被傳輸通過(guò)一個(gè)不可信的通道后佩捞,再一次計(jì)算校驗(yàn)和,就可以判斷數(shù)據(jù)是否損壞蕾哟。如果新生成的校驗(yàn)和與原始的校驗(yàn)和不一樣一忱,就認(rèn)為數(shù)據(jù)遭到了損壞。這個(gè)技術(shù)不能夠修復(fù)數(shù)據(jù)谭确,僅僅是檢查數(shù)據(jù)是否損壞帘营。(這也是不使用低檔的硬件的原因,特殊情況下琼富,肯定要使用ECC內(nèi)存)仪吧。注意:有時(shí)校驗(yàn)和也可能損壞,而數(shù)據(jù)沒(méi)有損壞鞠眉,但這種可能性很低薯鼠,因?yàn)樾r?yàn)和比數(shù)據(jù)小多了。

通常使用的錯(cuò)誤檢測(cè)碼是CRC-32(32位循環(huán)冗余校驗(yàn))械蹋,不管輸入的數(shù)據(jù)量多大出皇,都計(jì)算出一個(gè)32的整數(shù)校驗(yàn)和。CRC-32在Hadoop的ChecksumFileSystem類(lèi)中用于計(jì)算校驗(yàn)和哗戈。然而HDFS使用的是另一種更有效的方式郊艘,叫做CRC-32C。

HDFS中的數(shù)據(jù)完整性

HDFS透明地計(jì)算寫(xiě)入的所有數(shù)據(jù)的校驗(yàn)和,并且默認(rèn)情況下會(huì)在讀取數(shù)據(jù)時(shí)驗(yàn)證校驗(yàn)和纱注。每個(gè)用dfs.bytes-per-checksum屬性指定大小的數(shù)據(jù)塊都會(huì)單獨(dú)生成一個(gè)校驗(yàn)和畏浆。默認(rèn)是512字節(jié)。因?yàn)镃RC-32C校驗(yàn)和是4個(gè)字節(jié)狞贱,所以存儲(chǔ)開(kāi)銷(xiāo)少于1%刻获。((12810241024)/5124/12810241024)100%=0.78%。

數(shù)據(jù)節(jié)點(diǎn)有責(zé)任在接收到數(shù)據(jù)后存儲(chǔ)數(shù)據(jù)前校驗(yàn)數(shù)據(jù)瞎嬉,并計(jì)算校驗(yàn)和蝎毡,不管從客戶(hù)端接收數(shù)據(jù)還是在復(fù)制復(fù)本數(shù)據(jù)期間從其它節(jié)點(diǎn)接收數(shù)據(jù)。正在寫(xiě)入數(shù)據(jù)到HDFS的客戶(hù)端將校驗(yàn)和傳入數(shù)據(jù)節(jié)點(diǎn)的管道中(如第3章介紹的那樣)氧枣,管道中的最后一個(gè)數(shù)據(jù)節(jié)點(diǎn)驗(yàn)證校驗(yàn)和沐兵。如果數(shù)據(jù)節(jié)點(diǎn)檢測(cè)到錯(cuò)誤,客戶(hù)端會(huì)收到一個(gè)IOExcption子類(lèi)的異常便监,客戶(hù)端應(yīng)該采取應(yīng)用程序特定的措施扎谎,比如,重新嘗試寫(xiě)入茬贵。

當(dāng)客戶(hù)端從數(shù)據(jù)節(jié)點(diǎn)讀取數(shù)據(jù)的時(shí)候簿透,它們也要驗(yàn)證校驗(yàn)和移袍,將讀取的數(shù)據(jù)計(jì)算出的校驗(yàn)和和存儲(chǔ)在數(shù)據(jù)節(jié)點(diǎn)中的校驗(yàn)和進(jìn)行比較解藻。每一個(gè)數(shù)據(jù)節(jié)點(diǎn)都永久保存了一份驗(yàn)證校驗(yàn)和的歷史日志。所以HDFS知道每一個(gè)數(shù)據(jù)塊最近驗(yàn)證校驗(yàn)和的時(shí)間葡盗。當(dāng)客戶(hù)端成功地校驗(yàn)了某一塊數(shù)據(jù)的時(shí)候螟左,它會(huì)告訴數(shù)據(jù)節(jié)點(diǎn),數(shù)據(jù)節(jié)點(diǎn)會(huì)更新日志觅够。保存這些校驗(yàn)的信息可以用于檢測(cè)壞的硬盤(pán)胶背。

除了客戶(hù)端讀取數(shù)據(jù)時(shí)的塊校驗(yàn),每一個(gè)數(shù)據(jù)節(jié)點(diǎn)都會(huì)以一個(gè)后臺(tái)線(xiàn)程方式執(zhí)行一個(gè)DataBlockScanner,周期性檢測(cè)存儲(chǔ)在這個(gè)數(shù)據(jù)節(jié)點(diǎn)上的數(shù)據(jù)塊是否損壞喘先。這是為了防止由于物理存儲(chǔ)媒介的"位衰減"造成的數(shù)據(jù)損壞钳吟。可以看第11章的"數(shù)據(jù)節(jié)點(diǎn)塊掃描"相關(guān)內(nèi)容詳細(xì)了解如何獲取掃描的報(bào)告窘拯。

由于HDFS存儲(chǔ)著數(shù)據(jù)塊的復(fù)本红且,所以它能夠通過(guò)復(fù)制一個(gè)好的復(fù)本生成一個(gè)新的,沒(méi)有損壞的復(fù)本來(lái)修復(fù)已經(jīng)損壞的塊涤姊。具體實(shí)現(xiàn)方法是客戶(hù)端在讀取塊數(shù)據(jù)時(shí)如果檢測(cè)到一個(gè)錯(cuò)誤暇番,它會(huì)向名稱(chēng)節(jié)點(diǎn)報(bào)告這個(gè)壞的塊和塊所在的數(shù)據(jù)節(jié)點(diǎn),然后拋出一個(gè)ChecksumException異常思喊。名稱(chēng)節(jié)點(diǎn)會(huì)將這個(gè)塊狀態(tài)標(biāo)記為"損壞"壁酬,并不再將其它客戶(hù)端提供這個(gè)塊的地址,然后在另外一個(gè)數(shù)據(jù)節(jié)點(diǎn)中生成這個(gè)塊的一個(gè)復(fù)本,直到達(dá)到設(shè)置的塊復(fù)本數(shù)舆乔,一旦完成后岳服,這個(gè)損壞的塊就會(huì)被刪除。

我們可以在調(diào)用FileSystem的open方法打開(kāi)文件之前希俩,調(diào)用它的setVerifyChecksum方法派阱,傳遞一個(gè)false值,就可以關(guān)閉校驗(yàn)和的驗(yàn)證斜纪。如果使用shell命令贫母,我們可以在-get或-copyToLocal命令中添加-ignoreCrc選項(xiàng)同樣可以關(guān)閉校驗(yàn)和的驗(yàn)證。如果你想要看看這部分損壞的數(shù)據(jù)盒刚,再進(jìn)行相應(yīng)處理的話(huà)瘤运,這個(gè)功能將是有用的键痛。例如,你也許想在刪除損壞的塊數(shù)據(jù)之前想要看看是否能夠恢復(fù)塊中的數(shù)據(jù)。

你可以通過(guò)使用hadoop fs -checksum來(lái)得到一個(gè)文件的校驗(yàn)和柄驻。這對(duì)于檢查HDFS中兩個(gè)文件是否有相同的內(nèi)容是有用的(distcp命令也可以做這些事情),可以參看"使用distcp命令并發(fā)復(fù)制"小節(jié)舉的示例猩系。

LocalFileSystem

Hadoop LocalFileSystem在客戶(hù)端驗(yàn)證校驗(yàn)和绍申。這意味著當(dāng)你向一個(gè)叫"filename"的文件中寫(xiě)入數(shù)據(jù)時(shí),文件系統(tǒng)客戶(hù)端會(huì)在文件相同目錄透明的創(chuàng)建一個(gè)隱藏的文件吩愧,叫做 .filename.crc芋酌,這個(gè)文件包含每一段文件數(shù)據(jù)的檢驗(yàn)和。段的大小由屬性file.bytes-per-checksum定義雁佳,默認(rèn)是512字節(jié)脐帝。段大小做為元數(shù)據(jù)存儲(chǔ)在.crc后綴的文件中,所以即使段大小的設(shè)置以后改變了糖权,文件仍然可以完好無(wú)損地讀取堵腹。當(dāng)讀取文件時(shí),會(huì)驗(yàn)證檢驗(yàn)和星澳,如果出現(xiàn)錯(cuò)誤疚顷,LocalFileSystem拋出ChecksumException異常。

計(jì)算校驗(yàn)和的代價(jià)很小(JAVA中禁偎,使用native代碼計(jì)算)腿堤,不會(huì)對(duì)讀取或?qū)懭胛募斐墒裁从绊憽?duì)于大多數(shù)應(yīng)用來(lái)說(shuō)届垫,為了保證數(shù)據(jù)的完整性這是完全可以承受的代價(jià)释液。然而,如果底層的文件系統(tǒng)本身支持校驗(yàn)装处,就可以關(guān)閉LocalFileSystem的校驗(yàn)误债。此時(shí)可以使用RawLocalFileSysem代替LocalFileSystem浸船。要想在應(yīng)用的全局范圍內(nèi)關(guān)閉校驗(yàn)和,可以將屬性fs.file.impl的值設(shè)置為org.apache.hadoop.fs.RawLocalFileSystem寝蹈。如果你僅僅想對(duì)某一些讀取操作關(guān)閉檢驗(yàn)和驗(yàn)證時(shí)李命,也可以直接創(chuàng)建一個(gè)RawLocalFileSystem實(shí)例。例如:

Configuration conf = ...
FileSystem fs = new RawLocalFileSystem();
fs.initialize(null, conf);

ChecksumFileSystem

LocalFileSystem使用CheckFileSystem來(lái)實(shí)現(xiàn)校驗(yàn)和的功能箫老。這個(gè)類(lèi)可以很方便地在其它沒(méi)有校驗(yàn)和功能的文件系統(tǒng)中加入校驗(yàn)和功能封字。ChecksumFileSystem僅僅是FileSystem的一個(gè)封裝類(lèi)。一般的寫(xiě)法如下:

FileSystem rawFs = ...
FileSystem checksummedFs = new ChecksumFileSystem(rawFs);

底層的文件系統(tǒng)叫做原生文件系統(tǒng)耍鬓,可以通過(guò)ChecksumFileSystem的getRawFileSystem方法獲得阔籽。ChecksumFileSystem還有一些和校驗(yàn)和相關(guān)的有用的方法,例如getChecksumFile()方法用于獲取任意文件的校驗(yàn)和文件的路徑牲蜀“手疲可以查看相關(guān)參考資料看看其它的方法。

如果在讀取文件的過(guò)程中涣达,ChecksumFileSystem檢測(cè)到一個(gè)錯(cuò)誤在辆。它將會(huì)調(diào)用它的reportChecksumFailure()方法。這個(gè)方法默認(rèn)的實(shí)現(xiàn)沒(méi)有做任何事情度苔。但是LocalFileSystem將檢驗(yàn)失敗的文件和它的校驗(yàn)和單獨(dú)移到同一設(shè)備中叫做"bad_files"的目錄中匆篓。管理員應(yīng)該定期地檢查這個(gè)目錄中是否有壞的文件并處理。

壓縮

文件壓縮有兩個(gè)主要的好處:減少存儲(chǔ)文件所需的空間;加快數(shù)據(jù)在網(wǎng)絡(luò)傳輸?shù)乃俾屎蛷挠脖P(pán)讀寫(xiě)文件的速度寇窑。當(dāng)處理海量數(shù)據(jù)時(shí)鸦概,這些好處帶來(lái)的效果是很可觀的,所以它值得我們仔細(xì)考慮如何在Hadoop使用壓縮疗认。

有多種不同的壓縮格式完残,工具和算法。每一種都有不同的特性横漏。表5-1例舉出了Hadoop常用的一些壓縮工具/格式。

壓縮格式 工具 算法 文件擴(kuò)展名 可切片?
DEFLATE[1] N/A DEFLATE .deflate No
gzip gzip DEFLATE .gz No
bzip2 bzip2 bzip2 .bz2 Yes
LZO lzop LZO .lzo No[2]
LZ4 N/A LZ4 .lz4 No
Snappy N/A Snappy .snappy No

所有的壓縮算法都會(huì)在空間與時(shí)間兩方面進(jìn)行權(quán)衡:更快地壓縮與解壓縮算法通常以節(jié)約更小的空間為代價(jià)熟掂。表5-1所列的壓縮工具一般都會(huì)提供9個(gè)不同的選擇來(lái)在空間與時(shí)間上進(jìn)行權(quán)衡缎浇。-1意思是優(yōu)化速度,-9意思是優(yōu)化空間赴肚。例如下面的命令以最快的壓縮速度創(chuàng)建了一個(gè)叫做file.gz的壓縮文件素跺。

% gzip -1 file

不同的壓縮工具有著非常不同的壓縮特性。通常選擇gzip壓縮格式誉券,所有壓縮工具中指厌,gzip在空間與時(shí)間權(quán)衡方面性能居中。bzip2比gzip有更高的壓縮率踊跟,但是更慢踩验。bzip2的解壓速度比它的壓縮速度快,但是還是比其它壓縮格式要慢。另一方面箕憾,LZO牡借、LZ4和Snappy都優(yōu)化了速度,在速度上按照順序依次更快袭异,且都比gzip快很多钠龙。但是壓縮率不如gzip高。Snappy和LZ4比LZO的解壓速度要快很多[3]御铃。

表5-1的"可切片"一列表示壓縮格式是否支持切片(也就是說(shuō)你可以定位到數(shù)據(jù)流的任意一點(diǎn)碴里,并從這一點(diǎn)開(kāi)始讀取數(shù)據(jù))∩险妫可切片的壓縮格式特別適合MapReduce并闲。可以看稍后的"壓縮與切片"小節(jié)進(jìn)一步討論谷羞。

編解碼器

編解碼器是壓縮-解壓算法的實(shí)現(xiàn)帝火。Hadoop中,一個(gè)編解碼器是CompressionCodec接口的一個(gè)實(shí)現(xiàn)類(lèi)湃缎。例如:GzipCodec封裝了gzip的壓縮與解壓算法犀填。表5-2列舉出了Hadoop中的編解碼器。

壓縮格式 Hadoop CompressCodec
DEFLATE org.apache.hadoop.io.compress.DefaultCodec
gzip org.apache.hadoop.io.compress.GzipCodec
bzip2 org.apache.hadoop.io.compress.BZip2Codec
LZO com.hadoop.compression.lzo.LzopCodec
LZ4 org.apache.hadoop.io.compress.Lz4Codec
Snappy org.apache.hadoop.io.compress.SnappyCodec

LZO庫(kù)是遵循GPL協(xié)議的嗓违,所以在Apache發(fā)布的Hadoop中也許沒(méi)有包含九巡,所以需要單獨(dú)從Google(或GitHub,包含bug修復(fù)和更多工具)下載。
LzopCodec是一個(gè)兼容lzop工具的實(shí)現(xiàn)類(lèi)蹂季,本質(zhì)上冕广,是帶有額外頭文件的LZO壓縮工具類(lèi)。也有一個(gè)純LZO壓縮格式的實(shí)現(xiàn)類(lèi)叫做LzoCodec,它使用的是.lzo_deflate文件擴(kuò)展名(就如同DEFLATE偿洁,是一個(gè)沒(méi)有頭文件的gzip)撒汉。

使用CompressionCodec壓縮與解壓流
CompressionCodec有兩個(gè)方法,可以讓你很容易的壓縮或解壓數(shù)據(jù)涕滋。為了在寫(xiě)入輸出流時(shí)壓縮數(shù)據(jù)睬辐,你可以使用createOutputStream(OutputStream out)方法創(chuàng)建一個(gè)CompressionOutputStream輸出流,然后你將未壓縮的數(shù)據(jù)寫(xiě)入宾肺,CompressionOutputStream就可以讓數(shù)據(jù)以壓縮的形式寫(xiě)入底層輸出流中溯饵。相應(yīng)地,要想從一個(gè)輸入流中解壓數(shù)據(jù)锨用,調(diào)用createInputStream(InpuStream in)方法獲取一個(gè)CompressionInputStream對(duì)象丰刊,這個(gè)對(duì)象可以讓你從底層流的壓縮數(shù)據(jù)中讀取出解壓后的數(shù)據(jù)。

CompressionOutputStream和CompressionInputStream與java.util.zip.DeflaterOutputStream和java.util.zip.DeflaterInputStream相似增拥。不過(guò)啄巧,前兩者比后兩者多個(gè)功能寻歧,可以重置底層的壓縮或解壓器。這對(duì)于想分塊壓縮數(shù)據(jù)的應(yīng)用來(lái)說(shuō)是很重要的棵帽。例如本章后面將講解的SequenceFile熄求。

示例5-1展示了如何將從標(biāo)準(zhǔn)輸入流讀取的數(shù)據(jù)壓縮,然后寫(xiě)入標(biāo)準(zhǔn)輸出流中逗概。

示例5-1:壓縮讀取的數(shù)據(jù)并寫(xiě)入標(biāo)準(zhǔn)輸出流的程序
public class StreamCompressor {
   public static void main(String[] args) throws Exception {
      String codecClassname = args[0];
     Class<?> codecClass = Class.forName(codecClassname);
     Configuration conf = new Configuration();
     CompressionCodec codec = (CompressionCodec)
    ReflectionUtils.newInstance(codecClass, conf);
    CompressionOutputStream out =      codec.createOutputStream(System.out);
    IOUtils.copyBytes(System.in, out, 4096, false);
    out.finish();
  }
}

這個(gè)應(yīng)用需要一個(gè) CompressionCodec實(shí)現(xiàn)類(lèi)的全類(lèi)名做為命令行第一個(gè)參數(shù)弟晚。我們使用ReflectionUtils創(chuàng)建一個(gè)編碼類(lèi)的實(shí)例,然后獲取一個(gè)System.out的壓縮封裝類(lèi)逾苫,然后我們調(diào)用IOUtils的copyBytes方法將輸入流中的數(shù)據(jù)復(fù)制到輸出流中卿城。在輸出之前,數(shù)據(jù)會(huì)經(jīng)過(guò) CompressionOutputStream壓縮铅搓。最后調(diào)用 CompressionOutputStream的finish方法告訴壓縮器停止向輸出流中寫(xiě)入壓縮的數(shù)據(jù)瑟押,但不關(guān)閉輸出流。我們可以用下面的命令進(jìn)行嘗試星掰,壓縮"Text"字符串多望,調(diào)用StreamCompressor類(lèi),傳入 GzipCodec壓縮器氢烘,然后用gunzip進(jìn)行解壓怀偷。

% echo "Text" | hadoop StreamCompressor org.apache.hadoop.io.compress.GzipCodec \
| gunzip -
Text

使用CompressionCodecFactory推斷出壓縮編碼
如果你需要讀取一個(gè)壓縮文件,正常情況下你會(huì)觀察壓縮文件的擴(kuò)展名來(lái)推斷出所使用的壓縮編碼播玖,.gz結(jié)尾的文件可以使用 GzipCodec讀取等等椎工。每一種壓縮編碼的擴(kuò)展名都在表5-1中列舉。CompressionCodecFactory通過(guò)它的getCodec()方法提供了一種通過(guò)擴(kuò)展名得到相應(yīng)壓縮編碼的方法蜀踏。示例5-2顯示了如何使用這種方法解壓文件维蒙。

示例:5-2 從文件擴(kuò)展名推斷出解壓縮編碼來(lái)對(duì)文件進(jìn)行解壓的程序
public class FileDecompressor {
public static void main(String[] args) throws Exception {
  String uri = args[0];
  Configuration conf = new Configuration();
  FileSystem fs = FileSystem.get(URI.create(uri), conf);
  Path inputPath = new Path(uri);
  CompressionCodecFactory factory = new CompressionCodecFactory(conf);
  CompressionCodec codec = factory.getCodec(inputPath);
  if (codec == null) {
   System.err.println("No codec found for " + uri);
  System.exit(1);
  }
  String outputUri =
  CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());
  InputStream in = null;
  OutputStream out = null;
  try {
   in = codec.createInputStream(fs.open(inputPath));
   out = fs.create(new Path(outputUri));
   IOUtils.copyBytes(in, out, conf);
  } finally {
    IOUtils.closeStream(in);
    IOUtils.closeStream(out);
    }
  }
}

一旦推斷出了編碼,就會(huì)使用 CompressionCodecFactory的 removeSuffix() 靜態(tài)方法去掉文件的后綴得到輸出文件名果覆。通過(guò)這種方法颅痊,使用如下命令,一個(gè)叫做file.gz的文件會(huì)被解壓成file随静。

% hadoop FileDecompressor file.gz

CompressionCodecFactory會(huì)加載表5-2中除了LZO之外的所有編碼八千,和表5-3中屬性 io.compression.codecs所列舉的所有編碼,默認(rèn)情況下燎猛,這個(gè)屬性值為空,如果你希望注冊(cè)一個(gè)自定義的編碼(例如這個(gè)外部的LZO編碼)照皆,你就需要修改這個(gè)屬性重绷。每一種編碼都知道它自己的默認(rèn)文件擴(kuò)展名,因此CompressionCodecFactory就可以通過(guò)搜索所有注冊(cè)的編碼找到與給定文件名匹配的編碼膜毁。

表5-3:壓縮編碼配置屬性

屬性名 類(lèi)型 默認(rèn)值 描述
io.compression.codecs 逗號(hào)分隔的類(lèi)名 外部的 CompressionCodec壓縮與解壓縮類(lèi)列表

本地庫(kù)
從性能考慮昭卓,推薦使用本地庫(kù)來(lái)進(jìn)行壓縮與解壓縮愤钾。例如一項(xiàng)測(cè)試表明,使用本地庫(kù)中的gzip比使用java內(nèi)建的gzip實(shí)現(xiàn)至多減少50%解壓縮時(shí)間和大約10%的壓縮時(shí)間候醒。表5-4顯示了對(duì)于所有壓縮格式能颁,java與本地庫(kù)是否提供了實(shí)現(xiàn)。所有的格式都有本地實(shí)現(xiàn)倒淫,但并不是都有java實(shí)現(xiàn)伙菊,例如LZO壓縮格式。

表5-4:壓縮庫(kù)實(shí)現(xiàn)

壓縮格式 java實(shí)現(xiàn) 本地庫(kù)實(shí)現(xiàn)
DEFLATE Yes Yes
gzip Yes Yes
bzip2 Yes Yes
LZO No Yes
LZ4 No Yes
Snappy No Yes

Apache Hadoop的二進(jìn)制tar包帶有預(yù)建的針對(duì)64位Linux系統(tǒng)的壓縮編碼本地庫(kù)實(shí)現(xiàn)敌土,叫做 libhadoop.so镜硕。對(duì)于其它平臺(tái),你需要按照Hadoop源碼頂級(jí)目錄中BUILDING.txt文件說(shuō)明的那樣編譯自己的庫(kù)文件返干。

通過(guò)設(shè)置java系統(tǒng)屬性 java.library.path可以找到本地庫(kù)兴枯,可以在hadoop的etc/hadoop目錄中進(jìn)行設(shè)置。如果你不想在hadoop配置文件中設(shè)置矩欠,你就需要在應(yīng)用程序中設(shè)置财剖。

默認(rèn)情況下,Hadoop會(huì)自動(dòng)尋找與它運(yùn)行平臺(tái)相對(duì)應(yīng)的本地庫(kù)癌淮,如果發(fā)現(xiàn)了躺坟,就會(huì)自動(dòng)加載。這就意味著你不需要為了使用本地庫(kù)而做任何配置该默。然后瞳氓,在某些情況下,你希望不使用本地庫(kù)栓袖,例如你想調(diào)度一個(gè)壓縮相關(guān)的問(wèn)題時(shí)。你可以通過(guò)將屬性io.native.lib.available設(shè)置成false來(lái)不使用本地庫(kù)裹刮,而使用Java內(nèi)建的編碼(如果可以找得到的話(huà))捧弃。

編碼池
如果你正在使用本地庫(kù)赠叼,而且在你的應(yīng)用程序中需要做大量的壓縮與解壓縮工作,可以考慮使用編碼池(CodecPool)违霞。編碼池可以讓你重用解壓縮對(duì)象,而省去了創(chuàng)建這些對(duì)象的開(kāi)銷(xiāo)涧郊。

示例5-3中的代碼顯示了編碼池的應(yīng)用。雖然本例實(shí)際上只需要?jiǎng)?chuàng)建一個(gè)解壓縮對(duì)象眼五,沒(méi)有必要使用編碼池妆艘。

示例5-3:從標(biāo)準(zhǔn)輸入中讀取數(shù)據(jù)彤灶,使用編碼池壓縮器將數(shù)據(jù)寫(xiě)入標(biāo)準(zhǔn)輸出中
public class PooledStreamCompressor {
  public static void main(String[] args) throws Exception {
    String codecClassname = args[0];
   Class<?> codecClass = Class.forName(codecClassname);
   Configuration conf = new Configuration();
  CompressionCodec codec = (CompressionCodec)
   ReflectionUtils.newInstance(codecClass, conf);
   Compressor compressor = null;
   try {
    compressor = CodecPool.getCompressor(codec);
    CompressionOutputStream out =
      codec.createOutputStream(System.out, compressor);
      IOUtils.copyBytes(System.in, out, 4096, false);
     out.finish();
  } finally {
     CodecPool.returnCompressor(compressor);
  }
}
}

對(duì)于給定的 CompressionCodec幌陕,我們可以從編碼池中獲取壓縮實(shí)例汽煮。然后在CompressionCodec的 createOutputStream() 方法中使用這個(gè)壓縮實(shí)例。通過(guò)使用finally塊搬卒,我們就可以確保翎卓,這個(gè)壓縮實(shí)例在使用完以后能夠回到編碼池中,即使在從標(biāo)準(zhǔn)輸入流復(fù)制數(shù)據(jù)到標(biāo)準(zhǔn)輸出流中時(shí)坯门,出現(xiàn)了IOException異常逗扒。

未完待續(xù).........


  1. DEFLATE壓縮算法標(biāo)準(zhǔn)實(shí)現(xiàn)是zlib.但是沒(méi)有生成DEFLATE格式的通用命令行工具。通常使用gzip工具(gzip使用DEFLATE壓縮算法现恼,不過(guò)增加了額外的頭和尾)黍檩。.deflate格式的擴(kuò)展文件是Hadoop使用的。 ?

  2. 如果在預(yù)處理過(guò)程中喳逛,已經(jīng)創(chuàng)建了索引棵里,LZO壓縮的文件可以切片,見(jiàn)后面的壓縮的切片小節(jié)介紹典蝌。 ?

  3. 想了解更多綜合性壓縮標(biāo)準(zhǔn)头谜,可以參看jvm壓縮標(biāo)準(zhǔn)了解JVM兼容的一些庫(kù)(包庫(kù)一些native庫(kù)) ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末乔夯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子侧纯,更是在濱河造成了極大的恐慌甲脏,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娜氏,死亡現(xiàn)場(chǎng)離奇詭異墩新,居然都是意外死亡海渊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)盔憨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)讯沈,“玉大人,你說(shuō)我怎么就攤上這事问慎∪謇希” “怎么了驮樊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)挖腰。 經(jīng)常有香客問(wèn)我练湿,道長(zhǎng),這世上最難降的妖魔是什么辽俗? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任崖飘,我火速辦了婚禮,結(jié)果婚禮上朱浴,老公的妹妹穿的比我還像新娘翰蠢。我一直安慰自己,他們只是感情好梁沧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布趁尼。 她就那樣靜靜地躺著,像睡著了一般砚殿。 火紅的嫁衣襯著肌膚如雪芝囤。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天羡藐,我揣著相機(jī)與錄音仆嗦,去河邊找鬼先壕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛集绰,可吹牛的內(nèi)容都是我干的谆棺。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼碍岔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了兰珍?” 一聲冷哼從身側(cè)響起询吴,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤猛计,失蹤者是張志新(化名)和其女友劉穎爆捞,沒(méi)想到半個(gè)月后煮甥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卖局,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年双霍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洒闸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡单鹿,死狀恐怖深纲,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昼窗,我是刑警寧澤涛舍,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站掸驱,受9級(jí)特大地震影響毕贼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鬼癣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一待秃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧枉氮,春花似錦暖庄、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蔬将。三九已至,卻和暖如春霞怀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背廉沮。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工滞时, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留滤灯,地道東北人曼玩。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓黍判,卻偏偏與公主長(zhǎng)得像篙梢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贬墩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 當(dāng)數(shù)據(jù)量增大到超出了單個(gè)物理計(jì)算機(jī)存儲(chǔ)容量時(shí)震糖,有必要把它分開(kāi)存儲(chǔ)在多個(gè)不同的計(jì)算機(jī)中趴腋。那些管理存儲(chǔ)在多個(gè)網(wǎng)絡(luò)互連的...
    單行線(xiàn)的旋律閱讀 1,907評(píng)論 0 7
  • 思考問(wèn)題 HDFS的IO操作總結(jié) Hadoop工程下與I/O相關(guān)的包如下: org.apache.hadoop.i...
    Sakura_P閱讀 444評(píng)論 0 2
  • 數(shù)據(jù)流 讀取文件數(shù)據(jù)的剖析 客戶(hù)端通過(guò)調(diào)用FileSystem對(duì)象的open()方法打開(kāi)一個(gè)希望從中讀取數(shù)據(jù)的文件...
    單行線(xiàn)的旋律閱讀 241評(píng)論 0 2
  • hadoop是什么?HDFS與MapReduceHive:數(shù)據(jù)倉(cāng)庫(kù)厅贪,在HDFS之上,后臺(tái)執(zhí)行葵硕,幫你執(zhí)行贯吓。faceb...
    Babus閱讀 2,362評(píng)論 0 5
  • 我不知道 將來(lái)的路會(huì)怎樣 是一條條陽(yáng)關(guān)大道 還是一條條獨(dú)木橋 是晴空萬(wàn)里 還是烏云密布 一分耕耘一分收獲 可是我害...
    簡(jiǎn)珞珞閱讀 185評(píng)論 1 1