date: 2020-12-25title: Hadoop HDFS单节点及伪分布集群部署 #标题
tags: HDFS #标签
categories: Hadoop # 分类

记录下Hadoop HDFS单节点及伪分布集群部署过程。
参考:

修改系统限制

  1. $ mv /etc/security/limits.conf{,.bak}
  2. cat > /etc/security/limits.conf << EOF
  3. * - nofile 655350
  4. * - memlock unlimited
  5. * - stack 655360
  6. * - nproc unlimited
  7. EOF
  8. cat > /etc/sysctl.conf << EOF
  9. kernel.sysrq = 0
  10. kernel.core_uses_pid = 1
  11. fs.file-max=655360
  12. kernel.msgmnb = 65536
  13. kernel.msgmax = 65536
  14. kernel.shmmax = 68719476736
  15. kernel.shmall = 4294967296
  16. kernel.pid_max = 655360
  17. net.ipv4.tcp_tw_reuse = 1
  18. net.ipv4.tcp_tw_recycle = 0
  19. net.ipv4.tcp_max_tw_buckets = 10000
  20. net.ipv4.tcp_fin_timeout = 30
  21. net.ipv4.tcp_timestamps = 0
  22. net.ipv4.tcp_sack = 1
  23. net.ipv4.tcp_window_scaling = 1
  24. net.ipv4.tcp_ecn = 0
  25. net.ipv4.tcp_keepalive_time = 600
  26. net.ipv4.tcp_keepalive_intvl = 30
  27. net.ipv4.tcp_keepalive_probes = 3
  28. net.ipv4.tcp_max_orphans = 655360
  29. net.ipv4.tcp_max_syn_backlog = 262144
  30. net.ipv4.tcp_mem = 65536 131072 262144
  31. net.ipv4.udp_mem = 65536 131072 262144
  32. net.ipv4.tcp_rmem = 4096 87380 16777216
  33. net.ipv4.tcp_wmem = 4096 16384 16777216
  34. net.ipv4.ip_local_port_range = 1024 65535
  35. net.ipv4.route.gc_timeout = 100
  36. # 禁止icmp重定向报文
  37. net.ipv4.conf.all.accept_redirects = 0
  38. # 禁止icmp源路由
  39. net.ipv4.conf.all.accept_source_route = 0
  40. net.core.somaxconn = 65535
  41. net.core.rmem_default = 8388608
  42. net.core.wmem_default = 8388608
  43. net.core.rmem_max = 16777216
  44. net.core.wmem_max = 16777216
  45. net.core.netdev_max_backlog = 262144
  46. vm.swappiness = 10
  47. vm.overcommit_memory = 1
  48. vm.max_map_count = 262144
  49. EOF
  50. sysctl -p

配置jdk

自行去oracle官网下载java包 jdk-8u261-linux-x64.tar.gz ,然后上传至服务器。

  1. $ mkdir /apps/usr -p && systemctl stop firewalld && systemctl disable firewalld && setenforce 0
  2. $ tar zxf jdk-8u261-linux-x64.tar.gz -C /apps/usr/
  3. $ ln -sf /apps/usr/jdk1.8.0_261 /apps/usr/jdk
  4. $ cat >> /etc/profile << EOF
  5. export JAVA_HOME=/apps/usr/jdk
  6. export CLASSPATH=\$JAVA_HOME/lib
  7. export PATH=\$JAVA_HOME/bin:\$PATH
  8. EOF
  9. $ source /etc/profile
  10. $ java -version # 查看版本信息
  11. java version "1.8.0_261"
  12. Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
  13. Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)

部署Hadoop

  1. # 配置主机名解析
  2. $ hostnamectl set-hostname hadoop01
  3. $ cat >> /etc/hosts << EOF
  4. 192.168.20.10 hadoop01
  5. EOF
  6. $ wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar.gz
  7. $ tar zxf hadoop-2.7.7.tar.gz -C /apps/usr/
  8. $ cat >> /etc/profile << EOF
  9. export HADOOP_HOME=/apps/usr/hadoop-2.7.7
  10. export PATH=\${HADOOP_HOME}/bin:\${HADOOP_HOME}/sbin:\${PATH}
  11. EOF
  12. $ source /etc/profile

独立运行hadoop

默认情况下,Hadoop被配置为以非分布式模式作为单个Java进程运行。这对于调试很有用。

grep案例

