一、關於設置hdfs
①獲取hdfs文件系統
備註:拋出異常Exception;直接操作hdfs上的文件,需要輸入用戶名,而提交Job等不需要輸入用戶名。
或者Run Configuration 的Environment variables HADOOP_USER_NAME hadoop
②單元測試@before 標識的函數 A---->對某函數B進行單元測試前必須先執行的函數A
@Test 被測試的函數 B
二、運行模式
/***********設定本地測試模式 輸入輸出文件,,在本地或者集羣*************/
備註:本地運行時,可以不 設置Run Configuration 的Environment variables HADOOP_USER_NAME hadoop 也能正常運行。
(即本地運行,用戶可設置也可不設置)
只是文件的user name 是本機電腦的user_name 不是hadoop
/***********設定集羣運行模式 輸入輸出文件都在集羣*************/
方式A
將程序打成JAR包,然後在集羣的任意一個節點上用hadoop命令啓動 推薦
$ hadoop jar wordcount.jar cn.itcast.bigdata.mrsimple.WordCountDriver inputpath outputpath
方式B
修改YarnRunner,並且將四個配置文件放在src下。在執行時也需要打包放到linux上。
只是把控制檯的消息打印在了windows的IDEA上,實際意義不大,放棄!
故總結運行模式:①本地來測試代碼邏輯;②打包提交到集羣模式運行
三、Hadoop開發MapReduce框架用到的Java API
①TestMapper類繼承Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>{}類
實現方法A:protected void map(LongWritable key, Text value, Context context) throw Exception{}
//map階段的業務邏輯就寫在自定義的map()方法中,maptask會對每一行輸入數據調用一次自定義的map()方法。
context.write(new Text(key) ,new IntWritable(value)) 無參數時用nullWritable。
實現方法B:protected void setup(Context context ,)throws Exception{} //task啓動的時候調用。
實現方法C:protected void cleanup(Context context ,)throws Exception{} //task結束的時候調用。
② TextReducer類繼承 Reducer<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {}類
實現方法A:protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws Exception {}類
//按照key分組,確定reduceTask的個數。每個reduceTask都會執行此自定義的reduce()方法,對values進行迭代
//如果key來傳過來的是對象, 每個對象都是不一樣的, 所以每個對象都調用一次reduce方法。
實現方法B:protected
void setup(Context context ,)throws Exception{} //task啓動的時候調用。
實現方法C:protected
void cleanup(Context context ,)throws Exception{} //task結束的時候調用。
③TextDriver類 執行main方法<完成九行設置,兩行IO,兩行等待結束>
……………………………………………………以上是標準MR程序的設計規範,以下補充一些常用的API…………………………………………………………………………
擴展API
①String[] values=value.toString().split("\t");//將讀取的第一行數據,按照字符串裏面內容分片.
數據表格:可將多重數據存在字符串中,然後再次利用split(",")方法取出各數據。
判斷讀入的字符串是否非空 StringUtils.isNotEmpty(line)
檢測字符串相同與否用 .equals();
將字符串中的數字轉變成int型 Integer.parseInt(fields[0])
②StringBuffer:起到String沒有的功能 stringBuffer.append(variable).append(",");
③Text,IntWritable,LongWritable. new
Text("A"); new IntWritable(1); new LongWritable();
④Iterable<T>接口,Iterator<T> iterator();用在reduce()方法直接寫出結果的情況。context.write(values.iterator().next(), bean);
⑤在處理切片時,通過文件名區別讀入的切片
FileSplit inputSplit = (FileSplit) context.getInputSplit();//獲得輸入切片
String fileName = inputSplit.getPath().getName();//獲得切片的源文件名
⑥遍歷values: for(String value : values);
⑦partitioner<key ,value>抽象類。繼承後重寫int getPartition(KEY key, VALUE value, int numPartitions);實現該方法,自定義某(k,v)對對應的reduceTask。
構建ProvincePartitioner.class 繼承Partitioner 實現字段匹配分類
四、關於Map等集合:大數據處理中的(k,v)對,Java一定會用到Map。
Map用於保存具有映射關係的數據,因此Map集合裏保存着兩組值,K-V,Key不能重複。元素的Key索引從Map裏取出該元素
Map裏:所有Key放在一起來看==>一個Set集合。Value放在一起==>一個List。即 Map<Set , List>.
Map接口下有HashMap、LinkedHashMap、SortedMap、TreeMap、EnumMap。
五、關於MapReduce編程的整理與總結
mapreduce在編程的時候,基本上一個固化的模式,沒有太多可靈活改變的地方,除了以下幾處:
1、輸入數據接口:InputFormat ---> FileInputFormat(文件類型數據讀取的通用抽象類) DBInputFormat (數據庫數據讀取的通用抽象類)
默認使用的實現類是: TextInputFormat job.setInputFormatClass(TextInputFormat.class)
TextInputFormat的功能邏輯是:一次讀一行文本,然後將該行的起始偏移量作爲key,行內容作爲value返回
2、邏輯處理接口: Mapper
完全需要用戶自己去實現其中 map() setup() clean()
3、map輸出的結果在shuffle階段會被partition以及sort,此處有兩個接口可自定義:
Partitioner有默認實現 HashPartitioner,邏輯是 根據key和numReduces來返回一個分區號; key.hashCode()&Integer.MAXVALUE % numReduces。通常情況下,用默認的這個HashPartitioner就可以,如果業務上有特別的需求,可以自定義
Comparable當我們用自定義的對象作爲key來輸出時,就必須要實現WritableComparable接口,override其中的compareTo()方法
4、reduce端的數據分組比較接口 : Groupingcomparator reduceTask拿到輸入數據(一個partition的所有數據)後,首先需要對數據進行分組,其分組的默認原則是key相同,然後對每一組kv數據調用一次reduce()方法,並且將這一組kv中的第一個kv的key作爲參數傳給reduce的key,將這一組數據的value的迭代器傳給reduce()的values參數。
利用上述這個機制,我們可以實現一個高效的分組取最大值的邏輯:自定義一個bean對象用來封裝我們的數據,然後改寫其compareTo方法產生倒序排序的效果,然後自定義一個Groupingcomparator,將bean對象的分組邏輯改成按照我們的業務分組id來分組(比如訂單號)這樣,我們要取的最大值就是reduce()方法中傳進來key
5、邏輯處理接口:Reducer完全需要用戶自己去實現其中 reduce() setup() clean()
6、輸出數據接口: OutputFormat ---> 有一系列子類 FileOutputformat DBoutputFormat .....默認實現類是TextOutputFormat,功能邏輯是: 將每一個KV對向目標文本文件中輸出爲一行
六、MR框架編程要點:
詳見eclipse的Test模板包
手機號的流量數據分析:
①從hdfs上獲取文件的手機號及其流量統計的數據
②輸出結果按照流量大小排序
③輸出結果按照省份分割數據到不同的文件
一、項目分析:
①對hdfs上的數據格式分析,確定(k,v)手機號來做key;上下行數據量構成對象做value。
②構造對象Bean,成員變量及其方法。
③編寫Mapper和Reducer類及方法
1、完成Bean的對象構造
①根據對象特點,完善其成員變量以及其get(),set()方法;
②因爲要使用context.write(k,v)所以對象要實現Writable的接口;實現後即可以被寫
③實現String toString();方法。
備註:如果作爲對象的模板學會 修改成員變量;
2、編寫Mapper類(在TestMR類中寫靜態mapper類)
①:繼承Mapper確定輸入輸出的數據格式;
②:讀取一行內容,用空格"\t"或者某些標識切割一行數據,獲取內容存儲在字符串數組中;
③:數據解析後構造對象,寫入context。
3、編寫Reducer類(在TestMR類中寫靜態reducer類)
①確定輸入輸出kv對與Mapper輸出的kv對格式相同;
②按照key完成Values的遍歷,迭代等操作;
③輸出結果文件,注意輸出的對象的定義,最後封裝對象輸出。
4、編寫Driver類(一般在TestMR類中寫main方法實現)
①設定Job;
②完成一系列的設置,類,輸入輸出格式,文件路徑;
③提交Job,檢測。
5、提交Job,進行雲計算
①打包jar,sftp提交到host上;
②執行 hadoop jar Test.jar test.TestMR
③執行 hadoop fs -cat /output/part-r-00000 讀取結果文件