title: Hadoop HDFS完全分布式集群部署 #标题tags: Hadoop #标签
date: 2020-11-11
categories: Hadoop # 分类

记录下hadoop分布式集群部署流程。

环境准备

OS hostname IP roles
Centos 7.5 hadoop01 192.168.20.2 DataNode、NameNode、NodeManager
Centos 7.5 hadoop02 192.168.20.3 DataNode、ResourceManager、NodeManager、historyserver
Centos 7.5 hadoop03 192.168.20.4 DataNode、SecondaryNameNode、NodeManager

上述角色中,只有DataNode、NameNode、SecondaryNameNode是HDFS中的角色,剩下的都是YARN中的角色。

建议NameNode和SecondaryNameNode不要部署在同一台机器上,并且其内存大小一致。
ResourceManager是YARN架构中的重要组件,是比较耗资源的一个组件,所以建议不要和NameNode、SecondaryNameNode部署在同一个节点上。

接下的所有操作,只要没特别说明,则只需在 hadoop01 这一个机器上执行即可。

配置ssh免密登录

切记,先配置主机解析记录,再配置免密登录。

  1. # 配置主机名解析记录
  2. $ cat >> /etc/hosts <<EOF
  3. 192.168.20.2 hadoop01
  4. 192.168.20.3 hadoop02
  5. 192.168.20.4 hadoop03
  6. EOF
  7. # 修改后的hosts文件发送至其他节点
  8. $ for i in $(seq 1 3);do rsync -az /etc/hosts hadoop0${i}:/etc/;done
  9. # 下面是配置免密登录,需要在resourcemanager和nodemanagere两个角色的机器上执行
  10. # 我这里是hadoop01、hadoop02这两个机器上执行
  11. # 为了方便后续群起集群,我们必须在resourcemanager和nodemanagere两个角色的机器上配置免密登录到其他节点
  12. $ ssh-keygen -t rsa # 执行后一路回车
  13. $ for i in $(seq 1 3);do ssh-copy-id hadoop0${i} ;done # 执行后根据提示,该输入yes输入yes,该输入密码就输入密码

修改系统限制

  1. $ mv /etc/security/limits.conf{,.bak}
  2. cat > /etc/security/limits.conf << EOF
  3. * - nofile 655360
  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
  51. #将修改后的文件发送至其他节点
  52. $ for i in $(seq 1 3);do rsync -az /etc/security/limits.conf hadoop0${i}:/etc/security/;done
  53. $ for i in $(seq 1 3);do rsync -az /etc/sysctl.conf hadoop0${i}:/etc/;done
  54. # 其余节点需执行下面命令刷新内核参数
  55. $ sysctl -p

配置jdk

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

配置jdk环境的操作,是需要在所有节点进行的。

  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)

配置ntp时间同步

在hadoop01配置时间服务器,其他客户端制定定时任务即可。

  1. $ yum -y install ntp
  2. $ vim /etc/ntp.conf # 修改配置文件
  3. # 找到(17行左右):
  4. #restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
  5. # 改为(网段是你自己的网段,表示允许哪个网段的客户端来同步时间):
  6. restrict 192.168.20.0 mask 255.255.255.0 nomodify notrap
  7. # 找到
  8. server 0.centos.pool.ntp.org iburst
  9. server 1.centos.pool.ntp.org iburst
  10. server 2.centos.pool.ntp.org iburst
  11. server 3.centos.pool.ntp.org iburst
  12. # 将其注释掉,表示不使用互联网上的时间同步服务器
  13. #server 0.centos.pool.ntp.org iburst
  14. #server 1.centos.pool.ntp.org iburst
  15. #server 2.centos.pool.ntp.org iburst
  16. #server 3.centos.pool.ntp.org iburst
  17. # 末尾追加
  18. server 127.127.1.0
  19. fudge 127.127.1.0 stratum 5
  20. # 在上级时钟源失效时,NTP会使用127.127.1.0的本地时钟,将local时间作为ntp服务器时间提供给ntp客户端。
  21. # NTP把本地主机的时钟也看作外部时钟源来处理,分配的地址是127.127.1.0
  22. # 让硬件时间和系统时间一起同步
  23. $ echo 'SYNC_HWCLOCK=yes' >> /etc/sysconfig/ntpd
  24. # 重启ntp服务器生效
  25. $ systemctl restart ntpd && systemctl enable ntpd
  26. # 配置其他客户端定时同步时间(哪些机器要同步上面时间服务器的时间,就进行以下配置)
  27. $ yum -y install ntp
  28. $ crontab -e # 写入以下定时任务
  29. */5 * * * * /usr/sbin/ntpdate 192.168.20.2 &> /dev/null

