在 Mac OS X 上编译 native-hadoop library

一般大家在安装完 Hadoop 后运行相关的命令,都会看到这样一个警告

1
WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

意思也就是加载不了 Hadoop 的本地库,这个问题不解决也不影响 Hadoop 的功能,因为它在加载不了本地库的情况下会去加载对应的 Java 代码库。
可是对应的 Java 实现的效率肯定不如本地库的,另外肯定有人像我一样,每次执行命令时看到这个 WARN 就感觉闹心,那就让我们来消灭这个警告。

先记录一下我在 Mac OS X 上的解决过程:
1、 需要 JDK、Maven 环境,用 Java 的人都有
2、 需要 protobuf
这里需要注意,protobuf 的版本需要为 2.5.0 的,比如我本来用的是 proto3,就出错了

1
[ERROR] Failed to execute goal org.apache.hadoop:hadoop-maven-plugins:2.7.1:protoc (compile-protoc) on project hadoop-common: org.apache.maven.plugin.MojoExecutionException: protoc version is 'libprotoc 3.0.0', expected version is '2.5.0' -> [Help 1]
1
2
3
4
$ cd protobuf-2.5.0-src
./configure --prefix=/dev/protobuf-2.5.0
$ make
$ make install

将 protobuf 放进环境变量

1
$ export PATH=/dev/protobuf-2.5.0/bin:$PATH

验证是是否安装成功

1
2
$ protoc --version
libprotoc 2.5.0

3、 下载 hadoop 对应版本的源码包,解压,然后使用 Maven 编译打包

1
2
$ cd hadoop-x.y.z-src
$ mvn package -Pdist,native -DskipTests -Dtar

p.s. 如果编译过程中因为墙而无法下载到某些依赖的 jar 包,可以在 Maven 中增加一个国内的公共库

1
2
3
4
5
6
7
<!-- ~/.m2/settings.xml -->
<mirror>
<id>nexus-osc</id>
<mirrorOf>central</mirrorOf>
<name>Nexus osc</name>
<url>http://maven.oschina.net/groups/public/</url>
</mirror>

如果一切顺利的话(当然这不太可能),编译好的包在hadoop-dist/target中,拷贝到hadoop/lib/native中,在运行 hadoop 的命令就没那烦人的警告了

1
$ cp hadoop-dist/target/hadoop-x.y.z/lib/native/* /dev/hadoop/lib/native

编译过程中可能会遇到以下问题:

1
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (make) on project hadoop-common: An Ant BuildException has occured: Execute failed: java.io.IOException: Cannot run program "cmake" (in directory "/Users/yibo/software/DevProgram/releases/hadoop-2.7.1-src/hadoop-common-project/hadoop-common/target/native"): error=2, No such file or directory

解决办法:

1
$ brew install cmake


1
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-antrun-plugin:1.7:run (make) on project hadoop-pipes: An Ant BuildException has occured: exec returned: 1

解决办法:

1
2
3
$ sudo port -v selfupdate
$ sudo port install ncurses
$ sudo port install openssl

注意,这里用brew install openssl不行,它只安装了openssl,没有安装openssl-devel,必须用 MacPorts 安装(需要梯子)。

最后捎带说一下 Linux 上的解决办法。
关于 Linux 上的这个警告的原因,网上有两种说法:

  1. Hadoop pre-build 版本带 native 库默认是 32 位的(未求证),而大家现在用的系统肯定都是 64 位的了,所以导致加载不了。
    这些网友给出的解决方案是去 http://dl.bintray.com/sequenceiq/sequenceiq-bin/ 下载对应版本的 tar 包解压后覆盖hadoop/lib/native/
    因为我采用的是第二种方法,所以该方案并未求证。
  2. glibc 需要升级。我是升级了 glibc(2.12 -> 2.14)后解决了这个问题,方法如下。
    tips: 升级 glibc 有风险,请谨慎
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ ll /lib64/libc.so.6    //先查看当前系统的 glibc 版本
    lrwxrwxrwx 1 root root 12 Jan 21 16:20 /lib64/libc.so.6 -> libc-2.12.so // 2.12
    $ export HADOOP_ROOT_LOGGER=DEBUG,console
    $ hadoop fs -ls /
    //此时会输出 debug 信息,找出 hadoop 需要的 glibc 版本,我这里需要的是 2.14
    //在 http://ftp.gnu.org/gnu/glibc/ 下载对应版本的 glibc,解压
    //在 ./configure 之前需要另外建立一个新目录作为编译的目录,否则报错
    $ mkdir glibc-2.14/glibc-build
    $ cd glibc-2.14/glibc-build
    $ ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
    $ make
    $ make install
    $ ll /lib64/libc.so.6
    lrwxrwxrwx 1 root root 12 Jan 21 16:20 /lib64/libc.so.6 -> libc-2.14.so