hadoop 小文件處理方案

hadoop hdfs 被設計用作海量數(shù)據(jù)存儲,適合存儲大文件,文件在hdfs中是以block的形式存儲的,在hadoop 1.x中秦效,hdfs block的默認大小為64m,而在hadoop 2.x中涎嚼,block的默認大小為128m阱州,可以在hdfs-site.xml文件中的dfs.block.size配置項修改默認的塊大小。文件由一個或多個block組成法梯,文件的元數(shù)據(jù)信息由namenode記錄苔货,因此如果hdfs存儲大量的小文件時,會占用大量的block以及namenode必須耗費大量內(nèi)存來記錄這些文件的元數(shù)據(jù),造成存儲空間浪費以及影響hdfs 集群的橫向擴展蒲赂。因此以下兩種方案可以用來處理hdfs 小文件的問題:
1.sequencefile
2.hadoop archives file

SequenceFile

sequencefile 由header和一個個記錄組成,header記錄著keyclass 類型刁憋,valueclass 類型滥嘴,壓縮信息以及用戶自定義的信息,記錄record存儲的是真正的數(shù)據(jù)并以key-value的格式進行存儲至耻,sequencefile文件按壓縮可分為無壓縮格式若皱,記錄壓縮格式和塊壓縮格式。無壓縮格式和記錄壓縮格式相似尘颓,唯一的區(qū)別是記錄壓縮格式是值壓縮走触,格式如下圖所示:


image.png

而塊壓縮是對record進行壓縮,一個塊由多個record組成疤苹,當一個record的大小達到io.seqfile.compress.blockseze 默認1000000字節(jié)時互广,可加入到塊中,格式如圖所示:


image.png

示例代碼

package com.zjc.spark;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.compress.DefaultCodec;
import org.apache.hadoop.util.LineReader;

import java.io.File;
import java.io.FileInputStream;

/**
 * Created by zjc on 2018/11/14.
 */

public class sparkApplication1 {

    static Configuration configuration = null;

    static {
        configuration = new Configuration();
        configuration.set("fs.defaultFS", "hdfs://z-cluster");
        configuration.set("dfs.nameservices", "z-cluster");
        configuration.set("dfs.ha.namenodes.z-cluster", "nn1,nn2");
        configuration.set("dfs.namenode.rpc-address.z-cluster.nn1", "192.168.1.22:8120");
        configuration.set("dfs.namenode.rpc-address.z-cluster.nn2", "192.168.1.107:8120");
        configuration.set("dfs.client.failover.proxy.provider.z-cluster", "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider");
        configuration.set("hadoop.user.name", "hadoop4.27");
    }

    public static void main6(String[] args) {
        IntWritable key = new IntWritable();
        Text value = new Text();
        SequenceFile.Writer out = null;
        try {
            FileSystem fileSystem = FileSystem.get(configuration);
            out = SequenceFile.createWriter(configuration, SequenceFile.Writer.file(new Path("/testFile")), SequenceFile.Writer.keyClass(IntWritable.class), SequenceFile.Writer.valueClass(Text.class), SequenceFile.Writer.compression(SequenceFile.CompressionType.BLOCK, new DefaultCodec()));
            for (int i = 0; i < 100; i++) {
                key.set(100 - i);
                value.set(DATA[i % DATA.length]);
                out.append(key, value);
                if (i % 20 == 0) {
                    out.sync();//每四百條記錄添加一個同步點
                }

            }

        } catch (Exception e) {
            System.out.println(e);
        } finally {
            IOUtils.closeStream(out);
        }
    }

 
    public static void main18(String[] args) {
        IntWritable key = new IntWritable();
        Text value = new Text();
        SequenceFile.Reader in = null;
        try {
            in = new SequenceFile.Reader(configuration, SequenceFile.Reader.file(new Path("/testFile")));
            // in.sync(2129);
            long position = in.getPosition();
            while (in.next(key, value)) {
                System.out.println("position:" + position + "  key:" + key.get() + "  value:" + value.toString());
                position = in.getPosition();
            }
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            IOUtils.closeStream(in);
        }
    }


}

可通過mr將多個小文件合并成一個sequencefile文件卧土,但是sequencefile的缺點是不支持追加惫皱。

Hadoop Archives File

可通過hdfs shell命令將多個小文件創(chuàng)建為歸檔文件,歸檔示例:

創(chuàng)建歸檔文件
hadoop archive -archiveName foo.har -p /user/hadoop -r 3 dir1 dir2 /user/zoo
上面的例子使用 /user/hadoop 作為創(chuàng)建歸檔的相對歸檔目錄尤莺。/user/hadoop/dir1 和 /user/hadoop/dir2 目錄將會歸檔到 /user/zoo/foo.har 里面旅敷。歸檔操作并不會刪除輸入文件。如果你想在創(chuàng)建歸檔文件之后刪除這些輸入文件颤霎,你需要自己做媳谁。在這個例子中,因為我們指定了 -r 3友酱,那么副本因子為3將會被使用晴音。

查找文件
在 hadoop 檔案中查找文件就像在文件系統(tǒng)上執(zhí)行 ls 一樣簡單。在我們歸檔完 /user/hadoop/dir1 和 /user/hadoop/dir2 目錄粹污,如果我們想查看歸檔里面有哪些文件段多,你僅僅需要使用下面命令:

hdfs dfs -ls -R har:///user/zoo/foo.har/
要理解-p 參數(shù)的重要性,讓我們再看一遍上面的例子壮吩。 如果您只是在 hadoop 存檔上使用 ls(而不是lsr)

hdfs dfs -ls har:///user/zoo/foo.har
輸出如下:

har:///user/zoo/foo.har/dir1
har:///user/zoo/foo.har/dir2
您可以回憶一下使用以下命令創(chuàng)建存檔

hadoop archive -archiveName foo.har -p /user/hadoop dir1 dir2 /user/zoo
如果我們將上面命令修改為下:

hadoop archive -archiveName foo.har -p /user/ hadoop/dir1 hadoop/dir2 /user/zoo
那么在 Hadoop 歸檔上如下使用 ls 命令:

hdfs dfs -ls har:///user/zoo/foo.har
那么你會得到如下結果:

har:///user/zoo/foo.har/hadoop/dir1
har:///user/zoo/foo.har/hadoop/dir2
請注意进苍,已歸檔文件已相對于 /user/ 而不是/ user/hadoop 進行歸檔。

Hadoop Archives 和 MapReduce
在 MapReduce 中使用 Hadoop Archives 就像使用默認文件系統(tǒng)中的文件一樣簡單鸭叙。 如果我們在 HDFS 上的 /user/zoo/foo.har 路徑里面存儲了 Hadoop 歸檔文件觉啊,那么在 MapReduce 里面將它作為輸入文件可以使用 har:///user/zoo/foo.har。

Hadoop Archives 是根據(jù)索引文件對目標文件進行讀取沈贝,所以讀性能比正常讀取低下杠人。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嗡善,更是在濱河造成了極大的恐慌辑莫,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罩引,死亡現(xiàn)場離奇詭異各吨,居然都是意外死亡,警方通過查閱死者的電腦和手機袁铐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進店門揭蜒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人剔桨,你說我怎么就攤上這事屉更。” “怎么了洒缀?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵瑰谜,是天一觀的道長。 經(jīng)常有香客問我帝洪,道長似舵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任葱峡,我火速辦了婚禮砚哗,結果婚禮上,老公的妹妹穿的比我還像新娘砰奕。我一直安慰自己蛛芥,他們只是感情好,可當我...
    茶點故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布军援。 她就那樣靜靜地躺著仅淑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胸哥。 梳的紋絲不亂的頭發(fā)上涯竟,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天,我揣著相機與錄音空厌,去河邊找鬼庐船。 笑死,一個胖子當著我的面吹牛嘲更,可吹牛的內(nèi)容都是我干的筐钟。 我是一名探鬼主播,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼赋朦,長吁一口氣:“原來是場噩夢啊……” “哼篓冲!你這毒婦竟也來了李破?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤壹将,失蹤者是張志新(化名)和其女友劉穎嗤攻,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诽俯,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡屯曹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了惊畏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,683評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡密任,死狀恐怖颜启,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情浪讳,我是刑警寧澤缰盏,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站淹遵,受9級特大地震影響口猜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜透揣,卻給世界環(huán)境...
    茶點故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一济炎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辐真,春花似錦须尚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至楔脯,卻和暖如春撩轰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昧廷。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工堪嫂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人麸粮。 一個月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓溉苛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親弄诲。 傳聞我的和親對象是個殘疾皇子愚战,可洞房花燭夜當晚...
    茶點故事閱讀 43,566評論 2 349

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