部署hadoop

没有特别说明的,以下操作在hadoop01上进行即可。

  1. $ wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.9.2/hadoop-2.9.2.tar.gz
  2. $ tar zxf hadoop-2.9.2.tar.gz -C /apps/usr/
  3. # 配置hadoop环境变量
  4. $ cat >> /etc/profile << EOF
  5. export HADOOP_HOME=/apps/usr/hadoop-2.9.2
  6. export PATH=\${HADOOP_HOME}/bin:\${HADOOP_HOME}/sbin:\${PATH}
  7. EOF
  8. $ source /etc/profile
  9. $ cd /apps/usr/hadoop-2.9.2/
  10. # 修改hadoop的jdk环境变量
  11. $ sed -i 's/export JAVA_HOME=.*/export JAVA_HOME=\/apps\/usr\/jdk/g' etc/hadoop/hadoop-env.sh
  12. $ vim etc/hadoop/core-site.xml # 修改此文件
  13. <configuration> # 找到此行,写入以下配置
  14. <!--指定HDFSNameNode的地址-->
  15. <property>
  16. <name>fs.defaultFS</name>
  17. <value>hdfs://hadoop01:9000</value>
  18. </property>
  19. <!--指定Hadoop运行时产生文件的存储目录-->
  20. <property>
  21. <name>hadoop.tmp.dir</name>
  22. <value>/apps/usr/hadoop-2.9.2/data/tmp</value>
  23. </property>
  24. </configuration>
  25. $ vim etc/hadoop/hdfs-site.xml # 修改此文件
  26. <configuration> # 找到此行,写入以下配置
  27. <!--默认副本数为3-->
  28. <property>
  29. <name>dfs.replication</name>
  30. <value>3</value>
  31. </property>
  32. <!--指定 Hadoop辅助节点(secondaryNameNode)主机配置-->
  33. <property>
  34. <name>dfs.namenode.secondary.http-address</name>
  35. <value>hadoop03:50090</value>
  36. </property>
  37. </configuration>
  38. # 修改yarn-site.xml
  39. $ vim etc/hadoop/yarn-site.xml
  40. <configuration> # 找到此行,写入以下内容
  41. <!--指定YARNResourceManager的地址-->
  42. <property>
  43. <name>yarn.resourcemanager.hostname</name>
  44. <value>hadoop02</value>
  45. </property>
  46. <!--Reducer获取数据的方式-->
  47. <property>
  48. <name>yarn.nodemanager.aux-services</name>
  49. <value>mapreduce_shuffle</value>
  50. </property>
  51. <!--开启日志聚集功能-->
  52. <property>
  53. <name>yarn.log-aggregation-enable</name>
  54. <value>true</value>
  55. </property>
  56. <!--日志保留时间设置为7天-->
  57. <property>
  58. <name>yarn.log-aggregation.retain-seconds</name>
  59. <value>604800</value>
  60. </property>
  61. </configuration>
  62. # 配置mapred-site.xml
  63. $ cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
  64. $ vim etc/hadoop/mapred-site.xml # 编辑此配置文件
  65. <configuration>
  66. <!-- 指定MapReduce运行时框架运行在YARN上,默认是local -->
  67. <property>
  68. <name>mapreduce.framework.name</name>
  69. <value>yarn</value>
  70. </property>
  71. <!--指定历史服务器端地址-->
  72. <property>
  73. <name>mapreduce.jobhistory.address</name>
  74. <value>hadoop02:10020</value>
  75. </property>
  76. <!--历史服务器web端地址-->
  77. <property>
  78. <name>mapreduce.jobhistory.webapp.address</name>
  79. <value>hadoop02:19888</value>
  80. </property>
  81. </configuration>
  82. # 修改slavaes文件,以便日后可以群起集群,而不是一个个节点去启动
  83. # 下面slaves写的是主机名,每行主机名后不可以有空格,并且必须保证hosts文件里写了正确的解析记录
  84. $ cat > etc/hadoop/slaves << EOF
  85. hadoop01
  86. hadoop02
  87. hadoop03
  88. EOF
  89. # 发送修改好的hadoop目录到其他节点
  90. $ for i in 2 3;do rsync -az /apps/usr/hadoop-2.9.2 hadoop0${i}:/apps/usr/;done
  91. # 其他节点执行以下命令,以便配置hadoop的环境变量
  92. $ cat >> /etc/profile << EOF
  93. export HADOOP_HOME=/apps/usr/hadoop-2.9.2
  94. export PATH=\${HADOOP_HOME}/bin:\${HADOOP_HOME}/sbin:\${PATH}
  95. EOF
  96. $ source /etc/profile
  97. # 接下来格式化、启动hdfs操作,继续在nodemanager(hadoop01)节点上执行
  98. $ hdfs namenode -format # 格式化namenode
  99. # 启动hdfs的所有节点(其中包括namenode、secondarynamenode、datanode)
  100. $ start-dfs.sh # 执行后,输出如下
  101. Starting namenodes on [hadoop01]
  102. hadoop01: starting namenode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-namenode-hadoop01.out
  103. hadoop01: starting datanode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-datanode-hadoop01.out
  104. hadoop03: starting datanode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-datanode-hadoop03.out
  105. hadoop02: starting datanode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-datanode-hadoop02.out
  106. Starting secondary namenodes [hadoop03]
  107. hadoop03: starting secondarynamenode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-secondarynamenode-hadoop03.out
  108. # 确认HDFS角色启动完毕
  109. $ jps | grep Jps -v # hadoop01启动角色如下
  110. 23367 NameNode
  111. 23498 DataNode
  112. $ jps | grep Jps -v # hadoop02启动角色如下
  113. 23392 DataNode
  114. $ jps | grep Jps -v # hadoop03启动角色如下
  115. 23249 DataNode
  116. 23350 SecondaryNameNode
  117. # hdfs启动后,最好等待三分钟,再启动yarn,否则,你启动yarn后,创建目录,大概率会得到如下提示:
  118. $ hdfs dfs -mkdir -p /user/lvjianzhao/test
  119. mkdir: Cannot create directory /user/lvjianzhao/test. Name node is in safe mode.
  120. # 之所以要等待几分钟,是因为hdfs刚刚启动,还在验证和适配,所以进入安全模式,此时不建议马上启动yarn。
  121. # 启动resourcemanager角色(必须在你规划的resourcemanager(hadoop02)主机上启动resourcemanager)
  122. $ start-yarn.sh # 启动成功后,输出如下
  123. starting yarn daemons
  124. starting resourcemanager, logging to /apps/usr/hadoop-2.9.2/logs/yarn-root-resourcemanager-hadoop02.out
  125. hadoop03: starting nodemanager, logging to /apps/usr/hadoop-2.9.2/logs/yarn-root-nodemanager-hadoop03.out
  126. hadoop02: starting nodemanager, logging to /apps/usr/hadoop-2.9.2/logs/yarn-root-nodemanager-hadoop02.out
  127. hadoop01: starting nodemanager, logging to /apps/usr/hadoop-2.9.2/logs/yarn-root-nodemanager-hadoop01.out
  128. # 再次确认各个节点上运行的角色是否和文章开头规划的角色一致
  129. $ jps | grep Jps -v # hadoop01节点
  130. 23367 NameNode
  131. 23498 DataNode
  132. 24079 NodeManager
  133. $ jps | grep Jps -v # hadoop02节点
  134. 23392 DataNode
  135. 24869 ResourceManager
  136. 25094 NodeManager
  137. $ jps | grep Jps -v # hadoop03节点
  138. 23249 DataNode
  139. 23684 NodeManager
  140. 23350 SecondaryNameNode
  141. # 启动历史服务器(在配置文件中指定的历史服务器主机上执行即可,我这里是hadoop02机器)
  142. $ mr-jobhistory-daemon.sh start historyserver
  143. $ jps | grep Jps -v # 确认JobHistoryServer启动成功
  144. 26432 NodeManager
  145. 26202 ResourceManager
  146. 26077 DataNode
  147. 26669 JobHistoryServer

