問題:不能將氣溫視為Text對象並以字典順序排序
正統做法:用順序文件存儲數據,其IntWritable鍵代表氣溫,其Text值就是數據行
常用簡單做法:首先,增加偏移量以消除所有負數;其次,在數字面前加0,使所有數字的長度相等;最后,用字典法排序。
streaming的做法:-D mapred.text.key.comparator.options="-k1n -k2nr" 第一個year字段按數值順序排序,第二個temp字段按數值順序方向排序
Partitioner

patition類結構
2. HashPartitioner是mapreduce的默認partitioner。計算方法是
which reducer=(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks,得到當前的目的reducer。
3. BinaryPatitioner繼承於Partitioner< BinaryComparable ,V>,是Partitioner的偏特化子類。該類提供leftOffset和rightOffset,在計算which reducer時僅對鍵值K的[rightOffset,leftOffset]這個區間取hash。
Which reducer=(hash & Integer.MAX_VALUE) % numReduceTasks
4. KeyFieldBasedPartitioner也是基於hash的個partitioner。和BinaryPatitioner不同,它提供了多個區間用於計算hash。當區間數為0時KeyFieldBasedPartitioner退化成HashPartitioner。
$HADOOP_HOME/bin/hadoop streaming \
-D stream.map.output.field.separator=. \
-D stream.num.map.output.key.fields=4 \
-D map.output.key.field.separator=. \ #map輸出分隔符設為“.”
-D num.key.fields.for.partition=2 \ #將key分隔出來的前兩個部分而不是整個key用於Partitioner做partition
-input /user/test/input -output /user/test/output \
-mapper “mymapper.sh” -reducer “ myreducer.sh” \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \ #使用KeyFieldBasedPartitioner
-file /home/work/mymapper.sh \
-file /home/work/myreducer.sh \
-jobconf mapred.job.name=”key-partition-demo”
5. TotalOrderPartitioner這個類可以實現輸出的全排序。不同於以上3個partitioner,這個類並不是基於hash的。在下一節里詳細的介紹totalorderpartitioner。
這樣的方法跟單機沒什么區別,完全沒有利用分布式計算的優勢;數據量稍大時,一個reduce的處理效率極低。
分布式方案:
首先,創建一系列排序好的文件;其次,串聯這些文件;最后生成一個全局排序的文件。
主要思路是使用一個partitioner來描述全局排序的輸出。
由此我們可以歸納出這樣一個用hadoop對大量數據排序的步驟:
1) 對待排序數據進行抽樣;
2) 對抽樣數據進行排序,產生標尺;
3) Map對輸入的每條數據計算其處於哪兩個標尺之間;將數據發給對應區間ID的reduce
4) Reduce將獲得數據直接輸出。
這里使用對一組url進行排序來作為例子:
采樣類結構圖
采樣方式對比表:
| 類名稱 |
采樣方式 |
構造方法 |
效率 |
特點 |
| SplitSampler<K,V> |
對前n個記錄進行采樣 |
采樣總數,划分數 |
最高 |
|
| RandomSampler<K,V> |
遍歷所有數據,隨機采樣 |
采樣頻率,采樣總數,划分數 |
最低 |
|
| IntervalSampler<K,V> |
固定間隔采樣 |
采樣頻率,划分數 |
中 |
對有序的數據十分適用 |
RandomSampler的三個參數分別是采樣率、最大樣本數、最大分區。
TotalOrderPartitioner.setPartitionFile(conf, partitionFile);
InputSampler寫的分區文件放在輸入目錄。
TotalOrderPartitioner指定partition文件。partition文件要求Key (這些key就是所謂的划分)的數量和當前reducer的數量相同並且是從小到大排列。
partition文件載入分布式緩存。
