zoukankan      html  css  js  c++  java
  • hadoop排序 -- 全排序

    目录      

    一、关于Reducer全排序

      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    

     

  • 相关阅读:
    Docker入门,看这一篇就够了
    SpringBoot15:整合JPA
    docker 常用命令备忘录
    LeetCode 93. 复原IP地址 | Python
    LeetCode 99. 恢复二叉搜索树 | Python
    LeetCode 100. 相同的树 | Python
    LeetCode 336. 回文对 | Python
    LeetCode 337. 打家劫舍 III | Python
    LeetCode 207. 课程表 | Python
    LeetCode 415. 字符串相加 | Python
  • 原文地址:https://www.cnblogs.com/yiwanfan/p/9098366.html
Copyright © 2011-2022 走看看