验证集群

上传文件至hdfs
  1. $ cd /apps/usr/hadoop-2.9.2/
  2. $ echo "test file upload" >> a.txt # 创建本地文件
  3. $ hdfs dfs -mkdir -p /user/lvjianzhao/test # 在hdfs上创建目录
  4. $ hdfs dfs -put a.txt /user/lvjianzhao/test/ # 上传本地文件至hdfs指定目录
  5. $ hdfs dfs -cat /user/lvjianzhao/test/a.txt # 查看hdfs上的文件内容
  6. test file upload

访问hdfs的namenode节点50070端口即可看到刚才上传的文件信息,如下:

Hadoop HDFS完全分布式集群部署 - 图1

  1. # 再上传一个大文件
  2. $ du -sh hadoop-2.9.2.tar.gz
  3. 350M hadoop-2.9.2.tar.gz
  4. $ hdfs dfs -put hadoop-2.9.2.tar.gz /user/lvjianzhao/test/

文件上传后,即可在web页面查看文件的详细信息,如下(由于一个块大小占128MB,故此文件占用了三个block,并且副本数为3,也就是说,每个datanode上都存储了此文件):

Hadoop HDFS完全分布式集群部署 - 图2

Hadoop HDFS完全分布式集群部署 - 图3

现在文件可以查看到了,那么此文件都存在了本地的哪里呢?接下来就找一下:

  1. $ cd /apps/usr/hadoop-2.9.2/data/tmp/dfs/data/current/BP-460095908-192.168.20.2-1605105847603/current/finalized/subdir0/subdir0
  2. $ ll blk_107374182[6-8] # 本地文件是blk_前缀加block id命名的
  3. -rw-r--r--. 1 root root 134217728 11 12 07:50 blk_1073741826
  4. -rw-r--r--. 1 root root 134217728 11 12 07:50 blk_1073741827
  5. -rw-r--r--. 1 root root 98011993 11 12 07:50 blk_1073741828
  6. # 现在按照顺序将此文件在本地恢复下(切记,下面的顺序不能乱)
  7. $ cat blk_1073741826 >> test.tgz
  8. $ cat blk_1073741827 >> test.tgz
  9. $ cat blk_1073741828 >> test.tgz
  10. $ tar zxf test.tgz # 解压此文件
  11. $ ls hadoop-2.9.2/ # 查看发现,就是我们上传的压缩包
  12. bin etc include lib libexec LICENSE.txt NOTICE.txt README.txt sbin share

