Hadoop lzo 正确安装及问题解决

2019-03-28 13:31|来源: 网络

之前有篇文章 http://www.linuxidc.com/Linux/2012-08/67021.htm 介绍解Hadoop-lzo相关问题,同时也介绍到了如何安装.但发现这种安装方法会出现一些问题.

同时这种安装方法也是网上流传的安装方法,我这里予以纠正.先说下大概原因:hadoop-lzo-xxx的前身是hadoop-gpl-compression-xxx,之前是放在google code下管理,地址:http://code.google.com/p/hadoop-gpl-compression/ .但由于协议问题后来移植到github上,也就是现在的hadoop-lzo-xxx,github,链接地址:https://github.com/kevinweil/hadoop-lzo.网上介绍hadoop lzo压缩都是基于hadoop-gpl-compression的介绍.而hadoop-gpl-compression还是09年开发的,跟现在hadoop版本已经无法再完全兼容,会发生一些问题.而按照网上的方法,为了兼容hadoop,使用hadoop-lzo-xxx,但安装hadoop-gpl-compression会报错.具体报错如下:

  1. 11/12/02 14:28:41 INFO lzo.GPLNativeCodeLoader: Loaded native gpl library   
  2. 11/12/02 14:28:41 WARN lzo.LzoCompressor: java.lang.NoSuchFieldError: workingMemoryBuf   
  3. 11/12/02 14:28:41 ERROR lzo.LzoCodec: Failed to load/initialize native-lzo library   
  4. 11/12/02 14:28:41 WARN mapred.LocalJobRunner: job_local_0001   
  5. java.lang.RuntimeException: native-lzo library not available   
  6.     at com.hadoop.compression.lzo.LzoCodec.createCompressor(LzoCodec.java:165)   
  7.     at com.hadoop.compression.lzo.LzopCodec.createOutputStream(LzopCodec.java:50)   
  8.     at org.apache.hadoop.mapreduce.lib.output.TextOutputFormat.getRecordWriter(TextOutputFormat.java:132)   
  9.     at org.apache.hadoop.mapred.MapTask$NewDirectOutputCollector.<init>(MapTask.java:520)   
  10.     at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:635)   
  11.     at org.apache.hadoop.mapred.MapTask.run(MapTask.java:322)   
  12.     at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:210)

我调试源码才发现原因,因为hadoop lzo实际上得依赖C/C++开发的lzo去压缩,而他们通过JNI去调用.如果使用hadoop-gpl-compression下的Native,但使用hadoop-lzo-xxx的话,会导致版本不一致问题.所以正确的做法是,将hadoop-lzo-xxx下的Native放入到/usr/local/lib下.而你每升级一个hadoop-lzo-xxx版本,或许就得重复将新lzo版本下的native目录放入/usr/local/lib下.具体需要测试.

同时这里说下,hadoop-lzo-xxx的验证原理,让我们更系统的了解为什么使用hadoop-lzo会报的一系列错误.

1)首先Hadoop-lzo会通过JNI调用gplcompression,如果调取不到会报Could not load native gpl library异常.具体代码如下:

  1. static {
  2.    try {   
  3.       //try to load the lib   
  4.       System.loadLibrary("gplcompression");   
  5.       nativeLibraryLoaded = true;   
  6.       LOG.info("Loaded native gpl library");   
  7.     } catch (Throwable t) {   
  8.       LOG.error("Could not load native gpl library", t);   
  9.       nativeLibraryLoaded = false;   
  10.     }   
  11. }

2)获取了gplcompression后需要初始化加载以便可以调用,如果加载不成功,如我刚才说的版本冲突等也会报一系列错误.

同时这里的加载和初始化分成两步,一步是压缩,对应Java的类是LzoCompressor.另一步解压缩,对应Java的类是LzoDecompressor.先看下LzoCompressor是如何加载初始化的,代码如下:

  1. static {   
  2.   if (GPLNativeCodeLoader.isNativeCodeLoaded()) {   
  3.     // Initialize the native library   
  4.     try {   
  5.       initIDs();   
  6.       nativeLzoLoaded = true;   
  7.     } catch (Throwable t) {   
  8.       // Ignore failure to load/initialize native-lzo   
  9.       LOG.warn(t.toString());   
  10.       nativeLzoLoaded = false;   
  11.     }   
  12.     LZO_LIBRARY_VERSION = (nativeLzoLoaded) ? 0xFFFF & getLzoLibraryVersion()   
  13.         : -1;   
  14.   } else {   
  15.     LOG.error("Cannot load " + LzoCompressor.class.getName() +    
  16.     " without native-hadoop library!");   
  17.     nativeLzoLoaded = false;   
  18.     LZO_LIBRARY_VERSION = -1;   
  19.   }   
  20. }

如我这里所报的警告WARN lzo.LzoCompressor: java.lang.NoSuchFieldError: workingMemoryBuf

就是由这里的LOG.warn(t.toString());所抛出.同时这里也会先加载gplcompression,加载不成功同样会报without native-hadoop library!错误.

