目录      

一、关于Reducer全排序

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

  1.1、  什么叫全排序

  1.2、  分区的标准是什么

二、全排序的三种方式

  2.1、  一个Reducer

  2.2、  自定义分区函数

  2.3、  采样

 

 

 

  一、关于Reducer全排序  

1.1、什么叫全排序?

在所有的分区(Reducer)中,KEY都是有序的:

  • 正确举例:如Reducer分区1中的key是1、3、4,分区2中的key是5、8、9
  • 错误举例:如Reducer分区1中的key是1、3、4,分区2中的key是2、7、9

 

1.2、数据分区的标准是什么?

默认的分区方式是根据mapper后的key的hash值,除以Reducer的分区数量,取其余数判定;例:

  • 某key的hash值是999,此时有3个分区(Reducer),则999 % 3 = 0;则该key和其对应value会分在第一个区(同理,当余数为1,2时会分在对应的另外两个区)。

注意:若key的类型是Text类(或IntWritable等)的,则计算的是Text类型的key的hash值,而非通过Text获取到的String(或int等)类型的hash值。

 也可自定义分区的判定方式,见下2.2、自定义分区函数

 

  二、全排序的三种方式  

  • 一个Reduce
  • 自定义分区函数
  • 采样

 

2.1、一个Reduce

只有一个Reduce分区,自然是全排序效果

 

2.2、自定义分区函数

  1. 创建一个继承Partitioner的类,如:Partition
  2. 重写其”getPartition“方法,作为判断分区的依据
  3. 在main的job中将其加入:job.setPartitionerClass(Partition.class);

以随机分区为例,伪代码如下:

 1 public class Partition extends Partitioner <Text,IntWritable>{  2 
 3  @Override  4     public int getPartition(Text text, IntWritable intWritable, int numPartitions) {  5         Random r = new Random();  6         //根据分区的数量(numPartitions),获取一个随机值返回,返回的值作为Key判断分区的依据
 7         int i = r.nextInt(numPartitions);  8         return i;  9  } 10 } 11 
12 public class RandomAPP { 13     public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { 14  ...... 15 
16         //放判断放入分区的方式(随机放入)
17         job.setPartitionerClass(Partition.class); 18         
19  ...... 20 
21         //等待执行MapperReducer
22         job.waitForCompletion(true); 23  } 24 }

 

 

 

2.3、采样:TotalOrderPartition

  • RandomSampler:随机采样 ,性能差,适合乱序数据
  • IntervalSampler:间隔采样 ,性能较好,适合有序数据
  • SplitSampler:切片采样 ,性能较好,适合有序数据

 

以随机采样为例,伪代码如下:

注:以下需要放在App中设置配置文件的后面

 1         //在App中指定分区函数类
 2         job.setPartitionerClass(TotalOrderPartition.class);  3 
 4         //设置文件的写入路径
 5         TotalOrderPartition.setPartitionFile(job.getConfiguration(),new Path("E:/par.dat"));  6 
 7         /**
 8  * 初始化采样器  9  * RandomSampler 采用随机采样的方式 10  * freq 每个Key被选中的概率 freq x key > 分区数 11  * numSamples 需要的样本数 numSamples > 分区数 12  * maxSplitsSampled 文件最大切片数 maxSplitsSampled > 当前切片数 13          */
14         InputSampler.RandomSampler = new InputSampler.RandomSampler(freq, numsamples,maxsplitsSampled ); 15 
16         //写入采样数据
17         InputSampler.writePartitionFile(job,sampler);

 

 

    Over    

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