二、Hadoop环境搭建

在阿里云服务器 ECS 上搭建 hadoop 的开发环境。
参考了林子雨老师的博客,推荐学习大数据的朋友可以看看,老师写的真好–>林子雨老师博客

1. 建立用户

1.1 hoopp

  1. 创建一个hp用户,用来学习 Hadoop

    # 建立用户
    sudo useradd -m hp -s /bin/bash
    # 建立密码
    sudo passwd hp
    # 增加权限
    sudo adduser hp sudo
    # 切换用户
    su hp
    # 更新软件目录
    sudo apt-get update
    
  2. 集群、单节点模式都需要 SSH 登录,配置 SSH 免密登录更加方便

    # 安装 SSH server
    sudo apt-get install openssh-server
    # 通过SSH登录本机,首次需要输入 yes
    ssh localhost
    # 退出刚才的 ssh localhost
    exit 
    # 进入.ssh 文件夹
    cd ~/.ssh/       
    # 会有提示,填写文件名需要修改 config,其余都按回车就可以
    ssh-keygen -t rsa        
    # 加入授权
    cat ./id_rsa.pub >> ./authorized_keys 
    # 由于 SSH 默认只会读取 id_rsa 这个私钥,所以我们需要为Hadoop_ssh私钥修改 config 配置
    ######################################
    					# 没改名字就不用 #
    ######################################
    vim config
    # 输入下列代码
    Host hp
        HostName mark3
        Port 22
        User hp
        IdentityFile  ~/.ssh/hadoop_ssh
        IdentitiesOnly yes
    # 测试
    ssh hp
    
  3. SSH 配置文件补充

    参考资料

    SSH 程序将从下面两个地方获取配置参数

    用户配置文件 (~/.ssh/config)
    系统配置文件 (/etc/ssh/ssh_config)

    Host 别名
    HostName 主机名
    Port 端口
    User 用户名
    IdentityFile 密钥文件的路径
    IdentitiesOnly 只接受SSH key 登录
    PreferredAuthentications 强制使用Public Key验证

2. Java

2.1 JDK1.8

2.2.1 手动安装

  1. 下载 Java 安装包jdk-8u162-linux-x64.tar.gz,点击这里下载

    # 创建/usr/lib/jvm目录用来存放JDK文件
    cd /usr/lib
    sudo mkdir jvm 
    # 进入安装包所在目录
    cd ~/Downloads 
    # 把JDK文件解压到/usr/lib/jvm目录下
    sudo tar -zxvf ./jdk-8u162-linux-x64.tar.gz -C /usr/lib/jvm  
    
  2. 设置环境变量

    # 编辑 bashrc 配置
    vim ~/.bashrc
    # 在文件开头添加下列四行
    export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_162
    export JRE_HOME=${JAVA_HOME}/jre
    export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
    export PATH=${JAVA_HOME}/bin:$PATH
    # 更新 bashrc 配置
    source ~/.bashrc
    # 测试 v9vapBWH8a_TGdsp
    java -version
    # 成功显示
    java version "1.8.0_162"
    

2.1.2 自动安装

sudo apt update
sudo apt install openjdk-8-jdk

2.2 JDK11

  1. 安装 openjdk

    # 更新软件包索引
    sudo apt update
    # 18.04系统默认为 jdk11
    sudo apt install default-jdk
    # 测试
    java -version
    

2.3 设置 Java 版本

# * 标识的即为默认版本,使用 enter 键选择
sudo update-alternatives --config java

2.4 JAVA_HOME 环境变量

应用程序需要通过JAVA_HOME环境变量来确定 Java 的安装位置。

  1. 找出 Java 安装路径

    sudo update-alternatives --config java
    
  2. 添加 Java 安装路径

    # 编辑配置文件(environment将对所有用户生效)
    sudo vim /etc/environment
    # 编辑配置文件(对当前用户生效)
    sudo vim ~/.bashrc
    
    # 上列配置文件二选一即可,在末尾添加
    JAVA_HOME="/usr/lib/jvm/java-11-openjdk-amd64"
    
    # 更新配置文件
    source /etc/environment
    
    # 测试
    echo $JAVA_HOME
    