下面的示例复制解压缩的etc目录以用作输入,然后查找并显示给定正则表达式的每个匹配项。输出被写入给定的输出目录。

  1. $ cd /apps/usr/hadoop-2.7.7/
  2. $ mkdir input
  3. $ cp etc/hadoop/*.xml input/
  4. $ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar grep input/ output 'dfs[a-z.]+'
  5. # 切记,output目录不可事先创建
  6. $ cat output/* # 查看输出内容
  7. 1 dfsadmin

wordcount 统计案例

wordcount用于统计input中单词的数量。

  1. # 准备检索数据源
  2. $ pwd # 确认当前目录
  3. /apps/usr/hadoop-2.7.7
  4. $ mkdir wcinput
  5. $ cat >> wcinput/a.txt << EOF
  6. hadoop yarn
  7. hadoop mapreduce
  8. atguigu
  9. atguigu
  10. EOF
  11. # 运行程序
  12. $ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar wordcount wcinput wcoutput
  13. $ cat wcoutput/* # 查看统计结果
  14. atguigu 2
  15. hadoop 2
  16. mapreduce 1
  17. yarn 1

部署伪分布集群

在部署伪分布集群前,请先参考上述部分,部署好单节点HDFS。

修改hadoop配置文件

  1. $ pwd # 确定当前路径
  2. /apps/usr/hadoop-2.7.7
  3. # 修改hadoop的jdk环境变量
  4. $ sed -i 's/export JAVA_HOME=.*/export JAVA_HOME=\/apps\/usr\/jdk/g' /apps/usr/hadoop-2.7.7/etc/hadoop/hadoop-env.sh
  5. $ vim etc/hadoop/core-site.xml # 修改此文件
  6. <configuration> # 找到此行,写入以下配置
  7. <!--指定HDFSNameNode的地址-->
  8. <property>
  9. <name>fs.defaultFS</name>
  10. <value>hdfs://192.168.20.10:9000</value>
  11. </property>
  12. <!--指定Hadoop运行时产生文件的存储目录-->
  13. <property>
  14. <name>hadoop.tmp.dir</name>
  15. <value>/apps/usr/hadoop-2.7.7/data/tmp</value>
  16. </property>
  17. </configuration>
  18. $ vim etc/hadoop/hdfs-site.xml # 修改此文件
  19. <configuration> # 找到此行,写入以下配置
  20. <!--默认副本数为3,修改为1-->
  21. <property>
  22. <name>dfs.replication</name>
  23. <value>1</value>
  24. </property>
  25. </configuration>

修改副本数的原因在于,目前只有一个datanode,即便是使用默认值3,也只会有一个副本,但如果后续增加datanode,它会在其他datanode上同步副本,直至满足定义的副本数。

上述所有配置文件中的默认配置,都可以在官网上找到答案,如下:

Hadoop HDFS单节点及伪分布集群部署 - 图1

点击任意一个进入后,即可看到如下页面(左边是name,右边是默认的value):

Hadoop HDFS单节点及伪分布集群部署 - 图2

启动HDFS并运行MapReduce

1、格式化NameNode(第一次启动时格式化,后续就不要总是格式化了)

格式化的概念,和磁盘的格式化一个意思,格式化后,所有数据就都没了,在集群运行一段时间后,再次格式化,可能需要将data目录删除后才可格式化,否则可能会报错。

  1. $ hdfs namenode -format

格式化成功后,部分输出如下:

Hadoop HDFS单节点及伪分布集群部署 - 图3

2、启动NameNode

  1. $ hadoop-daemon.sh start namenode
  2. # 启动后,会输出日志文件路径
  3. starting namenode, logging to /apps/usr/hadoop-2.7.7/logs/hadoop-root-namenode-lv.out

3、启动DataNode

  1. $ hadoop-daemon.sh start datanode
  2. starting datanode, logging to /apps/usr/hadoop-2.7.7/logs/hadoop-root-datanode-lv.out

4、确定集群已启动

  1. $ jps # 查看java进程
  2. 27984 DataNode
  3. 28100 Jps
  4. 27899 NameNode
  5. # 由于我这台机器上没有其他java进程,所以可以确定,所有端口都是HDFS在占用(也可以通过pid号来确认)
  6. $ ss -lnput | grep java
  7. tcp LISTEN 0 128 127.0.0.1:41703 *:* users:(("java",pid=27984,fd=198))
  8. tcp LISTEN 0 128 192.168.20.10:9000 *:* users:(("java",pid=27899,fd=205))
  9. tcp LISTEN 0 128 *:50070 *:* users:(("java",pid=27899,fd=194))
  10. tcp LISTEN 0 128 *:50010 *:* users:(("java",pid=27984,fd=186))
  11. tcp LISTEN 0 128 *:50075 *:* users:(("java",pid=27984,fd=226))
  12. tcp LISTEN 0 128 *:50020 *:* users:(("java",pid=27984,fd=231))

