完全分布式Hadoop 调用DFS上so文件做缓存分发 跑mr
来源:互联网 发布:安卓java模拟器星星 编辑:程序博客网 时间:2024/05/21 17:40
1、前提是你得搭建一个完全分布式环境,不然测试缓存分发没有意义,搭建教程:点击打开链接
2、使用JNA调用so:点击打开链接
3、这里为了只演示so文件的缓存分发,调用到的JNA jar包我就直接跟WordCount一起打包成一个jar包了。
4、测试程序如下,其中libtest.so是linux下编译的C程序动态链接库文件,拷贝到dfs上:
package com.busymonkey;import java.io.IOException;import java.net.URI;import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.filecache.DistributedCache;import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import org.apache.hadoop.util.GenericOptionsParser;import com.sun.jna.Library;import com.sun.jna.Native; public class WordCount { public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { TestDll2.INSTANCE.test(); int c = TestDll2.INSTANCE.addTest(10, 20); System.out.println("================="+c); String line = value.toString(); StringTokenizer itr = new StringTokenizer(line); while (itr.hasMoreTokens()) { word.set(itr.nextToken().toLowerCase()); context.write(word, one); } } } public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> { private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result); } } public interface TestDll2 extends Library {TestDll2 INSTANCE = (TestDll2) Native.loadLibrary("test", TestDll2.class);void test(); int addTest(int a, int b);} public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); DistributedCache.createSymlink(conf); DistributedCache.addCacheFile(new URI("/apps/icps/houTest/libtest.so#libtest.so"), conf); String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); if (otherArgs.length != 2) { System.err.println("Usage: wordcount <in> <out>"); System.exit(2); } Job job = Job.getInstance(conf,"word count"); job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(otherArgs[0])); FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } }
5、对与文本、压缩包、jar包的缓存分发(通过符号链接的方式,这样可以省去复杂的文件操作):
Configuration conf = new Configuration();DistributedCache.createSymlink(conf);//创建符号链接DistributedCache.addCacheFile(new URI("/user/tinfo/zhangguochen/file1#myfile"), conf);//加入分布式缓存,myfile是符号2.在mapreduce中使用public void setup(Context context) { File myfile = new File("myfile");//在这里就可以直接通过符号myfile使用此文件}
6、关于Hadoop DistributedCache 的简介:
DistributedCache是Hadoop提供的文件缓存工具,它能够自动将指定的文件分发到各个节点上,缓存到本地,供用户程序读取使用。它具有以下几个特点:缓存的文件是只读的,修改这些文件内容没有意义;用户可以调整文件可见范围(比如只能用户自己使用,所有用户都可以使用等),进而防止重复拷贝现象;按需拷贝,文件是通过HDFS作为共享数据中心分发到各节点的,且只发给任务被调度到的节点。本文将介绍DistributedCache在Hadoop 1.0和2.0中的使用方法及实现原理。
Hadoop DistributedCache有以下几种典型的应用场景:1)分发字典文件,一些情况下Mapper或者Reducer需要用到一些外部字典,比如黑白名单、词表等;2)map-side join:当多表连接时,一种场景是一个表很大,一个表很小,小到足以加载到内存中,这时可以使用DistributedCache将小表分发到各个节点上,以供Mapper加载使用;3)自动化软件部署:有些情况下,MapReduce需依赖于特定版本的库,比如依赖于某个版本的PHP解释器,一种做法是让集群管理员把这个版本的PHP装到各个机器上,这通常比较麻烦,另一种方法是使用DistributedCache分发到各个节点上,程序运行完后,Hadoop自动将其删除。
7、对于新版本的 hadoop api,这里提供新的缓存分发调用方式:
package com.busymonkey;import java.io.IOException;import java.net.URI;import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import org.apache.hadoop.util.GenericOptionsParser;import com.sun.jna.Library;import com.sun.jna.Native; public class WordCount { public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { TestDll2.INSTANCE.test(); int c = TestDll2.INSTANCE.addTest(10, 20); System.out.println("================="+c); String line = value.toString(); StringTokenizer itr = new StringTokenizer(line); while (itr.hasMoreTokens()) { word.set(itr.nextToken().toLowerCase()); context.write(word, one); } } } public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> { private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result); } } public interface TestDll2 extends Library {TestDll2 INSTANCE = (TestDll2) Native.loadLibrary("test", TestDll2.class);void test(); int addTest(int a, int b);} public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); if (otherArgs.length != 2) { System.err.println("Usage: wordcount <in> <out>"); System.exit(2); } Job job = Job.getInstance(conf,"word count"); job.addCacheFile(new URI("/apps/icps/houTest/libtest.so#libtest.so")); //新方法 job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(otherArgs[0])); FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } }
8、这里如果要引用jar包,同样的也是先拷贝到hdfs上,然后加入:
job.addFileToClassPath(new Path("/apps/icps/houTest/jna-3.5.1.jar"));
9、其实分发的本质就是把文件从dfs上拷贝到本地节点(只要用到的节点都会拷贝),对于引用 so 文件,或者jar包,因为在实际运行的时候程序是跑在本地的,所以本地的环境变量需要能找到这些库文件和包的位置才行,对于so文件,可以在环境变量里面设置:
export LD_LIBRARY_PATH=
这里再注意一下,如果hadoop的 mapred-site.xml文件没有配置缓存目录,那么他就会自动在默认的目录下缓存。这个可以在调用分发方法之后看到日志里有提示这个目录,一般是系统本地目录的 /tmp/hadoop-root/mapred/local 目录下。
- 完全分布式Hadoop 调用DFS上so文件做缓存分发 跑mr
- mr 分布式缓存学习
- Hadoop上编写mr计算
- python在 linux上调用.so文件
- Ubuntu上安装HADOOP多机完全分布式集群
- 虚拟机上进行Hadoop 2.X 完全分布式搭建
- Hadoop完全分布式配置
- Hadoop完全分布式配置
- hadoop完全分布式配置
- hadoop完全分布式实践
- hadoop完全分布式配置
- Hadoop完全分布式配置
- Hadoop完全分布式配置
- Hadoop完全分布式配置
- hadoop完全分布式安装
- Hadoop完全分布式配置
- Hadoop完全分布式配置
- hadoop完全分布式
- Draw2D简介
- python字符串的操作
- hdu5753 Permutation Bo (期望)
- 思维方式
- iOS中UIWebView的使用详解
- 完全分布式Hadoop 调用DFS上so文件做缓存分发 跑mr
- mybatis的org.apache.ibatis.builder.IncompleteElementException问题
- 关于Xcode升级后插件无法使用
- 使用dubbo时applicationContext.xml报错解决办法
- Layout Inflation不能这么用
- 盐雾腐蚀试验室测试标准
- C语言强化指针高级应用学习心得
- java学习之如何解决和检测端口冲突问题
- ImageLoader上网获取图片开源框架