MapReduce實現手機上網日誌分析(分區)

1、問題背景

  實際業務的須要,好比以移動爲例,河南的用戶去了北京上網,那麼他的上網信息默認保存在了北京的基站,那麼咱們想要查詢北京地區的上網日誌信息默認也包含了其餘地區用戶的在本區的上網信息,不然只能掃描日誌找到北京,很慢,因此分區很須要。html

2、數據集分析

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
1363157985066 	13726238888	00-FD-07-A4-72-B8:CMCC	120.196.100.82	i02.c.aliimg.com		24	27	2481	24681	200
1363157993055 	13560436666	C4-17-FE-BA-DE-D9:CMCC	120.196.100.99			18	15	1116	954	200 

  查看電話號碼一列,看前三位分爲移動、聯通和電信,不過還有以84開頭的贊成歸屬爲海外,那麼咱們須要的共有4個reducer,那麼須要Partitioner裏面須要本身分爲四類。java

  一個reducer對應一個結果文件。spring

  不能再本地運行,這樣的話只能一個map,一個reducer,不管設置。數據庫

3、理論準備

3.1 抽象類與接口

   咱們都知道在面向對象的領域一切都是對象,同時全部的對象都是經過類來描述的,可是並非全部的類都是來描述對象的。若是一個類沒有足夠的信息來描述一個具體的對象,而須要其餘具體的類來支撐它,那麼這樣的類咱們稱它爲抽象類。好比new Animal(),咱們都知道這個是產生一個動物Animal對象,可是這個Animal具體長成什麼樣子咱們並不知道,它沒有一個具體動物的概念,因此他就是一個抽象類,須要一個具體的動物,如狗、貓來對它進行特定的描述,咱們才知道它長成啥樣。跨域

  抽象類和普通類的區別是強制讓子類去重寫弗雷的方法。緩存

public abstract class Animal {  
    public abstract void cry();  
}  
  
public class Cat extends Animal{  
  
    @Override  
    public void cry() {  
        System.out.println("貓叫:喵喵...");  
    }  
}  
  
public class Dog extends Animal{  
  
    @Override  
    public void cry() {  
        System.out.println("狗叫:汪汪...");  
    }  
  
}  
  
public class Test {  
  
    public static void main(String[] args) {  
        Animal a1 = new Cat();  
        Animal a2 = new Dog();  
          
        a1.cry();  
        a2.cry();  
    }  
}  
  
--------------------------------------------------------------------  
Output:  
貓叫:喵喵...  
狗叫:汪汪...  
  其實抽象類就是一個規範,譬如打印機確定有打印功能,可是具體打印彩色仍是黑白就由具體的打印機去實現,強制其餘打印機實現發音方法,可是普通類並無這樣的要求,可能出錯。

  抽象層次不一樣。抽象類是對類抽象,而接口是對行爲的抽象。抽象類是對整個類總體進行抽象,包括屬性、行爲,可是接口倒是對類局部(行爲)進行抽象。安全

     抽象類所跨域的是具備類似特色的類,而接口卻能夠跨域不一樣的類。咱們知道抽象類是從子類中發現公共部分,而後泛化成抽象類,子類繼承該父類便可,可是接口不一樣。實現它的子類能夠不存在任何關係,共同之處。例如貓、狗能夠抽象成一個動物類抽象類,具有叫的方法。鳥、飛機能夠實現飛Fly接口,具有飛的行爲,這裏咱們總不能將鳥、飛機共用一個父類吧!因此說抽象類所體現的是一種繼承關係,要想使得繼承關係合理,父類和派生類之間必須存在"is-a" 關係,即父類和派生類在概念本質上應該是相同的。對於接口則否則,並不要求接口的實現者和接口定義在概念本質上是一致的, 僅僅是實現了接口定義的契約而已。ide

   java自己不支持多繼承,經過實現多個接口來達到多繼承的目的。

3.2 static塊與單例

  static塊會在實例初始化以前執行,因此你能夠在方法調用以前進行一些初始化操做,測試

  單例是獲取對象的一種方式而已,保證只有一個實現類,網站

  實際開發中幾乎用不到,單例spring提供有實現,static在測試的時候可能會用到,還有加載一些系統配置文件的時候可能會把加載寫在static塊中。

4、代碼實現

//Partitioner是map執行完成後reduce還沒執行,因此他的類型是map的輸出類型
public class DataCountPartitioner extends Partitioner<Text,DataBean> {

	//沒執行一次變讀取一次數據庫很很差,能夠作緩存,或者搞成單利,
	//爲了簡單直接搞一個static塊
	private static Map<String , Integer> dataCountMap = 
			new HashMap<String , Integer>();
	static {
		//靜態的從上往下執行,也就是先執行上面的datacoutnMap,不然靜態塊裏
		//網datacountmap裏棉放東西
		dataCountMap.put("135",1);
		dataCountMap.put("136",1);
		dataCountMap.put("137",1);
		dataCountMap.put("138",1);
		dataCountMap.put("139",1);
		dataCountMap.put("150",2);
		dataCountMap.put("159",2);
		dataCountMap.put("182",2);
		dataCountMap.put("183",2);
	}
	
	//int表示分區號
	//numPartitions:幾個reducer就有幾個這個值
	@Override
	public int getPartition(Text key, DataBean value, int numPartitions) {
		// TODO Auto-generated method stub
		String telNo = key.toString();
		//從0開始取3位
		String subTelNo = telNo.substring(0, 3);
		Integer code = dataCountMap.get(subTelNo);
		//186 843等開頭的默認是國外
		if(null==code) {
			code = 0;
		}
		return code;
	}
}

  

5、結果分析

5.1 _SUCCESS

  這個沒啥用,mapreduce自帶的,不過若是你的程序有多部mapreduce,確定會有中間結果,那麼卻是能夠這個_success來判斷是否執行了上個步驟,也就是說在補數據的時候,若是發現某一步_success了 那麼就說明上一步不用補跑mapreduce,直接執行下面的程序.

5.2 結果

  查看結果發現0裏面是134和841開頭的,達到預期,1和2分別是聯通,3是空的,爲何呢?由於partitioner裏面的分類設置類3個,而reducer個數是4個,其中一個reducer沒有數據粉發過去因此就是空的。

  那若是reducer個數小於partitioner個數呢,我發現輸出文件加油,也沒報錯,就是空文件夾。須要log4j才能看到報錯信息。

相關文章
相關標籤/搜索