Hadoop的编译-部署-启动脚本

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的编译注意事项:

  1. 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

  1. 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
  1. 编译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下载和编译

  1. 从apache下载源码和预编译包
  • https://archive.apache.org/dist/hadoop/common/hadoop-2.7.1/
  1. yum 安装各种依赖
yum -y install gcc-c++ build-essential autoconf automake libtool cmake zlib1g-dev pkg-config libssl-devua svn openssl-devel ncurses-devel
  1. 安装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
  1. 下载安装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
  1. 下载安装ProtocolBuffer

  2. 运行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 命令

  1. 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()中跑 ExampleDriver

关于RunJar.main() 中classPath的问题


ClassPath 的ClassLoader的问题

classLoader里 ucp的字段值; 是 jarFile对应的值;
其中的partent字段,应该就是 bin/hadoop脚本中 ClassPath的

你可能感兴趣的:(Hadoop的编译-部署-启动脚本)