在自己的Macbook pro上配置了Hadoop伪分布式系统,用java写word count程序,运行成功,请参考《在Mac OS上配置Hadoop伪分布式环境》(见 )和《在伪分布式Hadoop上手把手实践word count程序》(见 )。不过我主要编程语言是c/c++,还是很有冲动用c/c++写hadoop程序的。
c/c++程序在hadoop上通过pipes的机制来运行,pipes主要是通过网络套接字的方式将c/c++程序与java虚拟机进行交互。理论的部分我就不多说了,即便说也没有书上说的好。在coding的时候,c/c++程序要用到pipes的方法,这些方法通过静态库和动态库来实现。我在编译c/c++程序的时候遇到了麻烦,错误信息提示:这些pipes的方法全都未定义,指定的静态库的版本与当前系统不兼容。思考之后得出原因,这些库都是为linux环境编译的,虽然macos也是unix内核,不过macos的静态库、动态库的二进制格式以及加载方式都和linux上面的不一样。想要编译成功,必须在macos环境下重新编译这些库。好在hadoop是开源的,都有源代码。接下来做下笔记,说说都是怎么做的。
先说一下我的macos环境,安装的最新的moutain lion,10.8.1。hadoop是hadoop-0.20.2版本。
编译hadoop java库很容易,用ant就可以。即cd到hadoop home目录下,在terminal中输入
ant
会自动根据build.xml中的配置进行编译。编译的时间较长。一般都能编译成功。不过这个并不包含pipes的几个库。为了编译pipes的几个库,我在网上也搜了好久,baidu、sogou、google都用了,最后还是google给了一丝线索,在著名的stack overflow论坛上,有人提到相关的话题。总之,尝试了下,方法是work的。还是cd到hadoop home目录下,输入如下命令
ant -Dcompile.c++=true -Dpipes=true compile-c++-pipes
ant的几个参数,大家看意思都能猜个大概。输入这个命令之后,就开始编译了。但是,会出现编译错误,原因是相关脚本install-sh和ltmain.sh当前用户没有执行权限,这些脚本都在“hadoop-0.20.2/src/c++/pipes/”目录下。也不管那么多了,chmod 777 install-sh将这些脚本的所有权限都给打开了(linux还是用的不熟,求快了)。同时,pipes还会依赖utils,里面也有两个同名的脚本,将他们的权限也都改过来。然后再运行,大概4-5s的样子,就编译成功了。生成的文件放在“hadoop-0.20.2/build/c++/Mac_OS_X-x86_64-64/”目录下。
可以对比一下“hadoop-0.20.2/c++/Linux-i386-32/lib”中的内容。发现hdfs还没有编译。继续在hadoop home目录下,在terminal中输入
ant -Dcompile.c++=true -Dlibhdfs=true compile-c++-libhdfs
来编译hdfs的静态库。此时会有错误信息,如下:
[exec] /Volumes/Data/hadoop-0.20.2/src/c++/libhdfs/hdfsJniHelper.c:18:19: error: error.h: No such file or directory
linux中定义变量errno取值的文件,在macos中没有同名文件。用编辑器编辑hdfsJniHelper.c,将 “#include <error.h>” 一行注释掉。就可以编译通过。最后,将“hadoop-0.20.2/build/c++/Mac_OS_X-x86_64-64/”拷贝到“hadoop-0.20.2/c++/Mac_OS_X-x86_64-64/”中,这里才是使用这些库的地方。
在MacOS上写c/c++程序,需要注意的是,在makefile中一定要指明是64位编译(加入参数 ‘-m64’),否则还是会编译不过的。以上pipes的静态库都是默认在64位下编译的。
另外,还可以编译hadoop自带的c++的例子,如word count等,命令为
ant -Dcompile.c++=yes examples
ant通过build.xml中的配置来找到源文件的位置进行编译。