1、需求

按学生的年龄段,将数据输出到不同的文件。这里我们分为三个年龄段:小于等于20岁、大于20岁小于等于50岁和大于50岁

2、实现

1、编写Partitioner,代码如下

public static class StudentPartitioner extends Partitioner<IntWritable, Text> {
@Override
public int getPartition(IntWritable key, Text value, int numReduceTasks) {
// 学生年龄
int ageInt = key.get(); // 默认指定分区 0
if (numReduceTasks == 0)
return 0; if (ageInt <= 20) { // 年龄小于等于20,指定分区0
return 0;
}else if (ageInt <= 50) { // 年龄大于20,小于等于50,指定分区1
return 1;
}else{ // 剩余年龄,指定分区2
return 2;
}
}
}

2、编写mapper

public static class StudentMapper extends Mapper<LongWritable, Text, IntWritable, Text>{
@Override
protected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {
String[] studentArr = value.toString().split("\t"); if(StringUtils.isNotBlank(studentArr[1])){
/*
* 姓名 年龄(中间以tab分割)
* 张明明 45
*/
// 年龄
IntWritable pKey = new IntWritable(Integer.parseInt(studentArr[1].trim())); // 以年龄作为key输出
context.write(pKey, value);
}
}
}

3、编写reducer

public static class StudentReducer extends Reducer<IntWritable, Text, NullWritable, Text> {
@Override
protected void reduce(IntWritable key, Iterable<Text> values,Context context) throws IOException, InterruptedException {
for(Text value : values){
context.write(NullWritable.get(), value);
}
}
}

4、一些运行代码

@Override
public int run(String[] arg0) throws Exception {
// 读取配置文件
Configuration conf = new Configuration(); Path mypath = new Path(arg0[1]);
FileSystem hdfs = mypath.getFileSystem(conf);
if (hdfs.isDirectory(mypath)) {
hdfs.delete(mypath, true);
} // 新建一个任务
Job job = new Job(conf, "PartitionerDemo");
// 设置主类
job.setJarByClass(StudentPartitioner.class); // 输入路径
FileInputFormat.addInputPath(job, new Path(arg0[0]));
// 输出路径
FileOutputFormat.setOutputPath(job, new Path(arg0[1])); // Mapper
job.setMapperClass(StudentMapper.class);
// Reducer
job.setReducerClass(StudentReducer.class); // mapper输出格式
job.setMapOutputKeyClass(IntWritable.class);
job.setMapOutputValueClass(Text.class); // reducer输出格式
job.setOutputKeyClass(NullWritable.class);
job.setOutputValueClass(Text.class); //设置Partitioner类
job.setPartitionerClass(StudentPartitioner.class);
// reduce个数设置为3
job.setNumReduceTasks(3); //提交任务
return job.waitForCompletion(true)?0:1;
}
public static void main(String[] args0) throws Exception {
// 数据输入路径和输出路径
// String[] args0 = {
// "hdfs://ljc:9000/buaa/student/student.txt",
// "hdfs://ljc:9000/buaa/student/out/"
// };
int ec = ToolRunner.run(new Configuration(), new StudentAgePartitionerDemo(), args0);
System.exit(ec);
}

3、总结

Partitioner适用于事先知道分区数的情况下,比如像上面这个需求

缺点:

1、在作业运行之前需要知道分区数,也就是年龄段的个数,如果分区数未知,就无法操作。

2、一般来说,让应用程序来严格限定分区数并不好,因为可能导致分区数少或分区不均

如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【刘超★ljc】。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

实现代码及数据:下载

