IDEA下調試和運行Hadoop程序例子
準備
配置好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程序例子