2.5 卸载 jdk

sudo apt remove openjdk-11*

3. vscode

目前的想法是在服务器上通过 vscode 来编写代码。至于为什么不用由于 IDEA,当然是因为内存太小= =

3.1 安装 vscode

  1. 在官网下载安装包

  2. 安装 vscode

    cd ~/Downloads 
    sudo dpkg -i code_1.44.2-1587059832_amd64.deb 
    sudo apt-get -f install
    

3.2 配置 vscode

3.2.1 [可选]中文环境

  1. 按住 Shift+Ctrl+P,打开命令窗口,输入 language
  2. 选择 config display language
  3. 下载 简体中文包

3.2.2 Java 插件

  • Red Hat

    对 Maven/Gradle 项目的基本支持、代码格式化,代码重构、代码片段、语法高亮、代码自动补全等等核心功能,都在这个插件中。

  • Debugger for Java

    Debugger for Java 除了提供 Launch/Attach、断点/条件断点、Step In/Out/Over、Callstacks 这些基本功能,还支持 Logpoints、Hot Code Replace 等高级功能,使得调试 Java 项目如丝般顺滑。

  • Java Test Runner

    对主流的测试框架 JUnit 和 TestNG 都有着很好的支持。在 Test Explorer 中,可以方便地查看所有测试用例、运行/调试测试代码、查看测试报告。

  • Maven for Java

    基于 Maven Archetype 生成 Maven 项目、运行各种 Maven 命令,在 VS Code 中也能轻松地开发 Maven 项目。

  • Java Dependency Viewe

    可以方便地列出当前 Java 项目所有地依赖项,并且可以开始地创建一个 Java 项目。

4. Hadoop