再看看解压缩LzoDecompressor,原理差不多,不再阐述,代码如下:

  1. static {   
  2.   if (GPLNativeCodeLoader.isNativeCodeLoaded()) {   
  3.     // Initialize the native library   
  4.     try {   
  5.       initIDs();   
  6.       nativeLzoLoaded = true;   
  7.     } catch (Throwable t) {   
  8.       // Ignore failure to load/initialize native-lzo   
  9.       LOG.warn(t.toString());   
  10.       nativeLzoLoaded = false;   
  11.     }   
  12.     LZO_LIBRARY_VERSION = (nativeLzoLoaded) ? 0xFFFF & getLzoLibraryVersion()   
  13.         : -1;   
  14.   } else {   
  15.     LOG.error("Cannot load " + LzoDecompressor.class.getName() +    
  16.     " without native-hadoop library!");   
  17.     nativeLzoLoaded = false;   
  18.     LZO_LIBRARY_VERSION = -1;   
  19.   }   
  20. }

以上基本包含了hadoop-lzo安装使用所遇到的问题.最后回到本文的主题,正确安装hadoop-lzo.

1)首先下载https://github.com/kevinweil/hadoop-lzo/,我这里下载到/home/guoyun/Downloads//home/guoyun/hadoop/kevinweil-hadoop-lzo-2dd49ec

2)通过ant生成native和jar,命令如下:

ant tar

在build目录下生成对应的tar包,解压缩后,进入该目录可以看到对应的jar包hadoop-lzo-0.4.14.jar.同时将lib/native/Linux-amd64-64/目录下所有文件拷贝到$HADOOP_HOME/lib和/usr/local/lib两个目录下.

注明:拷贝到/usr/local/lib是便于调试,如是生产环境则无需拷贝.

相关问答

更多
  • hadoop-examples-1.0.2.jar文件不在当前目录,建议使用全路径表述。比如: hadoop jar /home/hadoop/..../..../hadoop-examples-1.0.2.jar teragen ... ... hadoop jar /home/hadoop/..../..../hadoop-examples-1.0.2.jar terasort ... ... hadoop jar /home/hadoop/..../..../hadoop-examples-1.0.2 ...
  • 现在hadoop1.0都出了 简单说一下吧 你的java jdk的环境变量没有设置吧? 最好按以下步骤再做一遍: 1 用root用户安装jdk1.6以上 2 用root用户 创建hadoop用户 3 在hadoop用户下安装hadoop(你上面说的1到4) 4 修改/home/hadoop/.bash_profile将JDK和hadoop的环境变量设置好 5 安装ssh(伪集群也需要ssh)
  • 尝试运行: hduser@ubuntu:~$ /usr/local/hadoop/sbin/start-all.sh 由于start-all.sh和stop-all.sh位于sbin目录中,而hadoop二进制文件位于bin目录中。 还更新了.bashrc : export PATH = $ PATH:$ HADOOP_HOME / bin: $ HADOOP_HOME / sbin 这样你就可以直接访问start-all.sh Try to run : hduser@ubuntu:~$ /usr/loc ...
  • 有三个主要的混淆点: 当指针所指向的缓冲区不是以空字符结尾的字符串时,最好不要使用char *,因为它令人困惑。 strlen()只会给你一个以null结尾的字符串的长度,它不会给你内存中任意缓冲区的大小。 您需要在其他地方获取该信息。 传递给lzo1x_1_compress()的缓冲区实际上需要包含要压缩的数据,而不是包含零的空缓冲区。 假设你可以使用imageIn-> getFrameSizeBytes()之类的东西从imageIn获取图像的大小,试试这个: int r; lzo_bytep o ...
  • 如何用-c开关在子lzop中启动lzop二进制文件 ,然后逐行读取其STDOUT? How about starting an lzop binary in a subprocess with -c switch and then read its STDOUT line by line?
  • 看起来你正在使用hadoop的后级版本。 检查您的图形构建器版本所需的hadoop版本,并确保它是您正在运行的版本。 Looks like you're using a back level version of hadoop. Check the version of hadoop that your version of graph builder needs and make sure that's the version you're running.
  • 对我的第一个问题的简短回答: AWS不会自动编制索引。 我已经用自己的工作证实了这一点,并且在他们的论坛上也从Andrew @ AWS中读到了相同的内容。 以下是如何进行索引编制的方法: 要索引一些LZO文件,你需要使用我自己的从hadoop-lzo项目构建的Jar。 如果要直接使用EMR进行索引,则需要在某处构建Jar,然后上传到Amazon S3。 另外,Cloudera对在您自己的群集上进行此设置的所有步骤都有很好的说明。 我在我的本地群集上做了这个,这允许我构建Jar并上传到S3。 如果您不想自己构 ...
  • 因此,在hadoop世界之外没有可用的库来创建lzo和lzo索引文件。 这基本上让我们使用像hadoop-lzo这样的开源项目(调用native c ++ lzo library)和lzo-java(其中包含lzo压缩的java实现) So there aren't libraries readily available outside hadoop world to create lzo and lzo index files. Which basically leaves us to use open ...
  • 您错过了内容最后一行的回复。 你必须使用这样的条件来控制EOF: while (line = mycontent.readLine()) != null) { ... ... } ok, i finally find the answer , it is unbelievable , Through the Hbase gc log , i see a long full gc suggest , my hbase's heap size is default 1 gb , so it maybe occ ...
  • 我得到了与你相同的结果,最终这对我有用: export C_INCLUDE_PATH=/usr/local/Cellar/lzo/2.09/include/lzo:/usr/local/Cellar/lzo/2.09/include export LIBRARY_PATH=/usr/local/lib pip install python-lzo (显然,您可能需要调整这些,具体取决于您安装的lzo brew发行版的版本。) 哪个回答了我的问题,但我真的不明白为什么没有正确配置... 我也安装了Xco ...