运行一个wordcount工作
  1. $ cd /apps/usr/hadoop-2.9.2/
  2. # 就拿第一次上传的文件进行测试
  3. $ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.2.jar wordcount /user/lvjianzhao/test/a.txt /user/lvjianzhao/test/output
  4. # 命令行查看统计结果
  5. $ hdfs dfs -cat /user/lvjianzhao/test/output/*
  6. file 1
  7. test 1
  8. upload 1

查看cluster的web界面

访问8088端口(访问的是mapreduce的管理页面,我这里也就是resourcemanager所在节点的8088端口),如下:

Hadoop HDFS完全分布式集群部署 - 图4

Hadoop HDFS完全分布式集群部署 - 图5

如下,可以看到日志,则说明日志聚合功能配置无误:

Hadoop HDFS完全分布式集群部署 - 图6

至此,集群验证完毕。

查看各个文件的配置模板

hadoop二进制包中提供了各个配置文件中支持的所有参数及参数详细解释,那么怎么找到这些文件呢?请看如下:

  1. $ /apps/usr/hadoop-2.9.2 # 进入hadoop家目录
  2. $ find . -name "*xml*" | grep default # 这样即可查看到hadoop支持的所有配置
  3. ./share/hadoop/httpfs/tomcat/webapps/webhdfs/WEB-INF/classes/httpfs-default.xml
  4. ./share/doc/hadoop/hadoop-yarn/hadoop-yarn-common/yarn-default.xml
  5. ./share/doc/hadoop/hadoop-project-dist/hadoop-common/core-default.xml
  6. ./share/doc/hadoop/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
  7. ./share/doc/hadoop/hadoop-project-dist/hadoop-hdfs-rbf/hdfs-rbf-default.xml
  8. ./share/doc/hadoop/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml