一、背景
dfs-fuse,可以将hdfs上的目录挂载到本地的目录,就可以直接通过linux的命令直接访问hdfs上的数据
大多数云上的hadoop环境,或者下载别人编译好的包中,并没有fuse的相关脚本和命令
因此我们要自己编译hadoop
我是基于Hadoop2.8.5编译的
hadoop编译中,遇到的问题还是挺多的,而且要安装一些其他的服务,会在本文中逐一说明
二、准备环境
hadoop的源码根目录下有个:BUILDING.txt
里面详细描述了,需要什么环境
1、cmake,protobuf的前置环境
安装cmake和protobuf的时候,需要autoconf,否则会失败(找不到命令),因此先执行以下的yum命令安装相关环境
yum install autoconf automake libtool ncurses-devel
yum install gcc-c++
2、安装cmake
我发现yum安装的版本太低了,所以直接到git上下载3.15.0版本
cmake-3.15.0.tar.gz
https://github.com/Kitware/CMake/releases
Linux下安装cmake步骤详解(图文)_黄先森的博客-CSDN博客_cmake 安装
依次执行命令:
cd cmake-3.15.0
./bootstrap
gmake
make install
cmake --version
3、安装protobuf
hadoop大量用了google的protobuf(在各个组件项目传递信息的模块,nn向dn发信息等等,源码里就能看到)
https://github.com/protocolbuffers/protobuf/releases
protobuf-2.5.0.zip
(我原来是安装3.19.0的版本,结果maven编译的时候,报错提示使用低于2.5.0,所以我索性就又装了一个2.5.0)
安装步骤:
(1)、修改autogen.sh的内容
autogen.sh中有一段下载gtest的命令,但是基本是下不到的,所以替换成从github上下载
原来:
curl http://googletest.googlecode.com/files/gtest-1.5.0.tar.bz2 | tar jx
mv gtest-1.5.0 gtest
替换成:
wget https://github.com/google/googletest/archive/release-1.5.0.tar.gz
tar xzvf release-1.5.0.tar.gz
mv googletest-release-1.5.0 gtest
(2)、依次执行命令
执行./autogen.sh
./configure --prefix=/usr/local/protobuf
看到某些文档会让你写 --prefix=/usr/local/protobuf,但其实不需要,有默认路径,如果不按照默认路径来,后面还要配环境变量,不然会遇到protoc命令找不到
make
make check
这一步才是实际安装
make install
protoc --version
4、安装maven
因为编译hadoop源码需要maven
yum -y install maven
5、安装linux-fuse
如果编译dfs-fuse,需要有linux的fuse
yum install fuse-devel
三、编译hadoop
1、下载hadoop源码
2、解压,进入hadoop源码根目录
unzip hadoop-branch-2.8.5.zip
cd hadoop-branch-2.8.5
3、编译
mvn -X package -Pnative -Drequire.fuse=true -DskipTests -Dmaven.javadoc.skip=true
-Drequire.fuse=true 这段是必须的,否则编译完之后,还是没有fuse相关的脚本
-X会打印详细的编译信息,当有报错的时候,请往上翻,看maven之前的报错是什么
比如下面这个,maven的报错中有明显的信息,但是大多数情况下maven的报错可能是没有明细信息的,得往上翻,找到实际的报错是什么
编译是时候其实主要遇到的问题就是cmake,protobuf不存在或者版本问题等
然后我遇到了make的报错(这个报错的因为我先安装了高版本的cmake,然后又装了低版本,相互有冲突导致的,后来我重新找了个干净的环境编译,一下就成功了)
然后有什么报错就百度,解什么报错,正常情况下,上面的环境安装的都是对的,不会有什么奇怪的报错的
之后在如下路径里就能找到dfs_fuse命令
$HADOOP_HOME/hadoop-hdfs-project/hadoop-hdfs-native-client/target/main/native/fuse-dfs
四、挂载
1、前置准备
创建一个目录,把fuse_dfs和fuse_dfs_wrapper.sh这两个文件放一起
fuse_dfs是编译后生成的文件,fuse_dfs_wrapper.sh可以在源码里面找到
当然可以使用find / -name fuse_dfs_wrapper.sh 搜索
修改fuse_dfs_wrapper.sh的内容,添加上hadoop相关环境变量
阿里云EMR的hadoop相关环境变量都在/etc/profile.d/hdfs.sh所以先source
接着要设置HADOOP_PREFIX,这是编译过的源码包的地址,会加载fuse相关环境,甚至hadoop-hdfs-project的环境变量
2、执行挂载命令
9000端口是因为我的机器是单header,namenode只有一台,如果是多台的话,写namespace
##如果需要debug,请使用-d参数: ./fuse_dfs_wrapper.sh dfs://0.0.0.0:9000 /root/test/ -d
3、相关报错
(1)、error while loading shared libraries: libjvm.so: cannot open shared object file: No such file or directory
loading shared libraries: libjvm.so错误_在路上-CSDN博客_libjvm.so
这个报错其实是一些so文件没加载到,可以find命令查下机器上是否有(你编译的那台机器,一般都会有的)
可以把相关so的路径加到/etc/ld.so.conf中,然后可以使用ldconfig -v 来查看哪个目录加载到了哪些so,这个配置文件中只需要写路径就行,不需要通配符,不需要指定到具体的某个so!!
(2)、请注意,一定要用fuse_dfs_wrapper.sh脚本挂载,因为该脚本中会加载一些jar和环境,如果直接用fuse_dfs挂载,会显示挂载成功,但是显示Transport endpoint is not connected
(3)、<符号异常
类似如下报错
可能是我不小心改动了use_dfs_wrapper.sh中红框的内容,导致shell命令执行失败,后来我把报错行删了,重新写了下,就成功了
如下两个classpath非常关键,我尝试过注释掉,会导致Transport endpoint is not connected
五、推荐博客
网上很多博客,hadoop版本都太低了,参考价值比较低,但我还是找到了几篇确实很有用的文章,分享给大家: