1. 程式人生 > >IDEA下調試和運行Hadoop程序例子

IDEA下調試和運行Hadoop程序例子

看不見 菜單欄 ear filename 楓葉 ref 技術分享 true java

準備

配置好JDK和Hadoop環境,

在IDEA中建立maven項目,建立後的目錄結構為:

技術分享圖片

修改pom..xml引入相關支持:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
> <modelVersion>4.0.0</modelVersion> <groupId>com.xuan</groupId> <artifactId>hadoopdemo</artifactId> <version>1.0-SNAPSHOT</version> <name>hadoopdemo</name> <!-- FIXME change it to the project‘s website -->
<url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target>
</properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.5.2</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.5.2</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.5.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </project>

一,測試字母統計

創建測試類WordCount.java:

public class WordCount {
    public static class TokenizerMapper
            extends Mapper<Object, Text, Text, IntWritable> {

        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();

        @Override
        public void map(Object key, Text value, Context context
        ) throws IOException, InterruptedException {
            StringTokenizer itr = new StringTokenizer(value.toString());
            while (itr.hasMoreTokens()) {
                word.set(itr.nextToken());
                context.write(word, one);
            }
        }
    }

    public static class IntSumReducer
            extends Reducer<Text, IntWritable, Text, IntWritable> {
        private IntWritable result = new IntWritable();

        @Override
        public void reduce(Text key, Iterable<IntWritable> values,
                           Context context
        ) throws IOException, InterruptedException {
            int sum = 0;
            for (IntWritable val : values) {
                sum += val.get();
            }
            result.set(sum);
            context.write(key, result);
        }
    }

    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "word count");
        job.setJarByClass(WordCount.class);
        job.setMapperClass(TokenizerMapper.class);
        job.setCombinerClass(IntSumReducer.class);
        job.setReducerClass(IntSumReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

配置輸入和輸出結果文件夾:

添加和src目錄同級的input文件夾到項目中

在input文件夾中放置一個或多個輸入文件源,比如file1.txt;file2.txt

file1.txt內容為:

q
w
ww
q
we
qwe
as
q
w
ww
q
w
we

file2.txt內容也類似的隨意輸入。

配置運行參數

在Intellij菜單欄中選擇Run->Edit Configurations,在彈出來的對話框中點擊+,新建一個Application配置。配置Main class為WordCount(可以點擊右邊的...選擇),

Program arguments為input/ output/,即輸入路徑為剛才創建的input文件夾,輸出為output

技術分享圖片

由於Hadoop的設定,下次運行時務必刪除output文件夾

運行程序,結果生成out目錄,裏面有執行結果文件“part-r-00000”,其內容:

技術分享圖片

二。在多條數據中查找包含某個字符串的語句。

創建Search.java統計類

public class Search {
    public static class Map extends Mapper<Object, Text, Text, Text> {
        private static final String word = "月";
        private FileSplit fileSplit;

        @Override
        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            fileSplit = (FileSplit) context.getInputSplit();
            String fileName = fileSplit.getPath().getName().toString();
            //按句號分割
            StringTokenizer st = new StringTokenizer(value.toString(), "。");
            while (st.hasMoreTokens()) {
                String line = st.nextToken().toString();
                if (line.indexOf(word) >= 0) {
                    context.write(new Text(fileName), new Text(line));
                }
            }
        }
    }

    public static class Reduce extends Reducer<Text, Text, Text, Text> {
        @Override
        public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            String lines = "";
            for (Text value : values) {
                lines += value.toString() + "---|---";
            }
            context.write(key, new Text(lines));
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        String[] otherArgs = {"input/", "output/"};
        //配置作業名
        Job job = Job.getInstance(conf, "search");
        //配置作業各個類
        job.setJarByClass(Search.class);
        job.setMapperClass(Map.class);
        job.setReducerClass(Reduce.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

此例子中的運行目錄是直接在代碼中寫的

修改file1.txt和file2.txt的內容:

潯陽江頭夜送客,楓葉荻花秋瑟瑟。主人下馬客在船,舉酒欲飲無管弦。醉不成歡慘將別,別時茫茫江浸月。忽聞水上琵琶聲,主人忘歸客不發。尋聲暗問彈者誰?琵琶聲停欲語遲。移船相近邀相見,添酒回燈重開宴。千呼萬喚始出來,猶抱琵琶半遮面。轉軸撥弦三兩聲,未成曲調先有情。弦弦掩抑聲聲思,似訴平生不得誌。低眉信手續續彈,說盡心中無限事。輕攏慢撚抹復挑,初為霓裳後六幺。大弦嘈嘈如急雨,小弦切切如私語。嘈嘈切切錯雜彈,大珠小珠落玉盤。間關鶯語花底滑,幽咽泉流冰下難。冰泉冷澀弦凝絕,凝絕不通聲暫歇。別有幽愁暗恨生,此時無聲勝有聲。銀瓶乍破水漿迸,鐵騎突出刀槍鳴。曲終收撥當心畫,四弦一聲如裂帛。東船西舫悄無言,唯見江心秋月白。
沈吟放撥插弦中,整頓衣裳起斂容。自言本是京城女,家在蝦蟆陵下住。十三學得琵琶成,名屬教坊第一部。曲罷曾教善才服,妝成每被秋娘妒。五陵年少爭纏頭,一曲紅綃不知數。鈿頭銀篦擊節碎,血色羅裙翻酒汙。今年歡笑復明年,秋月春風等閑度。弟走從軍阿姨死,暮去朝來顏色故。門前冷落鞍馬稀,老大嫁作商人婦。商人重利輕別離,前月浮梁買茶去。去來江口守空船,繞船月明江水寒。夜深忽夢少年事,夢啼妝淚紅闌幹。
我聞琵琶已嘆息,又聞此語重唧唧。同是天涯淪落人,相逢何必曾相識!我從去年辭帝京,謫居臥病潯陽城。潯陽地僻無音樂,終歲不聞絲竹聲。住近湓江地低濕,黃蘆苦竹繞宅生。其間旦暮聞何物?杜鵑啼血猿哀鳴。春江花朝秋月夜,往往取酒還獨傾。豈無山歌與村笛?嘔啞嘲哳難為聽。今夜聞君琵琶語,如聽仙樂耳暫明。莫辭更坐彈一曲,為君翻作《琵琶行》。感我此言良久立,卻坐促弦弦轉急。淒淒不似向前聲,滿座重聞皆掩泣。座中泣下誰最多?江州司馬青衫濕。
漢皇重色思傾國,禦宇多年求不得。
楊家有女初長成,養在深閨人未識。
天生麗質難自棄,一朝選在君王側。
回眸一笑百媚生,六宮粉黛無顏色。
春寒賜浴華清池,溫泉水滑洗凝脂。
侍兒扶起嬌無力,始是新承恩澤時。
雲鬢花顏金步搖,芙蓉帳暖度春宵。
春宵苦短日高起,從此君王不早朝。
承歡侍宴無閑暇,春從春遊夜專夜。
後宮佳麗三千人,三千寵愛在一身。
金屋妝成嬌侍夜,玉樓宴罷醉和春。
姊妹弟兄皆列土,可憐光彩生門戶。
遂令天下父母心,不重生男重生女。
驪宮高處入青雲,仙樂風飄處處聞。
緩歌謾舞凝絲竹,盡日君王看不足。
漁陽鼙鼓動地來,驚破霓裳羽衣曲。
九重城闕煙塵生,千乘萬騎西南行。
翠華搖搖行復止,西出都門百余裏。
六軍不發無奈何,宛轉蛾眉馬前死。
花鈿委地無人收,翠翹金雀玉搔頭。
君王掩面救不得,回看血淚相和流。
黃埃散漫風蕭索,雲棧縈紆登劍閣。
峨嵋山下少人行,旌旗無光日色薄。
蜀江水碧蜀山青,聖主朝朝暮暮情。
行宮見月傷心色,夜雨聞鈴腸斷聲。
天旋地轉回龍馭,到此躊躇不能去。
馬嵬坡下泥土中,不見玉顏空死處。
君臣相顧盡沾衣,東望都門信馬歸。
歸來池苑皆依舊,太液芙蓉未央柳。
芙蓉如面柳如眉,對此如何不淚垂。
春風桃李花開日,秋雨梧桐葉落時。
西宮南內多秋草,落葉滿階紅不掃。
梨園弟子白發新,椒房阿監青娥老。
夕殿螢飛思悄然,孤燈挑盡未成眠。
遲遲鐘鼓初長夜,耿耿星河欲曙天。
鴛鴦瓦冷霜華重,翡翠衾寒誰與共。
悠悠生死別經年,魂魄不曾來入夢。
臨邛道士鴻都客,能以精誠致魂魄。
為感君王輾轉思,遂教方士殷勤覓。
排空馭氣奔如電,升天入地求之遍。
上窮碧落下黃泉,兩處茫茫皆不見。
忽聞海上有仙山,山在虛無縹渺間。
樓閣玲瓏五雲起,其中綽約多仙子。
中有一人字太真,雪膚花貌參差是。
金闕西廂叩玉扃,轉教小玉報雙成。
聞道漢家天子使,九華帳裏夢魂驚。
攬衣推枕起徘徊,珠箔銀屏迤邐開。
雲鬢半偏新睡覺,花冠不整下堂來。
風吹仙袂飄飄舉,猶似霓裳羽衣舞。
玉容寂寞淚闌幹,梨花一枝春帶雨。
含情凝睇謝君王,一別音容兩渺茫。
昭陽殿裏恩愛絕,蓬萊宮中日月長。
回頭下望人寰處,不見長安見塵霧。
惟將舊物表深情,鈿合金釵寄將去。
釵留一股合一扇,釵擘黃金合分鈿。
但教心似金鈿堅,天上人間會相見。
臨別殷勤重寄詞,詞中有誓兩心知。
七月七日長生殿,夜半無人私語時。
在天願作比翼鳥,在地願為連理枝。
天長地久有時盡,此恨綿綿無絕期。

在增加一個文件file3.txt

春江潮水連海平,海上明月共潮生。
灩灩隨波千萬裏,何處春江無月明!
江流宛轉繞芳甸,月照花林皆似霰;
空裏流霜不覺飛,汀上白沙看不見。
江天一色無纖塵,皎皎空中孤月輪。
江畔何人初見月?江月何年初照人?
人生代代無窮已,江月年年只相似。
不知江月待何人,但見長江送流水。
白雲一片去悠悠,青楓浦上不勝愁。
誰家今夜扁舟子?何處相思明月樓?
可憐樓上月徘徊,應照離人妝鏡臺。
玉戶簾中卷不去,搗衣砧上拂還來。
此時相望不相聞,願逐月華流照君。
鴻雁長飛光不度,魚龍潛躍水成文。
昨夜閑潭夢落花,可憐春半不還家。
江水流春去欲盡,江潭落月復西斜。
斜月沈沈藏海霧,碣石瀟湘無限路。
不知乘月幾人歸,落月搖情滿江樹。

運行程序Search.java,結果生成out目錄,裏面有執行結果文件“part-r-00000”,其內容:

file1.txt    春江花朝秋月夜,往往取酒還獨傾---|---去來江口守空船,繞船月明江水寒---|---商人重利輕別離,前月浮梁買茶去---|---今年歡笑復明年,秋月春風等閑度---|---東船西舫悄無言,唯見江心秋月白---|---醉不成歡慘將別,別時茫茫江浸月---|---
file2.txt    七月七日長生殿,夜半無人私語時---|---昭陽殿裏恩愛絕,蓬萊宮中日月長---|---行宮見月傷心色,夜雨聞鈴腸斷聲---|---
file3.txt    不知乘月幾人歸,落月搖情滿江樹---|---斜月沈沈藏海霧,碣石瀟湘無限路---|---江水流春去欲盡,江潭落月復西斜---|---此時相望不相聞,願逐月華流照君---|---可憐樓上月徘徊,應照離人妝鏡臺---|---誰家今夜扁舟子?何處相思明月樓?---|---不知江月待何人,但見長江送流水---|---人生代代無窮已,江月年年只相似---|---江畔何人初見月?江月何年初照人?---|---江天一色無纖塵,皎皎空中孤月輪---|---江流宛轉繞芳甸,月照花林皆似霰;---|---灩灩隨波千萬裏,何處春江無月明!---|---春江潮水連海平,海上明月共潮生---|---

三。Partitioner與自定義Partitioner,生成多個結果文件

參考:https://www.cnblogs.com/edisonchou/p/4297828.html

創建MyKpiJob.java

public class MyKpiJob extends Configured implements Tool {

    /*
     * 自定義數據類型KpiWritable
     */
    public static class KpiWritable implements Writable {

        long upPackNum; // 上行數據包數,單位:個
        long downPackNum; // 下行數據包數,單位:個
        long upPayLoad; // 上行總流量,單位:byte
        long downPayLoad; // 下行總流量,單位:byte

        public KpiWritable() {
        }

        public KpiWritable(String upPack, String downPack, String upPay,
                           String downPay) {
            upPackNum = Long.parseLong(upPack);
            downPackNum = Long.parseLong(downPack);
            upPayLoad = Long.parseLong(upPay);
            downPayLoad = Long.parseLong(downPay);
        }

        @Override
        public String toString() {
            String result = upPackNum + "\t" + downPackNum + "\t" + upPayLoad
                    + "\t" + downPayLoad;
            return result;
        }

        @Override
        public void write(DataOutput out) throws IOException {
            out.writeLong(upPackNum);
            out.writeLong(downPackNum);
            out.writeLong(upPayLoad);
            out.writeLong(downPayLoad);
        }

        @Override
        public void readFields(DataInput in) throws IOException {
            upPackNum = in.readLong();
            downPackNum = in.readLong();
            upPayLoad = in.readLong();
            downPayLoad = in.readLong();
        }

    }

    /*
     * 自定義Mapper類,重寫了map方法
     */
    public static class MyMapper extends
            Mapper<LongWritable, Text, Text, KpiWritable> {
        @Override
        protected void map(
                LongWritable k1,
                Text v1,
                Context context)
                throws IOException, InterruptedException {
            String[] spilted = v1.toString().split("\t");
            String msisdn = spilted[1]; // 獲取手機號碼
            Text k2 = new Text(msisdn); // 轉換為Hadoop數據類型並作為k2
            KpiWritable v2 = new KpiWritable(spilted[6], spilted[7],
                    spilted[8], spilted[9]);
            context.write(k2, v2);
        }

        ;
    }

    /*
     * 自定義Reducer類,重寫了reduce方法
     */
    public static class MyReducer extends
            Reducer<Text, KpiWritable, Text, KpiWritable> {
        @Override
        protected void reduce(
                Text k2,
                Iterable<KpiWritable> v2s,
                Context context)
                throws IOException, InterruptedException {
            long upPackNum = 0L;
            long downPackNum = 0L;
            long upPayLoad = 0L;
            long downPayLoad = 0L;
            for (KpiWritable kpiWritable : v2s) {
                upPackNum += kpiWritable.upPackNum;
                downPackNum += kpiWritable.downPackNum;
                upPayLoad += kpiWritable.upPayLoad;
                downPayLoad += kpiWritable.downPayLoad;
            }

            KpiWritable v3 = new KpiWritable(upPackNum + "", downPackNum + "",
                    upPayLoad + "", downPayLoad + "");
            context.write(k2, v3);
        }
    }

    // 輸入文件目錄
    public static final String INPUT_PATH = "hdfs://hadoop-master:9000/testdir/input/HTTP_20130313143750.dat";
    // 輸出文件目錄
    public static final String OUTPUT_PATH = "hdfs://hadoop-master:9000/testdir/output/mobilelog";

    /*
     * 自定義Partitioner類
     */
    public static class KpiPartitioner extends Partitioner<Text, KpiWritable> {
        //返回值要小於setNumReduceTasks的值
        @Override
        public int getPartition(Text key, KpiWritable value, int numPartitions) {
            // 實現不同的長度不同的號碼分配到不同的reduce task中
            int numLength = key.toString().length();
            if (numLength == 11) {
                return 1;
            } else {
                return 2;
            }
        }
    }

    @Override
    public int run(String[] args) throws Exception {
        String[] otherArgs = {"input/", "output/"};
        //配置作業名
        Job job = Job.getInstance(this.getConf(), "search");

        // 設置自定義Mapper類
        job.setMapperClass(MyMapper.class);
        // 指定<k2,v2>的類型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(KpiWritable.class);
        // 設置自定義Reducer類
        job.setReducerClass(MyReducer.class);
        // 指定<k3,v3>的類型
        job.setOutputKeyClass(Text.class);
        job.setOutputKeyClass(KpiWritable.class);

        // 設置Partitioner
        job.setPartitionerClass(KpiPartitioner.class);
        job.setNumReduceTasks(3);

        // // 設置輸入,輸出目錄
        FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
        // 提交作業
        Boolean res = job.waitForCompletion(true);
        if (res) {
            System.out.println("Process success!");
            System.exit(0);
        } else {
            System.out.println("Process failed!");
            System.exit(1);
        }
        return 0;
    }

    public static void main(String[] args) {
        Configuration conf = new Configuration();
        try {
            int res = ToolRunner.run(conf, new MyKpiJob(), args);
            System.exit(res);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

刪除input文件下面除file1.txt文件的其它文件,修改file1.txt的內容為

1363157985066     13726230503    00-FD-07-A4-72-B8:CMCC    120.196.100.82    i02.c.aliimg.com        24    27    2481    24681    200
1363157995052     13826544101    5C-0E-8B-C7-F1-E0:CMCC    120.197.40.4            4    0    264    0    200
1363157991076     13926435656    20-10-7A-28-CC-0A:CMCC    120.196.100.99            2    4    132    1512    200
1363154400022     13926251106    5C-0E-8B-8B-B1-50:CMCC    120.197.40.4            4    0    240    0    200
1363157993044     18211575961    94-71-AC-CD-E6-18:CMCC-EASY    120.196.100.99    iface.qiyi.com    視頻網站    15    12    1527    2106    200
1363157995074     84138413    5C-0E-8B-8C-E8-20:7DaysInn    120.197.40.4    122.72.52.12        20    16    4116    1432    200
1363157993055     13560439658    C4-17-FE-BA-DE-D9:CMCC    120.196.100.99            18    15    1116    954    200
1363157995033     15920133257    5C-0E-8B-C7-BA-20:CMCC    120.197.40.4    sug.so.360.cn    信息安全    20    20    3156    2936    200
1363157983019     13719199419    68-A1-B7-03-07-B1:CMCC-EASY    120.196.100.82            4    0    240    0    200
1363157984041     13660577991    5C-0E-8B-92-5C-20:CMCC-EASY    120.197.40.4    s19.cnzz.com    站點統計    24    9    6960    690    200
1363157973098     15013685858    5C-0E-8B-C7-F7-90:CMCC    120.197.40.4    rank.ie.sogou.com    搜索引擎    28    27    3659    3538    200
1363157986029     15989002119    E8-99-C4-4E-93-E0:CMCC-EASY    120.196.100.99    www.umeng.com    站點統計    3    3    1938    180    200
1363157992093     13560439658    C4-17-FE-BA-DE-D9:CMCC    120.196.100.99            15    9    918    4938    200
1363157986041     13480253104    5C-0E-8B-C7-FC-80:CMCC-EASY    120.197.40.4            3    3    180    180    200
1363157984040     13602846565    5C-0E-8B-8B-B6-00:CMCC    120.197.40.4    2052.flash2-http.qq.com    綜合門戶    15    12    1938    2910    200
1363157995093     13922314466    00-FD-07-A2-EC-BA:CMCC    120.196.100.82    img.qfc.cn        12    12    3008    3720    200
1363157982040     13502468823    5C-0A-5B-6A-0B-D4:CMCC-EASY    120.196.100.99    y0.ifengimg.com    綜合門戶    57    102    7335    110349    200
1363157986072     18320173382    84-25-DB-4F-10-1A:CMCC-EASY    120.196.100.99    input.shouji.sogou.com    搜索引擎    21    18    9531    2412    200
1363157990043     13925057413    00-1F-64-E1-E6-9A:CMCC    120.196.100.55    t3.baidu.com    搜索引擎    69    63    11058    48243    200
1363157988072     13760778710    00-FD-07-A4-7B-08:CMCC    120.196.100.82            2    2    120    120    200
1363157985079     13823070001    20-7C-8F-70-68-1F:CMCC    120.196.100.99            6    3    360    180    200
1363157985069     13600217502    00-1F-64-E2-E8-B1:CMCC    120.196.100.55            18    138    1080    186852    200

運行程序MyKpiJob.java,結果生成out目錄,裏面有執行結果文件“part-r-00000”,“part-r-00001”,“part-r-00002”

IDEA下調試和運行Hadoop程序例子