Hadoop的Linux 一般编译环境
1. yum 安装各种准备命令
yum install svn
# GUN操作系统的编译和安装工具
yum install autoconfautomake libtool cmake
yum install -y lzo-devel zlib-devel libtool
yum install ncurses-devel
# 安全通信协议
yum install openssl-devel
// 安装重要的压缩命令
yum install -y snappy snappy-devel
yum install gcc*
2. 下载protocol buffer, 2.5.0以上
Hadoop使用protocol buffer进行通信
- 下载地址: https://github.com/protocolbuffers/protobuf/releases/download/v2.5.0/protobuf-2.5.0.tar.gz
- 解压后在protobuf-2.5.0/下直接运行其
cd protobuf-2.5.0
./configure
make
make check
sudo make install
protoc --version 检查版本
3. 安装 findbugs 3.0.1 以上
下载
- https://nchc.dl.sourceforge.net/project/findbugs/findbugs/3.0.1/findbugs-3.0.1.tar.gz
sudo vim /etc/profile
export FINDBUGS_HOME=/home/app/softpkg/hadoop-compile/findbugs-3.0.1
export PATH=$FINDBUGS_HOME/bin:$PATH
// source 一下后, 测试下findbugs命令:
findbugs -version
4. 安装cmake命令: 3.6 以上;
Linux yum安装的cmake 最高只有3.1版本, 没有3.6的. 需要自己安装:
- 直接安装预编译包 /配置环境
- 下载cmake源码包, 自己编译
1. 下载预编译包; 直接安装/ 配置环境变量
* 地址: https://cmake.org/files/v3.13/cmake-3.13.1-Linux-x86_64.tar.gz
tar -xvf
vim /etc/profile
export CMAKE_HOME=
export PATH=$CMAKE_HOME/bin:$PATH
// 测试cmake 命令
cmake -version
2. 下载源码包, 编译: 省略
* https://codeload.github.com/Kitware/CMake/zip/v3.13.1
./configure
sudo make && make install
cmake -version
5. 编译hadoop源码
cd hadoop-src
mvn clean package -DskipTests -Dtar -Pdist,native
Hadoop-2.6.0-cdh-2.16.2的编译注意事项:
- java版本的问题, 把pom中的 javaVersion属性改为1.8(默认1.7);
plugins.enforcer.RequireJavaVersion failed with message:
Detected JDK Version: 1.8.0-171 is not in the allowed range [1.7.0,1.7.1000}]
1.8
1.8
- hadoop-common-project\hadoop-annotations 中报错
[ERROR] E:\ws\ws-idea\hadoop-source\hadoop-2.6.0-cdh5.16.2\hadoop-common-project\hadoop-annotations\src\main\java\org\apache\hadoop\classification\tools\ExcludePrivateAnnotationsStandardDoclet.java:[34,16] 错误: 找不到符号
[ERROR] 符号: 类 LanguageVersion
位置: 类 ExcludePrivateAnnotationsStandardDoclet
E:\ws\ws-idea\hadoop-source\hadoop-2.6.0-cdh5.16.2\hadoop-common-project\hadoop-annotations\src\main\java\org\apache\hadoop\classification\tools\ExcludePrivateAnnotationsStandardDoclet.java:[38,30] 错误: 找不到符号
[ERROR] 符号: 类 RootDoc
位置: 类 ExcludePrivateAnnotationsStandardDoclet
- 编译Hadoop的源码
参考 https://blog.csdn.net/tvpbvt/article/details/23843575 解决源码总相关BUG
- hadoop-2.2.0-src\hadoop-common-project\hadoop-auth\pom.xml新增 jetty-util
- hadoop-2.2.0-src/hadoop-project/pom.xml文件,新增
-Xdoclint:-html :
1 . hadoop-auth\pom.xml新增 jetty-util依赖
org.mortbay.jetty
jetty-util
test
2. hadoop-project/pom.xml: maven-javadoc-plugin 中增加 -Xdoclint:-html
org.apache.maven.plugins
maven-javadoc-plugin
...
${project.build.directory}
-Xdoclint:-html
mvn package -Pdist,native -DskipTests -Dtar
用 hadoop-2.2.0-src/hadoop-dist/target/hadoop-2.2.0/lib/native 替换掉 hadoop-2.2.0/lib/native
替代掉以后, 执行检查
./bin/hdfs getconf -namenodes
ldsver42,这下就对了!
把编译出来的native包, 替换原来的native包
编译报错解决:
[WARNING] [protoc, --version] failed: java.io.IOException: Cannot run program "protoc": error=2, 没有那个文件或目录
原因分析, 是因为protobuf还没有按照, 依据上面步骤按照并make install 即可.
Hadoop-2.7.1下载和编译
- 从apache下载源码和预编译包
- https://archive.apache.org/dist/hadoop/common/hadoop-2.7.1/
- yum 安装各种依赖
yum -y install gcc-c++ build-essential autoconf automake libtool cmake zlib1g-dev pkg-config libssl-devua svn openssl-devel ncurses-devel
- 安装FindBugs组件,
- 下载 findbugs-3.0.1.tar.gz: http://findbugs.sourceforge.net/downloads.html
- 安装到linxu上并配置环境变量;
在 /etc/profile 文件末尾添加:
export FINDBUGS_HOME=/opt/findbugs-3.0.1
export PATH=$PATH:$FINDBUGS_HOME/bin
# 验证findbugs 版本
findbugs -version
- 下载安装snappy
- 下载 snappy-1.1.3.tar.gz(预编译包,非源码包): https://src.fedoraproject.org/repo/pkgs/snappy/
- 编译和安装
./configurte
make -j 4 # -j 以4核同时编译
make install # 安装命令
# 查看按照到/usr/local/lib下的snappy包
ls -lh /usr/local/lib |grep snappy
下载安装ProtocolBuffer
运行Mvn命令 编译hadoop源码
mvn clean package -Pdist,native -DskipTests -Dtar -Dsnappy.lib=/usr/local/lib -Db
undle.snappy
# 如果中途编译失败,并且不要文档的话,请使用这个命令
mvn clear package -Pdist,native -DskipTests -Dtar -Dsnappy.lib=/usr/local/lib -Dbundle.snappy -Drequire.openssl
Hadoop 的部署
新环境Linux基本配置
关闭selinux
vim /etc/selinux/config
-> SELINUX=disabled
关闭firewalld防火墙
systemctl stop firewalld
systemctl disable firewalld
设置主机网络同步, 辅机与主机同步
tzselect //选择时区
// 1. Contos7默认是以chrony服务作为时间同步的, 不建议用ntp;
yum list installed |grep chrony //先检查是否已安装chrony包
systemctl list-units |grep chrony //查看是否已安装chrony服务;
systemctl status chronyd // 查看chronyd服务状态;
//若没有chrony服务, 安装并开机启动
yum -y install chrony
systemctl enable chronyd
systemctl start chronyd
// 编辑同步时间的服务器
vim /etc/chrony.conf
# 作为时间服务主节点, 从网络同步时间:
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server time1.aliyun.com iburst
server time2.aliyun.com iburst
server time5.aliyun.com iburst
server time.windows.com iburst
# Slave节点打开一下配置, 从ldsver55节点同步时间;
#server ldsver55 iburst
#server 192.168.51.151 iburst
chronyc sources -v //查看时间源
chronyc sourcestats -v //查看时间源状态
timedatectl set-ntp yes //启用NTP时间同步
chronyc tracking //校验时间
chronyc activity //显示有多少NTP源在线/离线
timedatectl //查看系统时间和时区;
rpm -q ntp // 检测ntp服务是否
// 若需要删除已安装的ntp包
rpm -qa | grep -i ntp
yum remove -y ntp-4.2.6p5-29.el7.centos.2.x86_64 // 先查看该包, 再移除该包名
yum remove -y ntp.x86_64
yum remove -y ntpdate
// 2. 安装ntp服务作为时间同步, 若安装ntpd,则需要先卸载chrony服务;
systemctl list-units --type=service |grep ntp // 查看是否已经安装/禁用ntpd服务;
systemctl status ntpd
systemctl enable ntpd
systemctl start ntpd
//重启后插卡ntpd服务是否自动重启;
集群安装
配置环境变量: hadoop-env.sh
主要配置 .bashrc 和 hadoop-env.sh的环境变量;
总结: 把不在默认HADOOP_HOME目录下的环境变量,都需要重新设置下目录;
vim ~/.bashrc
vim hadoop-env.sh
# 配置基本Home目录
export JAVA_HOME=/usr/java/jdk-release
export HADOOP_HOME=/home/bigdata/app/hadoop-release
# 配置CONF_DIR目录
export HADOOP_CONF_DIR=/home/bigdata/data/hadoop/conf
export YARN_CONF_DIR=${HADOOP_CONF_DIR}
export HADOOP_MAPRED_CONF_DIR=${HADOOP_CONF_DIR}
# 配置pid目录
export HADOOP_PID_DIR=/home/bigdata/data/hadoop/pid/hdfs
export YARN_PID_DIR=/home/bigdata/data/hadoop/pid/yarn
export HADOOP_MAPRED_PID_DIR=/home/bigdata/data/hadoop/pid/mapred
# 配置日志目录
export HADOOP_LOG_DIR=/home/bigdata/log/hadoop/hdfs
export YARN_LOG_DIR=/home/bigdata/log/hadoop/yarn
export HADOOP_MAPRED_LOG_DIR=/home/bigdata/log/hadoop/madred
启动mr-jobhistory
开启hadoop和 yarn的 jobhistory服务
1. mapred-site.xml 中设置history的端口;
mapreduce.jobhistory.address
0.0.0.0:10020
mapreduce.jobhistory.webapp.address
0.0.0.0:19888
// 2. 配置开启yarn的history日志: vim yarn-site.xml
yarn.log-aggregation-enable
true
yarn.log-aggregation.retain-seconds
172800
yarn.nodemanager.log-aggregation.compression-type
gz
yarn.nodemanager.local-dirs
${hadoop.tmp.dir}/nm-local-dir
yarn.resourcemanager.max-completed-applications
100
// 设置jobhistory的堆大小,最好不要乱设置,采用默认的;
// export HADOOP_JOB_HISTORYSERVER_HEAPSIZE=2000
// 启动historyserver
mr-jobhistory-daemon.sh start historyserver
// 停止 history Server
mr-jobhistory-daemon.sh stop historyserver
当把HADOOP_CONF_DIR的配置目录更改后, jobhistory的服务好像运行异常:
查看其脚本:
// 先执行那个 mapred-confi.sh 加载mr的环境变量;
. $HADOOP_LIBEXEC_DIR/mapred-config.sh
// 定义日志文件和pid
log=$HADOOP_MAPRED_LOG_DIR/mapred-$HADOOP_MAPRED_IDENT_STRING-$command-$HOSTNAME.out
pid=$HADOOP_MAPRED_PID_DIR/mapred-$HADOOP_MAPRED_IDENT_STRING-$command.pid
// 最总启动命令:
nohup nice -n $HADOOP_MAPRED_NICENESS "$HADOOP_MAPRED_HOME"/bin/mapred --config $HADOOP_CONF_DIR $command "$@" > "$log" 2>&1 < /dev/null &
nohup nice -n 0 /home/bigdata/app/hadoop-2.6.0-cdh5.16.2/bin/mapred --config /home/bigdata/data/hadoop/conf historyserver > /home/bigdata/app/hadoop-2.6.0-cdh5.16.2/logs/mapred-bigdata-historyserver-ldsver55.out
starting historyserver, logging to /home/bigdata/app/hadoop-2.6.0-cdh5.16.2/logs/mapred-bigdata-historyserver-ldsver55.out
其中log=HADOOP_MAPRED_IDENT_STRING-HOSTNAME.out
很容易出问题: 就是 HADOOP_MAPRED_LOG_DIR 的环境变量问题;
重置HADOOP_CONF_DIR在独立目录
要重置hadoop_conf_dir在其他目录, 需要
设置环境 .bashrc中 HADOOP_CONF_DIR的目录;
// 1. 设置 shell环境变量;
vim ~/.bashrc
export HADOOP_CONF_DIR=/home/bigdata/data/hadoop/conf
export YARN_CONF_DIR=/home/bigdata/data/hadoop/conf
// 2. 设置hadoop-env.sh, yarn-env.sh
export HADOOP_CONF_DIR=/home/bigdata/data/hadoop/conf
export YARN_CONF_DIR=/home/bigdata/data/hadoop/conf
// 3. 设置 libexec下的hadoop-config.sh
vim libexec/hadoop-config.sh
export HADOOP_CONF_DIR=/home/bigdata/data/hadoop/conf
export YARN_CONF_DIR=/home/bigdata/data/hadoop/conf
给MapReducer添加 spark-shuffle组件
vim yarn-site.xml
yarn.nodemanager.aux-services
mapreduce_shuffle,spark_shuffle
yarn.nodemanager.aux-services.mapreduce.shuffle.class
org.apache.hadoop.mapred.ShuffleHandler
yarn.nodemanager.aux-services.spark_shuffle.class
org.apache.spark.network.yarn.YarnShuffleService
加上spark-shuffle以后, 还需要copy SPARK_HOME/yarn下面的shuffle.jar包到 $HADOOP_HOME/share/hadoop/mapreduce2/这个目录中来;
采用本地native-lib
Hadoop 各种脚本
Hadoop jar 命令
- bin/hadoop 的Hadoop命令脚本
// 这里导入Classpath作为环境变量; 应该是后面的 RunJar中会自动加载该$CLASSPATH到其环境变量中;
export CLASSPATH=$CLASSPATH
echo "hadoop shell: $JAVA $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS $@ "
exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
// 对于hadoop jar jarFile className
java -Xmx1000m -Xmx512m \
-agentlib:jdwp=transport=dt_socket,server=n,suspend=n,address=192.168.51.1:45040 \
-Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=/home/bigdata/log/hadoop -Dhadoop.log.file=hadoop.log \
-Dhadoop.home.dir=/home/bigdata/app/hadoop-2.6.0-cdh5.16.2 -Dhadoop.id.str=bigdata -Dhadoop.root.logger=INFO,console \
-Djava.library.path=/home/bigdata/app/hadoop-release/lib/native -Dhadoop.policy.file=hadoop-policy.xml \
-Djava.net.preferIPv4Stack=true -Dhadoop.security.logger=INFO,NullAppender \
org.apache.hadoop.util.RunJar /home/bigdata/app/hadoop-release/share/hadoop/mapreduce2/hadoop-mapreduce-examples-2.6.0-cdh5.16.2.jar pi 2 2
RunJar 的参数
RunJar.main()方法的源码
RunJar.main(String[] args) {
new RunJar().run(args);{//参数第一个是 JarFile ;
String usage = "RunJar jarFile [mainClass] args...";
if (args.length < 1) {
System.exit(-1);
}
int firstArg = 0;
String fileName = args[firstArg++];
File file = new File(fileName);
if (!file.exists() || !file.isFile()) {
System.err.println("Not a valid JAR: " + file.getCanonicalPath());
System.exit(-1);
}
JarFile jarFile =new JarFile(fileName);
// 确定mainClass, 优先从Jar中的Mainifest获取mainClass,其从从第二个参数
String mainClassName = null;
Manifest manifest = jarFile.getManifest();
if (manifest != null) {
mainClassName = manifest.getMainAttributes().getValue("Main-Class");
}
jarFile.close();
if (mainClassName == null) { //当Jar.Mainifest 没有时,尝试从第二个args参数解析;
if (args.length < 2) {
System.err.println(usage);
System.exit(-1);
}
mainClassName = args[firstArg++];
}
mainClassName = mainClassName.replaceAll("/", ".");
File workDir = File.createTempFile("hadoop-unjar", "", new File(System.getProperty("java.io.tmpdir"))); //Java应用临时目录;
if (!workDir.delete()) {
System.err.println("Delete failed for " + workDir);
System.exit(-1);
}
ensureDirectory(workDir);
ShutdownHookManager.get().addShutdownHook( //钩子函数,保证wordDir能被完成删除;
new Runnable() {
@Override
public void run() {FileUtil.fullyDelete(workDir);}
}, SHUTDOWN_HOOK_PRIORITY);
unJar(file, workDir);
ClassLoader loader = createClassLoader(file, workDir);
Thread.currentThread().setContextClassLoader(loader);
// 定义mainClass 和 Dirver的main()方法, args参数;
Class> mainClass = Class.forName(mainClassName, true, loader);
Method main = mainClass.getMethod("main", new Class[] {
Array.newInstance(String.class, 0).getClass()
});
String[] newArgs = Arrays.asList(args).subList(firstArg, args.length).toArray(new String[0]);
// 执行用户定义的UserDriver.main()方法
main.invoke(null, new Object[] { newArgs });
}
}
命令的记录:
关于RunJar.main() 中classPath的问题
classLoader里 ucp的字段值; 是 jarFile对应的值;
其中的partent字段,应该就是 bin/hadoop脚本中 ClassPath的