MapReduce排序总结

本文总结了Hadoop MapReduce的排序机制,包括默认的key排序、二次排序以及全局排序的实现方式,如单一Reducer、自定义Partitioner和使用TotalOrderPartitioner,特别是讨论了TotalOrderPartitioner如何解决OOM和数据倾斜问题,并介绍了三种采样器的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【1】Hadoop默认的排序算法,只会针对key值进行排序,按照字典顺序排序

【2】二次排序,在一个数据文件中,首先按照key排序。在key相同的情况下,再按照value大小排序。难度在于要同时参考两列的数据,可以将一行中的两列值封装到bean中。实现WritableComparable接口,重写compareTo进行排序,指定比较规则,实现二次排序,具体可参见博客

【3】全局排序
1、使用一个Reducer
优点:实现简单
缺点:没有利用分布式

2、重写Partioner类
通过重写Partition类,把key在一个范围内的发往一个固定的Reducer,这样在一个Reducer内key是全排序的,在Reducer之间按照序号也是排好序的。比如key代表的是一个年龄,可以把数据输出到10个Reducer。1-10岁之间发往第0个Reducer,11-20发往第2个Reducer,以此类推。但是这样做有两个缺点:

  1. 当数据量大时会出现OOM(内存用完了)
  2. 会出现数据倾斜

3、 TotalOrderPartitioner类
Hadoop提供TotalOrderPartitioner类用于实现全局排序的功能,并且解决了OOM和数据倾斜的问题。TotalOrderPartitioner类提供了数据采样器,对key值进行部分采样,然后按照采样结果寻找key值的最佳分割点,将key值均匀的分配到不同的分区中。TotalOrderPartitioner 类提供了三个采样器,分别是:

  • SplitSampler 分片采样器,从数据分片中采样数据,该采样器不适合已经排好序的数据
  • RandomSampler随机采样器,按照设置好的采样率从一个数据集中采样,是一个优秀的通配采样器
  • IntervalSampler间隔采样机,以固定的间隔从分片中采样数据,对于已经排好序的数据效果非常好

三个采样器都实现了K[] getSample(InputFormat<K,V> inf, Job job)方法,该方法返回的是K[]数组,数组中存放的是根据采样结果返回的key值,即分隔点,MapRdeuce就是根据K[]数组的长度N生成N-1个分区partition数量,然后按照分割点的范围将对应的数据发送到对应的分区中。TotalOrderPartitioner类实现全局排序的功能。代码如下:

Map类:
public class MaxTempMapper extends Mapper<IntWritable, IntWritable, IntWritable, IntWritable>{
   
    protected void map(IntWritable key, IntWritable value, Context context) throws IOException, InterruptedException {
   
     /*   String line=value.toString();
        String arr[]=line.split(" ");*/
        context.write(key,value);
    
在Eclipse中进行MapReduce排序操作,主要是通过编写MapReduce程序来实现数据的排序。以下是一个基本的步骤指南,帮助你在Eclipse中完成MapReduce排序任务: ### 步骤一:安装和配置Hadoop和Eclipse 1. **安装Hadoop**:确保你已经安装了Hadoop,并且配置好了Hadoop环境变量。 2. **安装Eclipse**:下载并安装Eclipse IDE。 3. **安装Hadoop插件**:在Eclipse中安装Hadoop插件(如Hadoop Eclipse Plugin),以便在Eclipse中编写和运行MapReduce程序。 ### 步骤二:创建MapReduce项目 1. **创建新项目**:在Eclipse中创建一个新的Java项目。 2. **添加Hadoop库**:将Hadoop的相关JAR文件添加到项目的构建路径中。 ### 步骤三:编写MapReduce程序 1. **编写Mapper类**: ```java import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; public class SortMapper extends Mapper<LongWritable, Text, IntWritable, IntWritable> { private static IntWritable data = new IntWritable(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); data.set(Integer.parseInt(line)); context.write(data, new IntWritable(0)); } } ``` 2. **编写Reducer类**: ```java import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer; public class SortReducer extends Reducer<IntWritable, IntWritable, IntWritable, IntWritable> { @Override protected void reduce(IntWritable key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { for (IntWritable val : values) { context.write(key, val); } } } ``` 3. **编写主程序类**: ```java import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class SortDriver { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "Sort Job"); job.setJarByClass(SortDriver.class); job.setMapperClass(SortMapper.class); job.setReducerClass(SortReducer.class); job.setOutputKeyClass(IntWritable.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } } ``` ### 步骤四:运行MapReduce程序 1. **配置运行参数**:在Eclipse中配置运行参数,输入和输出路径。 2. **运行程序**:运行主程序类,查看输出结果。 ### 总结 通过上述步骤,你可以在Eclipse中编写并运行MapReduce排序程序。这个过程包括安装和配置Hadoop和Eclipse,编写Mapper、Reducer和主程序类,以及运行程序查看结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值