使用Partitioner实现输出到多个文件的更多相关文章

  1. android源码环境下用mmm/mm编译模块,输出编译log到文件的方法

    android源码环境下用mmm/mm编译模块,输出编译log到文件的方法 1,在android目录下直接用mmm命令编译, log信息保存在android目录下 mmm packages/apps/ ...

  2. Linux标准输入、输出和错误和文件重定向(转) --- good

    标准输入.输出和错误 当我们在shell中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件.由于文件描述符不容易记忆,shell同时也给出了相应的文件名.下面就是这些文 ...

  3. hadoop1.2.1 MultipleOutputs将结果输出到多个文件或文件夹

    hadoop1.2.1 MultipleOutputs将结果输出到多个文件或文件夹 博客分类:http://tydldd.iteye.com/blog/2053867 hadoop   hadoop1 ...

  4. log4j.properties配置与将异常输出到Log日志文件实例

    将异常输出到 log日志文件 实际项目中的使用: <dependencies> <dependency> <groupId>org.slf4j</groupI ...

  5. 写文件的工具类,输出有格式的文件(txt、json/csv)

    import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io. ...

  6. Linux标准输入、输出和错误和文件重定向 专题

    当我们在shell中执行命令的时候,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件.由于文件描述符不容易记忆,shell同时也给出了相应的文件名. 下面就是这些文件描述符及它们通常所 ...

  7. Log4j按级别输出日志到不同文件配置

    1.自定义LogFileAppender类,继承DailyRollingFileAppender,实现Log4j按级别输出日志到不同文件. package com.liying.mango.commo ...

  8. Altium Designer 输出 gerber 光绘文件的详细说明

    Altium Designer 输出 gerber 光绘文件的详细说明 PCB画好后,我们需要输出光绘文件交给制版厂家.由此,输出光绘文件的重要性就显出来了. 先复习一下介绍各层的定义吧,哈哈 (1) ...

  9. loadrunner脚本中参数化和返回值输出log到外部文件

    loadrunner脚本中参数化和返回值输出log到外部文件 很多时候,我们在做性能测试之前,需要造数据,但是使用的这些参数化数据和生成的返回数据在后面的测试都会用的,所以我们需要在造数据过程中,将参 ...

随机推荐

  1. 批处理协同blat自动发邮件

    Blat - A Windows (32 & 64 bit) command line SMTP mailer. Use it to automatically eMail logs, the ...

  2. double类型字符串转换成一个纯数字字符串和一个小数点位数的c++代码

    今天工作中遇到一个要不一个double型的字符串转换成一个纯字数字符串和一个标志这个数字字符串的小数点有几位的int类型 例如:“23.123”--->“23123” + 3   比较简单.就是 ...

  3. Laravel之路——缓存使用

    1.使用Redis类 use Illuminate\Support\Facades\Redis; //设置指定 key 的值(覆盖老的value) Redis::setex('key','value' ...

  4. PyCharm使用技巧记录(一)如何查看变量

    [为了方便自己以后查阅,记录下使用PyCharm时的一些小技巧] 正在学习Python,在调试Python程序时,遇到了一个非常大的问题:如何能够方便地查看变量的取值呢? 由于使用matlab多年,深 ...

  5. liveReload

    依赖条件: 1.安装liveReload浏览器插件: http://livereload.com/extensions/ chrome可以直接去在线商店安装liveReload. P.S.也可以贴代码 ...

  6. 【NOIP 2011】 观光公交

    题目描述 Description 风景迷人的小城 Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第0 分钟出现在1号 ...

  7. 在iOS中创建静态库

    如果您有不错的原创或译文,欢迎提交给我们,更欢迎其他朋友加入我们的翻译小组(联系qq:2408167315).  =========================================== ...

  8. 【技术贴】解决myeclipse SVN 提交代码 commit:remains in tree-conflict错误的解决办法

    [技术贴]解决myeclipse SVN 提交代码 commit:remains in tree-conflict错误的解决办法 错误是:Aborting commit: xxxxx’ remains ...

  9. Tomcat架构(三)

    嵌套组件 这些组件是针对Tocmat做的特定实现,他们的主要目的是使各种Tomcat容器可以完成各自的工作. 1.阀(Valve) valve是处理元素,它可以被包含在每个Tomcat容器的处理路径中 ...

  10. Keil 程序调试窗口

    上一讲中我们学习了几种常用的程序调试方法,这一讲中将介绍Keil提供各种窗口如输出窗口.观察窗口.存储器窗口.反汇编窗口.串行窗口等的用途,以及这些窗口的使用方法,并通过实例介绍这些窗口在调试中的使用 ...