访问hadoop的web管理页面

访问地址为你机器的50070端口即可。如下:

Hadoop HDFS单节点及伪分布集群部署 - 图4

Hadoop HDFS单节点及伪分布集群部署 - 图5

上述中的文件系统,和linux一样,都是以 “/” 开始。

运行MapReduce

  1. # 在HDFS中创建目录(没有任何输出,即表示创建成功)
  2. $ hdfs dfs -mkdir -p /user/lvjianzhao/test
  3. # 查看创建的目录
  4. $ hdfs dfs -ls /
  5. Found 1 items
  6. drwxr-xr-x - root supergroup 0 2020-11-08 20:01 /user
  7. $ hdfs dfs -ls -R / # 查看多级目录
  8. drwxr-xr-x - root supergroup 0 2020-11-08 20:01 /user
  9. drwxr-xr-x - root supergroup 0 2020-11-08 20:01 /user/lvjianzhao
  10. drwxr-xr-x - root supergroup 0 2020-11-08 20:01 /user/lvjianzhao/test

Hadoop HDFS单节点及伪分布集群部署 - 图6

  1. # 上传本地文件到HDFS
  2. $ echo "test file upload" >> a.txt # 创建测试文件
  3. $ hdfs dfs -put a.txt /user/lvjianzhao/test/ # 上传本地文件到刚才创建的目录下
  4. $ hdfs dfs -cat /user/lvjianzhao/test/a.txt # 查看上传的文件
  5. test file upload

上传的文件,亦可以在web界面看到并下载,如下:

Hadoop HDFS单节点及伪分布集群部署 - 图7

点击文件名后看到如下:

Hadoop HDFS单节点及伪分布集群部署 - 图8

  1. # wordcount统计刚才上传的文件
  2. $ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar wordcount /user/lvjianzhao/test/a.txt /user/lvjianzhao/test/output
  3. # 命令行查看统计结果
  4. $ hdfs dfs -cat /user/lvjianzhao/test/output/*
  5. file 1
  6. test 1
  7. upload 1

分析统计结果,照样可以在web页面查看到,如下:

Hadoop HDFS单节点及伪分布集群部署 - 图9

启动YARN并运行MapReduce程序

启动YARN并运行MapReduce程序的大概过程如下:
1、配置集群在YARN上运行RM
2、启动、测试集群增删改查
3、在YARN上执行wordcount案例

在启动yarn之前,我们先来看一下yarn的架构,如下:

Hadoop HDFS单节点及伪分布集群部署 - 图10

关于其架构的解释,可以观看尚硅谷视频

配置集群在YARN上运行

  1. $ pwd # 确定当前目录
  2. /apps/usr/hadoop-2.7.7
  3. # 修改yarn-site.xml
  4. $ vim etc/hadoop/yarn-site.xml
  5. <configuration> # 找到此行,写入以下内容
  6. <!--指定YARNResourceManager的地址-->
  7. <property>
  8. <name>yarn.resourcemanager.hostname</name>
  9. <value>hadoop01</value>
  10. </property>
  11. <!--Reducer获取数据的方式-->
  12. <property>
  13. <name>yarn.nodemanager.aux-services</name>
  14. <value>mapreduce_shuffle</value>
  15. </property>
  16. </configuration>
  17. # 配置mapred-site.xml
  18. $ cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
  19. $ vim etc/hadoop/mapred-site.xml # 编辑此配置文件
  20. <configuration>
  21. <!-- 指定MapReduce运行时框架运行在YARN上,默认是local -->
  22. <property>
  23. <name>mapreduce.framework.name</name>
  24. <value>yarn</value>
  25. </property>
  26. </configuration>

启动集群

  1. # 启动前必须保证namenode和datanode已经启动,如下:
  2. $ jps | grep -v Jps
  3. 27984 DataNode
  4. 27899 NameNode
  5. # 启动resourcemanager
  6. $ yarn-daemon.sh start resourcemanager
  7. # 启动nodemanager
  8. $ yarn-daemon.sh start nodemanager

查看cluster的web界面

访问8088端口(访问的是mapreduce的管理页面),如下:

Hadoop HDFS单节点及伪分布集群部署 - 图11

运行一个wordcount作业

  1. $ hdfs dfs -rm -r /user/lvjianzhao/test/output # 删除之前的作业输出目录
  2. # 重新运行wordcount作业
  3. $ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar wordcount /user/lvjianzhao/test/a.txt /user/lvjianzhao/test/output

wordcount运行成功后,即可看到如下信息:

Hadoop HDFS单节点及伪分布集群部署 - 图12

  1. $ vim etc/hadoop/mapred-site.xml # 编辑此文件,在末尾的</configuration> 标签之前增加以下内容
  2. <!--指定历史服务器端地址-->
  3. <property>
  4. <name>mapreduce.jobhistory.address</name>
  5. <value>192.168.20.10:10020</value>
  6. </property>
  7. <!--历史服务器web端地址-->
  8. <property>
  9. <name>mapreduce.jobhistory.webapp.address</name>
  10. <value>192.168.20.10:19888</value>
  11. </property>
  12. </configuration>
  13. # 启动历史服务器
  14. $ mr-jobhistory-daemon.sh start historyserver
  15. # 查看历史服务器是否已启动
  16. $ jps
  17. 27984 DataNode
  18. 29809 Jps
  19. 27899 NameNode
  20. 28877 ResourceManager
  21. 29117 NodeManager
  22. 29741 JobHistoryServer
  23. $ ss -lnput | egrep '10020|19888' # 确定端口在监听
  24. tcp LISTEN 0 128 192.168.20.10:19888 *:* users:(("java",pid=29741,fd=214))
  25. tcp LISTEN 0 128 192.168.20.10:10020 *:* users:(("java",pid=29741,fd=219))

到目前为止,我们还不能直接访问历史服务器的信息,因为点击后,就会跳转到以你hadoop所在机器的主机名开头的url中,所以你还需要自行配置本机的hosts文件(hosts文件路径:C:\Windows\System32\drivers\etc\hosts),才可以成功访问到如下页面:

Hadoop HDFS单节点及伪分布集群部署 - 图13

配置日志的聚集功能

日志聚集的概念:应用运行完成以后,将程序运行日志信息上传到HDFS系统上。
日志聚集功能的好处:可以方便的查看到程序运行详情,方便开发测试。

注意:开启日志聚集功能,需要重新启动NodeManager、ResourceManager、和HistroyManager。

  1. $ vim etc/hadoop/yarn-site.xml # 在configuration字段中添加以下内容
  2. <!--开启日志聚集功能-->
  3. <property>
  4. <name>yarn.log-aggregation-enable</name>
  5. <value>true</value>
  6. </property>
  7. <!--日志保留时间设置为7天-->
  8. <property>
  9. <name>yarn.log-aggregation.retain-seconds</name>
  10. <value>604800</value>
  11. </property>
  12. # 重启NodeManager、ResourceManager、和HistroyManager
  13. # 停止
  14. $ yarn-daemon.sh stop resourcemanager
  15. $ yarn-daemon.sh stop nodemanager
  16. $ mr-jobhistory-daemon.sh stop historyserver
  17. # 启动
  18. $ mr-jobhistory-daemon.sh start historyserver
  19. $ yarn-daemon.sh start nodemanager
  20. $ yarn-daemon.sh start resourcemanager

至此,日志聚合功能配置完毕,现在就来验证下。

  1. # 运行一个wordcount工作
  2. $ hdfs dfs -rm -r /user/lvjianzhao/test/output
  3. $ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.7.jar wordcount /user/lvjianzhao/test/a.txt /user/lvjianzhao/test/output

查看聚合后的日志:

1、进入job的history:

Hadoop HDFS单节点及伪分布集群部署 - 图14

2、进入job的logs

Hadoop HDFS单节点及伪分布集群部署 - 图15

3、查看日志信息

Hadoop HDFS单节点及伪分布集群部署 - 图16

集群部署问题汇总

namenode和datanode进程只能启动一个

遇到此问题,大多数是你二次格式化了namenode,造成namenode产生了新的cluster_ID,但datanode还是之前的cluster_ID,此时,他们谁也不认识谁,就会造成,只能启动datanode或者namenode,图示如下:

Hadoop HDFS单节点及伪分布集群部署 - 图17

  1. # namenode 的cluster信息存储路径
  2. $ grep 'clusterID' /apps/usr/hadoop-2.7.7/data/tmp/dfs/name/current/VERSION
  3. clusterID=CID-e605e3ae-d898-45d8-bf71-59345a1110fd
  4. # datanode 的cluster信息存储路径
  5. $ grep 'clusterID' /apps/usr/hadoop-2.7.7/data/tmp/dfs/data/current/VERSION
  6. clusterID=CID-e605e3ae-d898-45d8-bf71-59345a1110fd
  7. # 正常情况下,datanode和namenode的clusterID一致才对。