2.1 安装 Hadoop

  1. 下载 Hadoop安装包 hadoop-3.1.3.tar.gz点击下载

  2. 安装 Hadoop

    # 解压到/usr/local中
    cd ~/Download
    sudo tar -zxvf ./hadoop-3.1.3.tar.gz -C /usr/local    
    cd /usr/local/
    # 将文件夹名改为hadoop
    sudo mv ./hadoop-3.1.3/ ./hadoop            
    # 修改文件权限
    sudo chown -R hadoop ./hadoop  
    # 测试
    /usr/local/hadoop/bin/hadoop version
    
  3. 配置环境变量

    # 编辑配置文件
    
    
    # 定义HADOOP_HOME变量,指向hadoop的安装根目录
    export HADOOP_HOME=/usr/local/hadoop
    export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
    # 将hadoop目录里的bin目录和sbin目录加载到PATH环境变量
    export PATH=${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:$PATH
    # 更新配置文件
    source ~/.bashrc
    

2.2 非分布式模式

Hadoop 默认模式为非分布式模式(本地模式),无需进行其他配置即可运行。非分布式即单 Java 进程,方便进行调试。

  1. 设置JAVA_HOME

    sudo vim /usr/local/hadoop/etc/hadoop/hadoop-env.sh
    # 1.8 改为
    export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_162
    # 11 改为
    export JAVA_HOME=${JAVA_HOME}
    
  2. 测试 Hadoop 的 grep 例子

    cd /usr/local/hadoop
    # 将配置文件作为输入文件
    mkdir ./input
    cp ./etc/hadoop/*.xml ./input   
    # 筛选当中符合正则表达式 dfs[a-z.]+ 的单词并统计出现的次数,最后输出结果到 output 文件夹中
    ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar grep ./input ./output 'dfs[a-z.]+'
    # 查看运行结果
    cat ./output/*          
    
  3. Hadoop 不会覆盖输出文件,所以再次执行案例不会成功,需要删除输出文件

    rm -r ./output
    
  4. 查看 Hadoop 的所有例子

    ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar 
    

2.3 伪分布式模式

Hadoop 可以在单节点上以伪分布式的方式运行,Hadoop 进程以分离的 Java 进程来运行,节点既作为 NameNode 也作为 DataNode,同时,读取的是 HDFS 中的文件。

Hadoop 的配置文件位于 /usr/local/hadoop/etc/hadoop/ 中,伪分布式需要修改2个配置文件 core-site.xmlhdfs-site.xml

Hadoop的配置文件是 xml 格式,每个配置以声明 property 的 name 和 value 的方式来实现。

2.3.1 修改配置文件

Hadoop配置文件说明

Hadoop 的运行方式是由配置文件决定的(运行 Hadoop 时会读取配置文件),因此如果需要从伪分布式模式切换回非分布式模式,需要删除 core-site.xml 中的配置项。

此外,伪分布式虽然只需要配置 fs.defaultFS 和 dfs.replication 就可以运行(官方教程如此),不过若没有配置 hadoop.tmp.dir 参数,则默认使用的临时目录为 /tmp/hadoo-hadoop,而这个目录在重启时有可能被系统清理掉,导致必须重新执行 format 才行。所以我们进行了设置,同时也指定 dfs.namenode.name.dirdfs.datanode.data.dir,否则在接下来的步骤中可能会出错。

  1. 修改 core-site.xml 文件

    • before

      <configuration>
      </configuration>
      
    • after

      <configuration>
          <property>
              <name>hadoop.tmp.dir</name>
              <value>file:/usr/local/hadoop/tmp</value>
              <description>Abase for other temporary directories.</description>
          </property>
          <property>
              <name>fs.defaultFS</name>
              <value>hdfs://localhost:9000</value>
          </property>
      </configuration>
      
  2. 修改 hdfs-site.xml 文件

    • before

      <configuration>
      </configuration>
      
    • after

      <configuration>
          <property>
              <name>dfs.replication</name>
              <value>1</value>
          </property>
          <property>
              <name>dfs.namenode.name.dir</name>
              <value>file:/usr/local/hadoop/tmp/dfs/name</value>
          </property>
          <property>
              <name>dfs.datanode.data.dir</name>
              <value>file:/usr/local/hadoop/tmp/dfs/data</value>
          </property>
      </configuration>
      
  3. 执行 NameNode 格式化

    cd /usr/local/hadoop
    # 格式化
    ./bin/hdfs namenode -format
    
    # 成功会看到
    SHUTDOWN_MSG: Shutting down NameNode 
    
  4. 开启 NameNode 和 DataNode 守护进程

    cd /usr/local/hadoop
    # start-dfs.sh是个完整的可执行文件,中间没有空格
    ./sbin/start-dfs.sh 
    # 检测是否成功(jps是jdk提供的一个查看当前java进程的小工具)
    jps
    # 输出
    9496 NameNode
    9643 DataNode
    10030 Jps
    9887 SecondaryNameNode
    

2.3.2 一些小坑

  1. 启动 Hadoop 时提示ssh: Could not resolve hostname

    这个并不是 ssh 的问题,可通过设置 Hadoop 环境变量来解决。首先按键盘的 ctrl + c 中断启动,然后在 ~/.bashrc 中,增加如下两行内容(设置过程与 JAVA_HOME 变量一样,其中 HADOOP_HOME 为 Hadoop 的安装目录):

    export HADOOP_HOME=/usr/local/hadoop
    export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
    

    保存后,务必执行 source ~/.bashrc 使变量设置生效,然后再次执行 ./sbin/start-dfs.sh 启动 Hadoop。

  2. Hadoop无法正常启动的解决方法

    一般可以查看启动日志来排查原因,注意几点:

    • 启动时会提示形如 “DBLab-XMU: starting namenode, logging to /usr/local/hadoop/logs/hadoop-hadoop-namenode-DBLab-XMU.out”,其中 DBLab-XMU 对应你的机器名,但其实启动日志信息是记录在 /usr/local/hadoop/logs/hadoop-hadoop-namenode-DBLab-XMU.log 中,所以应该查看这个后缀为 .log 的文件;
    • 每一次的启动日志都是追加在日志文件之后,所以得拉到最后面看,对比下记录的时间就知道了。
    • 一般出错的提示在最后面,通常是写着 Fatal、Error、Warning 或者 Java Exception 的地方。
    • 可以在网上搜索一下出错信息,看能否找到一些相关的解决方法。

    此外,若是 DataNode 没有启动,可尝试如下的方法(注意这会删除 HDFS 中原有的所有数据,如果原有的数据很重要请不要这样做):、

    # 针对 DataNode 没法启动的解决方法
    cd /usr/local/hadoop
    # 关闭
    ./sbin/stop-dfs.sh   
    # 删除 tmp 文件,注意这会删除 HDFS 中原有的所有数据
    rm -r ./tmp     
    # 重新格式化 NameNode
    ./bin/hdfs namenode -format   
    # 重启
    ./sbin/start-dfs.sh  
    

2.3.3 运行实例

  1. 上面的单机模式,grep 例子读取的是本地数据,伪分布式读取的则是 HDFS 上的数据。要使用 HDFS,首先需要在 HDFS 中创建用户目录:

    ./bin/hdfs dfs -mkdir -p /user/hp
    

    这里有三种shell命令方式。

    1. hadoop fs
    2. hadoop dfs
    3. hdfs dfs

    hadoop fs适用于任何不同的文件系统,比如本地文件系统和HDFS文件系统
    hadoop dfs只能适用于HDFS文件系统
    hdfs dfs跟hadoop dfs的命令作用一样,也只能适用于HDFS文件系统

  2. 接着将 ./etc/hadoop 中的 xml 文件作为输入文件复制到分布式文件系统中,即将 /usr/local/hadoop/etc/hadoop 复制到分布式文件系统中的 /user/hp/input 中。我们使用的是 hp 用户,并且已创建相应的用户目录 /user/hp ,因此在命令中就可以使用相对路径如 input,其对应的绝对路径就是 /user/hp/input:

    # 创建输入目录,绝对路径为/user/hp/input
    ./bin/hdfs dfs -mkdir -p input
    # 将 xml 复制到输入目录
    ./bin/hdfs dfs -put ./etc/hadoop/*.xml input
    # 查看文件列表
    ./bin/hdfs dfs -ls input
    
  3. 运行实例。伪分布式运行 MapReduce 作业的方式跟单机模式相同,区别在于伪分布式读取的是HDFS中的文件(可以将单机步骤中创建的本地 input 文件夹,输出结果 output 文件夹都删掉来验证这一点)。

    # 运行实例
    ./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar grep input output 'dfs[a-z.]+'
    
    # 查看结果(查看的是位于 HDFS 中的输出结果)
    ./bin/hdfs dfs -cat output/*
    
    			# 查看结果(取回本地查看)#
    # 先删除本地的 output 文件夹(如果存在)
    rm -r ./output    
    # 将 HDFS 上的 output 文件夹拷贝到本机
    ./bin/hdfs dfs -get output ./output 
    # 查看
    cat ./output/*
    
    # 再次运行需要删除 output
    ./bin/hdfs dfs -rm -r output   
    
  4. 运行 Hadoop 程序时,为了防止覆盖结果,程序指定的输出目录(如 output)不能存在,否则会提示错误,因此运行前需要先删除输出目录。在实际开发应用程序时,可考虑在程序中加上如下代码,能在每次运行时自动删除输出目录,避免繁琐的命令行操作:

    Configuration conf = new Configuration();
    Job job = new Job(conf);
     
    /* 删除输出目录 */
    Path outputPath = new Path(args[1]);
    outputPath.getFileSystem(conf).delete(outputPath, true);
    
  5. 关闭 Hadoop

    ./sbin/stop-dfs.sh
    
  6. 启动 Hadoop

    ./sbin/start-dfs.sh 
    
  7. 启动成功后还可在web 端查看

    http://localhost:9870

2.4 Hadoop 集群

暂时学习使用伪分布式足矣,集群待入门之后再来更新。