hadoop,用户制定类
来源:互联网 发布:数据库设计思路与原则 编辑:程序博客网 时间:2024/06/05 17:48
转载: http://www.cnblogs.com/liqizhou/archive/2012/05/14/2499498.html
mapreduce是一个很精巧的构思和设计,对于很多计算问题,程序员通常可以使用默认设置取处理诸多底层的细节,但是,这并不意味着在解决复杂问题时,程序员就可以完全使用这二个函数就可以搞定一切,它还需要更加复杂和灵活的处理机制以及高级的编程技术和方法。本节介绍hadoop中mapreduce比较高级的方法---用户制定类。为什么要用户自定义类,一种直观的猜测就是基本的mapreduce处理不了或者处理的效果不好,才有可能用到用户制定,随着深入的学习,这些问题到处可见。比如文档的倒排索引,制定(优化)的目的就是减少中间键,从而减少每次的读写I/O和网络的压力。
1. 用户自定义数组类型
虽然hadoop中内置8种数据类型,我见过8种,但不一定就8种,这里就认为是8种吧,他们都实现了WritableComparable接口,这种好处就是可以被序列化进行网路传输和文件存储。BooleanWritable, ByteWritable, FloatWritable, IntWritable,LongWritable,Text, NullWritble,前几种大家都可以猜到表示是什么数据类型,Text表示使用UTF格式的存储的文本。好像visual stdio 中text控件,也是对String类型的一种包装。
自定义类型必须符合二个条件,第一:实现Writable接口。第二:如果该函数需要作为主键Key使用,或者要比较数值大小时,则要实现WritableComparable接口。下例子是一个圆为例。circle
public class Cricle implements Writable<Circle>{ private float radius,x,y; public float GetRadius(){return radius;} public float GetX(){return x;} public float GetY(){return y;} public void readFields(DataInput in)throws IOException{ radius=in.readFloat(); x=in.readFloat(); y=in.readFloat(); } public void write(DataOutput out)throws IOException{ out.writeFloat(radius); out.writeFloat(x); out.writeFloat(y); } public int CompareTo(Circle cl){ if(cl.radius==this.radius) return 0; if(cl.x>this.x) return 1; if(cl.y<this.y) return -1; }}
以上代码就是手写的,没有进行测试,肯定还有错误,只是向说明问题。readFields() 和write()实现Writable接口中定义的二中方法。
2. 用户制定输入/输出
尽管Hadoop提供了较为丰富的数据输入/输出格式,可以满足很多应用的需要,但是,对于特殊的要求,还是要用户自己制定。比如说,Hadoop默认的数据输入格式为TextInputFormat,可以将文本文件分块并逐行读入以便Map节点进行处理,每行所产生的Key是文本的字节位置的偏移量,而value就是该行的内日内个。但现在需要文件名@文本偏移量作为key,所以就需要制定输入类,假定现在制定一个数据输入格式FileNameInputFormat和fileNameRecordReader,比便直接产生FileName@lineoffset.
public class FileNameInputFormat extends FileInputForamt<Text,Text>{ public RecordReader<Text,Text>createRecordReader(InputSplit split,TaskAttemptContext context)throws IOException{ FileNameRecordReader fnrr = new FileNameRecordReader(); fnrr.initialize(split,context); }}public class FileNameRecordReader extends RecordReader<Text, Text> { String FileName; LineRecordReader lrr = new LineRecordReader(); public Text getCurrentKey() throws IOException { return new Text("(" + FileName + "@" + lrr.getCurrentKey() + ")"); } public Text getCurrentValue() throws IOException, InterruptedException { return new Text(lrr.getCurrentKey().toString()); } public void initialize(InputSplit arg0, TaskAttemptContext arg1) throws IOException { lrr.initialize(arg0, arg1); FileName = ((FileSplit) arg0).getPath().getName(); }}
没事什么好讲的,仔细看都能看的懂,输出就不讲了,和输入差不多。
3. 用户制定Patritioner和Combiner
Patritioner来完成中间结果向Reduce节点分区处理,通常是利用hash进行分配,hash划分主要是靠主键进行划分,即相同的主键划分到相同桶中,在mapreduce中就是划分到相同的reduce中。那么现在设想一个问题,我需要将这样的数据划分到一个reduce中,该怎么办? 数据为 hello:1, hello:2,hello:3,hello:4,......., 显然,用hash直接划分是不行的,这是我们可以观察到这些数据都具有一个hello,我们只需要在提取hello作为主键,在用hash划分,就可以把这些数据都划分到同一个reduce中,下面就个例子,给出Patritioner代码:
public class NParterioner extends HashPartitioner<Text,Text>{ public getPartition(Text key,Text value, int numReduceTasks){ String t=key.toString().split(":")[0]; Text term; term.set(t); super.getPartition(term,value,numReduceTasks); }}
还有像map,reduce, combiner的制定都是一样的道理。
总结:
用户类的制定主要取决于特定的应用的场合,但其目标都是不变的(减少中间结果来减小I/O和网络传输数据的压力)。
- hadoop,用户制定类
- hadoop,用户制定类
- hadoop,用户制定类
- 比较与选择 - 怎样通过设计帮助用户制定决策
- linux下创建用户,制定目录,赋权限
- 在制定seo计划之前要确定网站用户需求
- 【hadoop】用户自定义计数器
- hadoop之用户定制
- YII用户注册和用户登录(三)之模型中规则制定和分析
- eclipse中给类制定注释模板
- hadoop用户的权限分配
- hadoop的用户代理机制
- Hadoop用户行为分析项目
- 新建hadoop用户以及用户组
- IBM制定新Linux计划“策反”200万微软NT用户
- Ubuntu 添加新用户并制定目录和shell,并配置为root组用户|sudoer 修改
- Ubuntu 添加新用户并制定目录和shell,并配置为root组用户|sudoer 修改
- 通过File类在计算机上创建制定的文件
- Exercise 2-8.
- Java String.trim () 函数的使用
- UIDocumentInteractionController 第三方应用中打开自己的文件 方法
- java collection
- java继承中,成员变量的覆盖
- hadoop,用户制定类
- UiAutomator2自动化测试环境搭建
- Android获取电池电量的三种方法
- hdu 1069 Monkey and Banana
- 保存枚举值,应该是要保存int值
- 【GDKOI 2016】模拟训练总结合集
- Cordova各个插件使用介绍系列(一)—$cordovaSms发送短信
- SpringMVC使用@ResponseBody时返回json的日期格式处理为指定格式
- getc、fgetc、getchar、ungetc