title: Hadoop HDFS完全分布式集群部署 #标题tags: Hadoop #标签
date: 2020-11-11
categories: 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免密登录
切记,先配置主机解析记录,再配置免密登录。
# 配置主机名解析记录
$ cat >> /etc/hosts <<EOF
192.168.20.2 hadoop01
192.168.20.3 hadoop02
192.168.20.4 hadoop03
EOF
# 修改后的hosts文件发送至其他节点
$ for i in $(seq 1 3);do rsync -az /etc/hosts hadoop0${i}:/etc/;done
# 下面是配置免密登录,需要在resourcemanager和nodemanagere两个角色的机器上执行
# 我这里是hadoop01、hadoop02这两个机器上执行
# 为了方便后续群起集群,我们必须在resourcemanager和nodemanagere两个角色的机器上配置免密登录到其他节点
$ ssh-keygen -t rsa # 执行后一路回车
$ for i in $(seq 1 3);do ssh-copy-id hadoop0${i} ;done # 执行后根据提示,该输入yes输入yes,该输入密码就输入密码
修改系统限制
$ mv /etc/security/limits.conf{,.bak}
cat > /etc/security/limits.conf << EOF
* - nofile 655360
* - memlock unlimited
* - stack 655360
* - nproc unlimited
EOF
cat > /etc/sysctl.conf << EOF
kernel.sysrq = 0
kernel.core_uses_pid = 1
fs.file-max=655360
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
kernel.pid_max = 655360
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_max_tw_buckets = 10000
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_ecn = 0
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_max_orphans = 655360
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_mem = 65536 131072 262144
net.ipv4.udp_mem = 65536 131072 262144
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 16384 16777216
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.route.gc_timeout = 100
# 禁止icmp重定向报文
net.ipv4.conf.all.accept_redirects = 0
# 禁止icmp源路由
net.ipv4.conf.all.accept_source_route = 0
net.core.somaxconn = 65535
net.core.rmem_default = 8388608
net.core.wmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
vm.swappiness = 10
vm.overcommit_memory = 1
vm.max_map_count = 262144
EOF
sysctl -p
#将修改后的文件发送至其他节点
$ for i in $(seq 1 3);do rsync -az /etc/security/limits.conf hadoop0${i}:/etc/security/;done
$ for i in $(seq 1 3);do rsync -az /etc/sysctl.conf hadoop0${i}:/etc/;done
# 其余节点需执行下面命令刷新内核参数
$ sysctl -p
配置jdk
自行去oracle官网下载java包 jdk-8u261-linux-x64.tar.gz ,然后上传至服务器。
配置jdk环境的操作,是需要在所有节点进行的。
$ mkdir /apps/usr -p && systemctl stop firewalld && systemctl disable firewalld && setenforce 0
$ tar zxf jdk-8u261-linux-x64.tar.gz -C /apps/usr/
$ ln -sf /apps/usr/jdk1.8.0_261 /apps/usr/jdk
$ cat >> /etc/profile << EOF
export JAVA_HOME=/apps/usr/jdk
export CLASSPATH=\$JAVA_HOME/lib
export PATH=\$JAVA_HOME/bin:\$PATH
EOF
$ source /etc/profile
$ java -version # 查看版本信息
java version "1.8.0_261"
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)
配置ntp时间同步
在hadoop01配置时间服务器,其他客户端制定定时任务即可。
$ yum -y install ntp
$ vim /etc/ntp.conf # 修改配置文件
# 找到(17行左右):
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
# 改为(网段是你自己的网段,表示允许哪个网段的客户端来同步时间):
restrict 192.168.20.0 mask 255.255.255.0 nomodify notrap
# 找到
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst
# 将其注释掉,表示不使用互联网上的时间同步服务器
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
# 末尾追加
server 127.127.1.0
fudge 127.127.1.0 stratum 5
# 在上级时钟源失效时,NTP会使用127.127.1.0的本地时钟,将local时间作为ntp服务器时间提供给ntp客户端。
# NTP把本地主机的时钟也看作外部时钟源来处理,分配的地址是127.127.1.0
# 让硬件时间和系统时间一起同步
$ echo 'SYNC_HWCLOCK=yes' >> /etc/sysconfig/ntpd
# 重启ntp服务器生效
$ systemctl restart ntpd && systemctl enable ntpd
# 配置其他客户端定时同步时间(哪些机器要同步上面时间服务器的时间,就进行以下配置)
$ yum -y install ntp
$ crontab -e # 写入以下定时任务
*/5 * * * * /usr/sbin/ntpdate 192.168.20.2 &> /dev/null
部署hadoop
没有特别说明的,以下操作在hadoop01上进行即可。
$ wget https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/hadoop-2.9.2/hadoop-2.9.2.tar.gz
$ tar zxf hadoop-2.9.2.tar.gz -C /apps/usr/
# 配置hadoop环境变量
$ cat >> /etc/profile << EOF
export HADOOP_HOME=/apps/usr/hadoop-2.9.2
export PATH=\${HADOOP_HOME}/bin:\${HADOOP_HOME}/sbin:\${PATH}
EOF
$ source /etc/profile
$ cd /apps/usr/hadoop-2.9.2/
# 修改hadoop的jdk环境变量
$ sed -i 's/export JAVA_HOME=.*/export JAVA_HOME=\/apps\/usr\/jdk/g' etc/hadoop/hadoop-env.sh
$ vim etc/hadoop/core-site.xml # 修改此文件
<configuration> # 找到此行,写入以下配置
<!--指定HDFS中NameNode的地址-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop01:9000</value>
</property>
<!--指定Hadoop运行时产生文件的存储目录-->
<property>
<name>hadoop.tmp.dir</name>
<value>/apps/usr/hadoop-2.9.2/data/tmp</value>
</property>
</configuration>
$ vim etc/hadoop/hdfs-site.xml # 修改此文件
<configuration> # 找到此行,写入以下配置
<!--默认副本数为3-->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!--指定 Hadoop辅助节点(secondaryNameNode)主机配置-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop03:50090</value>
</property>
</configuration>
# 修改yarn-site.xml
$ vim etc/hadoop/yarn-site.xml
<configuration> # 找到此行,写入以下内容
<!--指定YARN的ResourceManager的地址-->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop02</value>
</property>
<!--Reducer获取数据的方式-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--开启日志聚集功能-->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!--日志保留时间设置为7天-->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
</configuration>
# 配置mapred-site.xml
$ cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
$ vim etc/hadoop/mapred-site.xml # 编辑此配置文件
<configuration>
<!-- 指定MapReduce运行时框架运行在YARN上,默认是local -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!--指定历史服务器端地址-->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop02:10020</value>
</property>
<!--历史服务器web端地址-->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop02:19888</value>
</property>
</configuration>
# 修改slavaes文件,以便日后可以群起集群,而不是一个个节点去启动
# 下面slaves写的是主机名,每行主机名后不可以有空格,并且必须保证hosts文件里写了正确的解析记录
$ cat > etc/hadoop/slaves << EOF
hadoop01
hadoop02
hadoop03
EOF
# 发送修改好的hadoop目录到其他节点
$ for i in 2 3;do rsync -az /apps/usr/hadoop-2.9.2 hadoop0${i}:/apps/usr/;done
# 其他节点执行以下命令,以便配置hadoop的环境变量
$ cat >> /etc/profile << EOF
export HADOOP_HOME=/apps/usr/hadoop-2.9.2
export PATH=\${HADOOP_HOME}/bin:\${HADOOP_HOME}/sbin:\${PATH}
EOF
$ source /etc/profile
# 接下来格式化、启动hdfs操作,继续在nodemanager(hadoop01)节点上执行
$ hdfs namenode -format # 格式化namenode
# 启动hdfs的所有节点(其中包括namenode、secondarynamenode、datanode)
$ start-dfs.sh # 执行后,输出如下
Starting namenodes on [hadoop01]
hadoop01: starting namenode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-namenode-hadoop01.out
hadoop01: starting datanode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-datanode-hadoop01.out
hadoop03: starting datanode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-datanode-hadoop03.out
hadoop02: starting datanode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-datanode-hadoop02.out
Starting secondary namenodes [hadoop03]
hadoop03: starting secondarynamenode, logging to /apps/usr/hadoop-2.9.2/logs/hadoop-root-secondarynamenode-hadoop03.out
# 确认HDFS角色启动完毕
$ jps | grep Jps -v # hadoop01启动角色如下
23367 NameNode
23498 DataNode
$ jps | grep Jps -v # hadoop02启动角色如下
23392 DataNode
$ jps | grep Jps -v # hadoop03启动角色如下
23249 DataNode
23350 SecondaryNameNode
# hdfs启动后,最好等待三分钟,再启动yarn,否则,你启动yarn后,创建目录,大概率会得到如下提示:
$ hdfs dfs -mkdir -p /user/lvjianzhao/test
mkdir: Cannot create directory /user/lvjianzhao/test. Name node is in safe mode.
# 之所以要等待几分钟,是因为hdfs刚刚启动,还在验证和适配,所以进入安全模式,此时不建议马上启动yarn。
# 启动resourcemanager角色(必须在你规划的resourcemanager(hadoop02)主机上启动resourcemanager)
$ start-yarn.sh # 启动成功后,输出如下
starting yarn daemons
starting resourcemanager, logging to /apps/usr/hadoop-2.9.2/logs/yarn-root-resourcemanager-hadoop02.out
hadoop03: starting nodemanager, logging to /apps/usr/hadoop-2.9.2/logs/yarn-root-nodemanager-hadoop03.out
hadoop02: starting nodemanager, logging to /apps/usr/hadoop-2.9.2/logs/yarn-root-nodemanager-hadoop02.out
hadoop01: starting nodemanager, logging to /apps/usr/hadoop-2.9.2/logs/yarn-root-nodemanager-hadoop01.out
# 再次确认各个节点上运行的角色是否和文章开头规划的角色一致
$ jps | grep Jps -v # hadoop01节点
23367 NameNode
23498 DataNode
24079 NodeManager
$ jps | grep Jps -v # hadoop02节点
23392 DataNode
24869 ResourceManager
25094 NodeManager
$ jps | grep Jps -v # hadoop03节点
23249 DataNode
23684 NodeManager
23350 SecondaryNameNode
# 启动历史服务器(在配置文件中指定的历史服务器主机上执行即可,我这里是hadoop02机器)
$ mr-jobhistory-daemon.sh start historyserver
$ jps | grep Jps -v # 确认JobHistoryServer启动成功
26432 NodeManager
26202 ResourceManager
26077 DataNode
26669 JobHistoryServer
验证集群
上传文件至hdfs
$ cd /apps/usr/hadoop-2.9.2/
$ echo "test file upload" >> a.txt # 创建本地文件
$ hdfs dfs -mkdir -p /user/lvjianzhao/test # 在hdfs上创建目录
$ hdfs dfs -put a.txt /user/lvjianzhao/test/ # 上传本地文件至hdfs指定目录
$ hdfs dfs -cat /user/lvjianzhao/test/a.txt # 查看hdfs上的文件内容
test file upload
访问hdfs的namenode节点50070端口即可看到刚才上传的文件信息,如下:
# 再上传一个大文件
$ du -sh hadoop-2.9.2.tar.gz
350M hadoop-2.9.2.tar.gz
$ hdfs dfs -put hadoop-2.9.2.tar.gz /user/lvjianzhao/test/
文件上传后,即可在web页面查看文件的详细信息,如下(由于一个块大小占128MB,故此文件占用了三个block,并且副本数为3,也就是说,每个datanode上都存储了此文件):
现在文件可以查看到了,那么此文件都存在了本地的哪里呢?接下来就找一下:
$ cd /apps/usr/hadoop-2.9.2/data/tmp/dfs/data/current/BP-460095908-192.168.20.2-1605105847603/current/finalized/subdir0/subdir0
$ ll blk_107374182[6-8] # 本地文件是blk_前缀加block id命名的
-rw-r--r--. 1 root root 134217728 11月 12 07:50 blk_1073741826
-rw-r--r--. 1 root root 134217728 11月 12 07:50 blk_1073741827
-rw-r--r--. 1 root root 98011993 11月 12 07:50 blk_1073741828
# 现在按照顺序将此文件在本地恢复下(切记,下面的顺序不能乱)
$ cat blk_1073741826 >> test.tgz
$ cat blk_1073741827 >> test.tgz
$ cat blk_1073741828 >> test.tgz
$ tar zxf test.tgz # 解压此文件
$ ls hadoop-2.9.2/ # 查看发现,就是我们上传的压缩包
bin etc include lib libexec LICENSE.txt NOTICE.txt README.txt sbin share
运行一个wordcount工作
$ cd /apps/usr/hadoop-2.9.2/
# 就拿第一次上传的文件进行测试
$ hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.2.jar wordcount /user/lvjianzhao/test/a.txt /user/lvjianzhao/test/output
# 命令行查看统计结果
$ hdfs dfs -cat /user/lvjianzhao/test/output/*
file 1
test 1
upload 1
查看cluster的web界面
访问8088端口(访问的是mapreduce的管理页面,我这里也就是resourcemanager所在节点的8088端口),如下:
如下,可以看到日志,则说明日志聚合功能配置无误:
至此,集群验证完毕。
查看各个文件的配置模板
hadoop二进制包中提供了各个配置文件中支持的所有参数及参数详细解释,那么怎么找到这些文件呢?请看如下:
$ /apps/usr/hadoop-2.9.2 # 进入hadoop家目录
$ find . -name "*xml*" | grep default # 这样即可查看到hadoop支持的所有配置
./share/hadoop/httpfs/tomcat/webapps/webhdfs/WEB-INF/classes/httpfs-default.xml
./share/doc/hadoop/hadoop-yarn/hadoop-yarn-common/yarn-default.xml
./share/doc/hadoop/hadoop-project-dist/hadoop-common/core-default.xml
./share/doc/hadoop/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
./share/doc/hadoop/hadoop-project-dist/hadoop-hdfs-rbf/hdfs-rbf-default.xml
./share/doc/hadoop/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml