在HBase MapReduce任务中加载本机共享库

时间:2015-03-04 03:02:29

标签: java hadoop mapreduce java-native-interface

最近我试图在JNI代码中实现我的算法(使用C ++)。我这样做并生成一个共享库。 这是我的JNI课程。

    public class VideoFeature{
        // JNI Code Begin
        public native static  float Match(byte[] testFileBytes, byte[] tempFileBytes);
        static {
            System.loadLibrary("JVideoFeatureMatch");
        }
        // JNI Code End
    }

在主要功能中,我写

    //  MapReduce
        Configuration conf = HBaseConfiguration.create();

    //  DistributedCache shared library
        DistributedCache.createSymlink(conf);
    //  Both following ways seem work.
    //  DistributedCache.addCacheFile(new URI("/home/danayan/Desktop/libJVideoFeatureMatch.so#JVideoFeatureMatch"), conf);
        DistributedCache.addCacheFile(new URI("hdfs://danayan-pc:9000/lib/libJVideoFeatureMatch.so#libJVideoFeatureMatch.so"), conf);

在地图方法中,代码跟随工作。

 public  static class MatchMapper extends TableMapper<Text, IntWritable> {

        @Override
        public void map(ImmutableBytesWritable key, Result values, Context context) throws IOException, InterruptedException {

        // Other codes
        Path[] localFiles = DistributedCache.getLocalCacheFiles(context.getConfiguration());
        for(Path temp:localFiles) {
            String path = temp.toString();
            if(path.contains("JVideoFeatureMatch")) {
                 System.out.println("JVideoFeatureMatch  found !");
            }
        }
}

换句话说,似乎我'DistributedCache'成功了我的共享库。但是我无法在Map函数中加载它。

 public  static class MatchMapper extends TableMapper<Text, IntWritable> {

    @Override
    public void map(ImmutableBytesWritable key, Result values, Context context) throws IOException, InterruptedException {
    // Other codes
    int score = (int)VideoFeature.Match(testBytes, tempBytes);
}

当我尝试在JNI类中调用静态函数时,抛出'java.lang.Exception':

java.lang.UnsatisfiedLinkError: no libJVideoFeatureMatch in java.library.path.

我也试过'System.load()'。我已经考虑在Linux系统中使用前缀'lib'和后缀'.so'。

更重要的是,我设置了一个jvm参数(删除它没有区别):

  -Djava.library.path=/usr/local/hadoop/lib/native/Linux-amd64-64

我已经通过将共享库移动到'Java.library.path'(上面设置)来成功地在本地计算机中加载了共享库。

我浏览了以下网站:

Issue loading a native library through the DistributedCache

Native Libraries Guide loading native libraries in hadoop reducer?

我不知道我是否说得清楚。如果没有,请告诉我。

1 个答案:

答案 0 :(得分:0)

  1. 首先将库复制到HDFS:

    bin/hadoop fs -copyFromLocal mylib.so.1 /libraries/mylib.so.1  
    
  2. 作业启动计划应包含以下内容:

    DistributedCache.createSymlink(conf);   
    DistributedCache.addCacheFile("hdfs://host:port/libraries/mylib.so.1#mylib.so", conf);  
    
  3. MapReduce任务可以包含:

    System.load((new File("mylib.so")).getAbsolutePath());
    
  4. 第三点与官方文档不同

    官方文件:Native Shared Libraries