二、Hadoop环境搭建
在阿里云服务器 ECS 上搭建 hadoop 的开发环境。
参考了林子雨老师的博客,推荐学习大数据的朋友可以看看,老师写的真好–>林子雨老师博客
1. 建立用户
1.1 hoopp
-
创建一个
hp
用户,用来学习 Hadoop# 建立用户 sudo useradd -m hp -s /bin/bash # 建立密码 sudo passwd hp # 增加权限 sudo adduser hp sudo # 切换用户 su hp # 更新软件目录 sudo apt-get update
-
集群、单节点模式都需要 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
-
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 手动安装
-
下载 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
-
设置环境变量
# 编辑 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
-
安装 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 的安装位置。
-
找出 Java 安装路径
sudo update-alternatives --config java
-
添加 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
-
在官网下载安装包
-
安装 vscode
cd ~/Downloads sudo dpkg -i code_1.44.2-1587059832_amd64.deb sudo apt-get -f install
3.2 配置 vscode
3.2.1 [可选]中文环境
- 按住
Shift+Ctrl+P
,打开命令窗口,输入language
- 选择
config display language
- 下载 简体中文包
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
-
下载 Hadoop安装包
hadoop-3.1.3.tar.gz
,点击下载 -
安装 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
-
配置环境变量
# 编辑配置文件 # 定义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 进程,方便进行调试。
-
设置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}
-
测试 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/*
-
Hadoop 不会覆盖输出文件,所以再次执行案例不会成功,需要删除输出文件
rm -r ./output
-
查看 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.xml 和 hdfs-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.dir 和 dfs.datanode.data.dir,否则在接下来的步骤中可能会出错。
-
修改 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>
-
-
修改 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>
-
-
执行 NameNode 格式化
cd /usr/local/hadoop # 格式化 ./bin/hdfs namenode -format # 成功会看到 SHUTDOWN_MSG: Shutting down NameNode
-
开启 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 一些小坑
-
启动 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。 -
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 运行实例
-
上面的单机模式,grep 例子读取的是本地数据,伪分布式读取的则是 HDFS 上的数据。要使用 HDFS,首先需要在 HDFS 中创建用户目录:
./bin/hdfs dfs -mkdir -p /user/hp
这里有三种shell命令方式。
- hadoop fs
- hadoop dfs
- hdfs dfs
hadoop fs适用于任何不同的文件系统,比如本地文件系统和HDFS文件系统
hadoop dfs只能适用于HDFS文件系统
hdfs dfs跟hadoop dfs的命令作用一样,也只能适用于HDFS文件系统 -
接着将 ./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
-
运行实例。伪分布式运行 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
-
运行 Hadoop 程序时,为了防止覆盖结果,程序指定的输出目录(如 output)不能存在,否则会提示错误,因此运行前需要先删除输出目录。在实际开发应用程序时,可考虑在程序中加上如下代码,能在每次运行时自动删除输出目录,避免繁琐的命令行操作:
Configuration conf = new Configuration(); Job job = new Job(conf); /* 删除输出目录 */ Path outputPath = new Path(args[1]); outputPath.getFileSystem(conf).delete(outputPath, true);
-
关闭 Hadoop
./sbin/stop-dfs.sh
-
启动 Hadoop
./sbin/start-dfs.sh
-
启动成功后还可在web 端查看
2.4 Hadoop 集群
暂时学习使用伪分布式足矣,集群待入门之后再来更新。