利用取樣器實現mapreduce任務輸出全排序

2021-09-22 03:39:11 字數 3960 閱讀 1192

取樣器是hadoop內自帶的乙個可以對目標檔案部分資料進行提取的工具類,以方便我們對這些取樣的資料做一些參考或者處理。hadoop提供了多種取樣器供我們使用,以滿足不同的需求。另外,取樣器不同於普通mapreduce操作。它是直接在客戶端機器上執行的。

常見取樣器

intervalsampler 以一定的間隔定期從劃分中選擇key,對有排序的資料來說更好

randomsameler 以指定的取樣率均勻的從資料集中選擇樣本

splitsampler 只取樣乙個分片的前n條記錄,所以不適合有排序的資料

最簡單的使用取樣器舉例

例1:

jobconf conf = new jobconf(samplertest.class);

conf.setjobname("sampler");

fileinputformat.setinputpaths(conf, new path(args[0]));

fileoutputformat.setoutputpath(conf, new path(args[1]));

//設定取樣率為0.1,最大樣本數1000,最大分割槽數10(在最多10個分割槽中,按照約總條數*0.1的間隔取出乙個樣本,最多1000個樣本,注意每條提取的順序也是被打亂了的),取樣器在客戶端執行

//理論上randomsampler中的k,v和inputformat中的map傳入值型別一致,但是這裡好像有個bug,在後面的sampler.getsample(inf, conf)中返回的list使用的toarrays()方法,這樣返回的就只能是object陣列了,所以k只能為object,否則會拋類轉換異常。另外v在取樣時沒什麼用

randomsamplersampler = new randomsampler(0.1, 1000, 10);

final inputformatinf = (inputformat) conf.getinputformat();

//因為sampler.getsample(inf, conf)的返回型別由inf中的inputformat中的k,v決定,所以這裡也要轉換成對應的k,v

從配置中獲得inputformat,若不配置,預設使用textinputformat(這裡就沒配置)

object keys = sampler.getsample(inf, conf);

for(object l:keys)

return 0;

上面的例子只是對取樣器進行了簡單的使用,從總條數*0.1的間隔取出乙個樣本,最多1000個樣本,最大10個分割槽中取出樣本。並將這些樣本列印出來。注意,若這裡面任意乙個條件滿足。則取樣本操作結束。比如已經取到了1000個樣本,或者已經取了10個分割槽時,這時就認為樣本已提取完成。

這個例子可以看出兩個問題:

1.該例子沒有進行runjob,所以沒有執行mapreduce任務。由此看來取樣器的獲取是在客戶端中進行的

2.該例子得到的sample只能是key的sample,不能是value的sample。若要得到value的sample則需要自己重寫該方法了。

利用樣本來對輸出內容進行全排序

使用hadoop對輸出檔案進行全排序有很多方法,他們各有優缺點,這裡總結一下各個方法的優劣:

1.直接使用乙個reduce,且輸出乙個檔案。

該操作的優點在於簡單,無須進行任何排序操作,hadoop在進行reduce的時候就對key進行了內部排序。所以直接輸出結果就醒了。但是它的缺點也是顯而易見的,就是一旦資料量大了以後,採用乙個reduce對資料進行處理顯然沒有達到分布式處理的效果,有違hadoop的操作宗旨。

2.自定義partitioner,按範圍來區分多個reduce任務,輸出多個檔案,然後再將這些檔案進行組合。

該操作的優點在於能夠有效的將大資料進行分布式處理,達到了一定程度的負載均衡。但是缺點是使用者依賴較大。除了要自己寫partitioner,使用者還要要事先知道資料的取之範圍,而且還要了解資料分布情況,若資料分布不均勻的時候也可能出現負載不均衡的情況。如乙個包含了各地溫度的資料。在-20~0度約有5%,0~20度約有80%,20~40度約有14%。若按照每20度來進行劃分的話,顯然不能達到均衡的效果。

3.採用hadoop提供的totalorderpartitioner分割槽工具進行全排序

該操作實際上就是hadoop內部使用了取樣器來對資料進行取樣,然後內部按分布比例進行分割槽。整個動作已經幫開發者做好了,所以它的優點是能夠最大限度的達到負載均衡。

方法1比較簡單,下面分別對方法2和方法3做乙個簡要描述和舉例:

利用方法2實現全排序:自定義partitioner的mapreduce任務來實現全排序

採用hadoop提供的totalorderpartitioner分割槽工具實現全排序簡單方便。但是有的時候我們可能需要增加一些自定義的東西來實現更通用的擴充套件。這個時候就有必要自己寫乙個類似的功能來實現全排序了。

全排序的思想無外乎就是先對資料進行取樣,然後根據取樣的資料進行分割槽。最後得到按指定分割槽好的並且已排序的資料。按照這個思想,我們就可以寫mapreduce任務了。

例2:

public class mymap extends mapreducebase implements

@override

public void map(longwritable key, text val,

outputcollectoroutput, reporter reporter)

throws ioexception

}

2.編寫reducer:reducer的任務就是對已排好序的key進行處理並輸出。

public class myred extends mapreducebase implements

reducer

}}

3.編寫partitioner:partitioner的作用就是將map任務的結果交給哪個reduce處理,這裡需要用到已建立好快取資料(該資料會在執行客戶端主程式時)。該快取資料告訴patitioner將哪些範圍中的資料放到哪個reducer中去

public class mypartitions implements partitioner

@override

public int getpartition(longwritable key, intwritable value,

int numpartitions)

}

4.最後編寫客戶端主程式:執行mapreduce任務驅動程式,並產生分布式快取資料

public class samplertest3 extends configured implements tool 

public static void main(string args) throws exception

}

利用方法3實現全排序:採用hadoop提供的totalorderpartitioner分割槽工具來實現全排序

採用hadoop的totalorderpartitioner簡化了開發,原理實際上和上面的例子類似,都是先取樣,然後進行分割槽。但是我們無需關心如何劃分partition,並且也不用關心分布式快取如何生成和使用。只要提供對應的key的樣本即可。下面這個例子就是使用了hadoop提供的分割槽工具。

例3:

public class samplertest4 extends configured implements tool 

public static void main(string args) throws exception

}

上面只是對有關全排序進行乙個針對性的描述。實際使用中還可以進一步優化,比如採用壓縮機制。或者自定義優化對key的排序,這樣會時mapredoce任務執行效率更高。

jmeter取樣器結果分析

thread name 執行緒組名稱 sample start 啟動開始時間 load time 載入時長,這個時間是我們測試常用的時間,也是整個請求的消耗時間,從傳送到接收完成全程消耗的時間 latency 等待時長,不常用,表示從請求傳送到剛開始接收響應時的時間 size in bytes 傳送...

17 Jmeter 取樣器一

這個是老熟人了,就不多說了。可以理解為對執行緒的操作,下面用乙個例子進行講解。test action例項 執行結果 通過上面的示例我們可以看到執行緒被暫停了3s再執行下乙個請求。這個也是我們除錯中常用的元件。debug sampler會生成乙個樣本,其中包含所有jmeter變數和 或屬性的值。可以在...

的取樣方式 可攜式水質自動取樣器水質取樣操作介紹

術語 取樣程式 是指為使取樣器按照使用者需求順利執行而修改的取樣引數,包括取樣方式 取樣量 啟動方式等等,使用者可以根據實際需要在操作介面對取樣引數進行修改 儲存。程式編號 使用者可以預先編寫10個取樣程式,每個取樣程式可以有不同的取樣方式及啟動方式,每個程式對應乙個程式編號,編號範圍為0 9,使用...