读取SequenceFile中自定义Writable类型值
2016-01-21 11:36
405 查看
1)hadoop允许程序员创建自定义的数据类型,如果是key则必须要继承WritableComparable,因为key要参与排序,而value只需要继承Writable就可以了。以下定义一个DoubleArrayWritable,继承自ArrayWritable。代码如下:
2)以下就是读取tansB.txt文件,将其值转化为DoubleArrayWritable存储到SequenceFile中。
3)将Seq文件上传,然后使用命令查看此Seq文件中的内容:
hadoop fs -text /lz/data/transBSeq
结果提示:
java.lang.RuntimeException: java.io.IOException: WritableName can't load class:matrix.DoubleArrayWritable
4)原因是新定义的Double数组属于第三方包,hadoop不能直接识别,需要将其以上DoubleArrayWritable的源码打成jar包,然后将此jar包的路径在Master端的hadoop-env.sh文件中配置,在其中加入第三方类的位置信息,多个jar包用逗号(,)分割:
export HADOOP_CLASSPATH=/home/hadoop/DoubleArrayWritable.jar;
如下所示,将自定义的DoubleArrayWritable和IntArrayWritable加入到Hadoop_classpath路径中,设置hadoop的环境参数值时可以不加双引号“”,多个jar包以逗号分割,如下所示:
5)然后,使用hadoop fs -text /lz/data/transBSeq就可以看到文件的内容了。如下所示:
可以看到,就是把内存中的对象,持久化存储到了文件中(序列化就是实现内存中”活对象“的持久化存储),为什么看不到具体的内容呢(我明明存储的是一个double数组呀)?我们看到的这个convert.DoubleArrayWritable@264b62a2就是内存中对象的序列化之后的结果,再将这个反序列化之后就可以看到你的double数组了。
参考:
http://www.eveningdrum.com/2014/05/04/hadoop%E4%BD%BF%E7%94%A8%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96jar%E5%8C%85/
6)SequenceFile被称为小文件的容器,主要是用来处理小文件的问题,一般小文件远远小于hadoop物理块的大小,那么分片的时候就会将一个小文件切分为一个单独的分片,而一个分片对应一个mapper,如果有大量的小文件,那么运行mapreduce作业的时候就会启动大量的mapper,增加调度开销,而一个mapper运行时间又很小,因此为了优化小文件的问题,提出了SequenceFile文件格式,这种文件由二进制形式的key-value组成,如果将key设计为文件名称,value为文件内容的话,就将大批小文件合并为一个大文件,SequenceFile也就成了名副其实的小文件容器。(http://www.aliog.com/19501.html,http://dongxicheng.org/mapreduce/hdfs-small-files-solution/)
package matrix; import org.apache.hadoop.io.*; public class DoubleArrayWritable extends ArrayWritable { public DoubleArrayWritable(){ super(DoubleWritable.class); } public double[] convert2double(DoubleWritable[] w){ double[] value=new double[w.length]; for (int i = 0; i < value.length; i++) { value[i]=Double.valueOf(w[i].get()); } return value; } }
2)以下就是读取tansB.txt文件,将其值转化为DoubleArrayWritable存储到SequenceFile中。
package convert; /** * Created with IntelliJ IDEA. * User: hadoop * Date: 16-1-19 * Time: 下午3:09 * To change this template use File | Settings | File Templates. */ import java.io.IOException; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.DoubleWritable; import org.apache.hadoop.io.IOUtils; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.SequenceFile; import org.apache.hadoop.io.Text; import org.apache.commons.io.FileUtils; import org.apache.commons.io.LineIterator; //import Jama.Matrix.*; //import java.io.IOException; import java.io.File; //import javax.sound.midi.SysexMessage; public class SequenceFileWriteDemo { public static void main(String[] args) throws IOException { String uri ="/home/hadoop/srcData/bDoubleArraySeq"; Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(URI.create(uri), conf); Path path = new Path(uri); IntWritable key = new IntWritable(); DoubleArrayWritable value = new DoubleArrayWritable(); SequenceFile.Writer writer = null; try { writer = SequenceFile.createWriter(fs, conf, path, key.getClass(), value.getClass()); final LineIterator it2 = FileUtils.lineIterator(new File("/home/hadoop/srcData/transB.txt"), "UTF-8"); try { int i=0; String[] strings; DoubleWritable[] ArrayDoubleWritables; while (it2.hasNext()) { ++i; final String line = it2.nextLine(); key.set(i); strings=line.split("\t"); ArrayDoubleWritables=new DoubleWritable[strings.length]; for (int j = 0; j < ArrayDoubleWritables.length; j++) { ArrayDoubleWritables[j] =new DoubleWritable(Double.valueOf(strings[j])); } value.set(ArrayDoubleWritables); writer.append(key,value); //System.out.println("ffd"); } } finally { it2.close(); } }finally { IOUtils.closeStream(writer); } System.out.println("ok"); } }
3)将Seq文件上传,然后使用命令查看此Seq文件中的内容:
hadoop fs -text /lz/data/transBSeq
结果提示:
java.lang.RuntimeException: java.io.IOException: WritableName can't load class:matrix.DoubleArrayWritable
4)原因是新定义的Double数组属于第三方包,hadoop不能直接识别,需要将其以上DoubleArrayWritable的源码打成jar包,然后将此jar包的路径在Master端的hadoop-env.sh文件中配置,在其中加入第三方类的位置信息,多个jar包用逗号(,)分割:
export HADOOP_CLASSPATH=/home/hadoop/DoubleArrayWritable.jar;
如下所示,将自定义的DoubleArrayWritable和IntArrayWritable加入到Hadoop_classpath路径中,设置hadoop的环境参数值时可以不加双引号“”,多个jar包以逗号分割,如下所示:
5)然后,使用hadoop fs -text /lz/data/transBSeq就可以看到文件的内容了。如下所示:
可以看到,就是把内存中的对象,持久化存储到了文件中(序列化就是实现内存中”活对象“的持久化存储),为什么看不到具体的内容呢(我明明存储的是一个double数组呀)?我们看到的这个convert.DoubleArrayWritable@264b62a2就是内存中对象的序列化之后的结果,再将这个反序列化之后就可以看到你的double数组了。
参考:
http://www.eveningdrum.com/2014/05/04/hadoop%E4%BD%BF%E7%94%A8%E7%AC%AC%E4%B8%89%E6%96%B9%E4%BE%9D%E8%B5%96jar%E5%8C%85/
6)SequenceFile被称为小文件的容器,主要是用来处理小文件的问题,一般小文件远远小于hadoop物理块的大小,那么分片的时候就会将一个小文件切分为一个单独的分片,而一个分片对应一个mapper,如果有大量的小文件,那么运行mapreduce作业的时候就会启动大量的mapper,增加调度开销,而一个mapper运行时间又很小,因此为了优化小文件的问题,提出了SequenceFile文件格式,这种文件由二进制形式的key-value组成,如果将key设计为文件名称,value为文件内容的话,就将大批小文件合并为一个大文件,SequenceFile也就成了名副其实的小文件容器。(http://www.aliog.com/19501.html,http://dongxicheng.org/mapreduce/hdfs-small-files-solution/)
相关文章推荐
- 1041. Be Unique (20)
- DRUID——为监控而生的DB池
- JAVA代码获取UUID
- [OCLint] oclint-xcodebuild 使用手册
- Win10 Ubuntu14.04 双系统 开机提示 error:no such partition grub rescue
- Easyui扩展或者重载(方法和属性)
- BlockingQueue
- UITextField值改变时的实时监控
- iOS开发UIImageView动画效果
- 处理 tableViewCell 中间的线条到最左边 uitableview separator full width
- confluence启动关闭
- Java语法基础===Java StringBuffer与StringBuider
- IOS开发UI:自定义TabB 4000 ar
- 记一条好用的ubuntu命令: apt-get build-dep
- HDU1423----Greatest Common Increasing Subsequence
- SQL Server 2016 查询存储(Query Store)SSMS面板
- 关于UILable自适应问题--《内容多少》《行间距》
- aduioRecorde录制MP3文件
- IOS中设置UINavigationBar的各种样式(图片/透明效果/下方内容显示情况)
- pcDuino: 无线视频监控小车视频及资料