Hadoop理论
hadoop的优势
1.高可靠性:维护了多个数据副本,即使某个节点出现错误也不会导致数据丢失。
2. 高扩展性:集群间分配任务数据,可以方便扩展节 点。
3. 高效性:在MapReduce的思想下,Hadoop是并行工作的。
4. 高可靠性:能够自动将失败的任务重新分配给其他节点。
5. 适合批处理:移动计算而非数据,将数据位置暴露给计算框架(数据块Block,每个数据块有一个Id标识);
6. 保证数据一致性(参考);
VM集群配置的基本步骤
- 安装虚拟机,设置主机名,配置网络。参考
- 最小系统需要安装软件仓库,工具包(ifconfig等命令),vim(编辑器)
2.1 yum install -y epel-release
2.2 yum install -y net-tools
2.3 yum install -y vim - 关闭防火墙
3.1关闭防火墙 systemctl stop firewalld
3.2关闭防火墙自启动 systemctl disable firewalld.service - 创建用户(xrl),修改其权限
4.1设置用户 useradd xrl
4.2设置密码 passwd xrl
4.3配置权限,在/etc/sudoers文件的%wheel ALL=(ALL) ALL这一行下面插入 xrl ALL=(ALL) NOPASSWD:ALL - 创建软件放置的位置:
5.1 在/opt目录下mkdir ./module ./software文件夹
5.2修改两个文件的所有者为xrl用户:chown xrl:xrl 【文件夹路径】 - 安装jdk:
6.1 如果有jdk先删除:rpm -qa | grep -i java | xargs -n1 rpm -e --nodeps 然后重启虚拟机reboot
【rpm -qa:查询所安装的所有rpm软件包】
【grep -i:忽略大小写】
【xargs -n1:表示每次只传递一个参数】
【rpm -e –nodeps:强制卸载软件】
6.2 利用Shell,将文件导入/opt/software/目录。并解压到/opt/module目录,tar -zxvf jdk-8u212-linux-x64.tar.gz -C /opt/module/ - 安装hadoop
7.1 利用Shell,将文件导入/opt/software/目录。并解压到/opt/module目录,tar -zxvf hadoop-3.3.1.tar.gz -C /opt/module/ - 配置环境变量
8.1 sudo vim /etc/profile.d/my_env.sh 创建一个文件,存放我们配置的环境变量。
8.2 添加内容:export 是将变量发布,$ PATH:$JAVA_HOME/bin向PATH后面追加环境变量
#JAVA_HOME
export JAVA_HOME=/opt/module/jdk1.8.0_212
export PATH=$ PATH:$JAVA_HOME/bin
#HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-3.3.1
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
8.3 让环境变量生效 source /etc/profile
8.4 测试:hadoop version 、jdk version 不能使用则重启虚拟机;
- 复制三台虚拟机,修改ip地址和主机名称;
- SSH免密登录配置:
10.1 在hadoop102上用xrl用户操作:cd /home/atguigu/.ssh
10.2 生成公钥(id_rsa.pub)和私钥(id_rsa):ssh-keygen -t rsa
10.3 将公钥拷贝的想要免密登录的目标机器102、103、10.4:ssh-copy-id hadoop102
10.5:然后在hadoop103,hadoop104、hadoop102的root用户上进行相同操作,
修改hadoop配置文件
- 默认文件 存储路径
[core-default.xml] hadoop-common-3.3.1.jar/core-default.xml
[hdfs-default.xml] hadoop-hdfs-3.3.1.jar/hdfs-default.xml
[yarn-default.xml] hadoop-yarn-common-3.3.1.jar/yarn-default.xml
[mapred-default.xml] hadoop-mapreduce-client-core-3.3.1.jar/mapred-default.xml - 自定义配置文件在$HADOOP_HOME/etc/hadoop这个路径下,有:core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml
- 核心配置文件core-site.xml:
<!-- 指定NameNode的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop102:9000</value>
</property>
<!-- 指定hadoop数据的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-3.3.1/data</value>
</property>
<!-- 配置HDFS网页登录使用的静态用户为xrl,可以在web界面上操作HDFS-->
<property>
<name>hadoop.http.staticuser.user</name>
<value>xrl</value>
</property>
<!-- 主类的配置,如果启动报找不到类的错误配置-->
<property>
<name>yarn.application.classpath</name>
<value>/opt/module/hadoop-3.3.1/etc/hadoop:/opt/module/hadoop-3.3.1/share/hadoop/common/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/common/*:/opt/module/hadoop-3.3.1/share/hadoop/hdfs:/opt/module/hadoop-3.3.1/share/hadoop/hdfs/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/hdfs/*:/opt/module/hadoop-3.3.1/share/hadoop/mapreduce/*:/opt/module/hadoop-3.3.1/share/hadoop/yarn:/opt/module/hadoop-3.3.1/share/hadoop/yarn/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/yarn/*</value>
</property>
- HDFS配置文件hdfs-site.xml:
<configuration>
<!-- 文件副本数-->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<!-- nn web端访问地址-->
<property>
<name>dfs.namenode.http-address</name>
<value>hadoop102:9870</value>
</property>
<!-- 2nn web端访问地址-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hadoop104:9868</value>
</property>
</configuration>
- YARN配置文件yarn-site.xml:
<configuration>
<!-- 指定MR走shuffle -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 指定ResourceManager的地址-->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop103</value>
</property>
<!-- 开启日志聚集功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 设置日志聚集服务器地址 -->
<property>
<name>yarn.log.server.url</name>
<value>http://hadoop102:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间为7天 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
- MapReduce配置文件mapred-site.xml
<configuration>
<!-- 指定MapReduce程序运行在Yarn上 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 历史服务器端地址 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop102:10020</value>
</property>
<!-- 历史服务器web端地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>hadoop102:19888</value>
</property>
</configuration>
- 配置workers,hadoop2.X版本是slaves文件,添加以下内容
hadoop102
hadoop103
hadoop104
- 分发配置xsync ./
基本测试(格式化、启动、停止),hadoop-3.3.1目录下:
13.1 格式化NameNode:hdfs namenode -format;如果不是第一次格式化需要停止NameNode和DataNode,删除所有机器上的data和logs目录,否则因为格式化后NameNode中保存了集群id,启动集群后DataNode也会保存与NameNode一样的集群id,如果再次格式化NameNode会新生成一个集群id,这个集群id与为删除的DataNode中的集群id不一致。
13.2 启动hdfs:sbin/start-dfs.sh
13.3 启动yarn:sbin/start-yarn.sh
13.4 查看hdfs和yarn的web页面:http://hadoop102:9870,http://hadoop103:8088
13.5 创建一个文件夹,hadoop fs -mkdir /input
13.6 上传一个文件,hadoop fs -put /opt/software/jdk-8u212-linux-x64.tar.gz /
13.7 在目录下有test文件,执行wordcount程序 :hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar wordcount /input /test;观察http://hadoop102:19888/jobhistory历史服务器历史任务。
14. 集群启动/停止方式:
14.1 整体停止/启动HDFS:start-dfs.sh/stop-dfs.sh
14.1 整体停止/启动YARN:start-yarn.sh/stop-yarn.sh
14.3 分别启动/停止hdfs组件:hadoop-daemon.sh start/stop 【namenode/datanode…】
14.4 别启动/停止YARN:yarn --daemon start/stop resourcemanager/nodemanager
15. 集群时间同步
集群脚本编写/home/xrl/bin目录下:
- 集群分发脚本xsync,创建xsync文件写入以下内容:
#!/bin/bash
#1. 判断参数个数
if [ $# -lt 1 ]
then
echo Not Enough Arguement!
exit;
fi
#2. 遍历集群所有机器
for host in hadoop102 hadoop103 hadoop104
do
echo ==================== $host ====================
#3. 遍历所有目录,挨个发送
for file in $@
do
#4. 判断文件是否存在
if [ -e $file ]
then
#5. 获取父目录
pdir=$(cd -P $(dirname $file); pwd)
#6. 获取当前文件的名称
fname=$(basename $file)
ssh $host "mkdir -p $pdir"
rsync -av $pdir/$fname $host:$pdir
else
echo $file does not exists!
fi
done
done
1.1 修改xsync的执行权限:chmod +x xsync
1.1 将脚本复制到bin中,以便全局调用:sudo cp xsync /bin/
1.1同步环境变量配置 sudo ./bin/xsync /etc/profile.d/my_env.sh
1.1 让环境变量生效:source /etc/profile
1.1 测试分发:xsync /home/xrl/bin;观察hadoop103 104上是否有这个文件了。
- Hadoop集群启停脚本myhadoop.sh:
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No Args Input..."
exit ;
fi
case $1 in
"start")
echo " =================== 启动 hadoop集群 ==================="
echo " --------------- 启动 hdfs ---------------"
ssh hadoop102 "/opt/module/hadoop-3.3.1/sbin/start-dfs.sh"
echo " --------------- 启动 yarn ---------------"
ssh hadoop103 "/opt/module/hadoop-3.3.1/sbin/start-yarn.sh"
echo " --------------- 启动 historyserver ---------------"
ssh hadoop102 "/opt/module/hadoop-3.3.1/bin/mapred --daemon start historyserver"
;;
"stop")
echo " =================== 关闭 hadoop集群 ==================="
echo " --------------- 关闭 historyserver ---------------"
ssh hadoop102 "/opt/module/hadoop-3.3.1/bin/mapred --daemon stop historyserver"
echo " --------------- 关闭 yarn ---------------"
ssh hadoop103 "/opt/module/hadoop-3.3.1/sbin/stop-yarn.sh"
echo " --------------- 关闭 hdfs ---------------"
ssh hadoop102 "/opt/module/hadoop-3.3.1/sbin/stop-dfs.sh"
;;
*)
echo "Input Args Error..."
;;
esac
2.1 chmod +x myhadoop.sh
2.2 分发这个脚本 xsync ./
- jpsall查看节点类型
#!/bin/bash
for host in hadoop102 hadoop103 hadoop104
do
echo =============== $host ===============
ssh $host jps
done
3.1 chmod +x jpsall
3.2 分发这个脚本 xsync ./
Hdoop-HDFS
定义
1. HDFS的是基于流数据模式访问(来了一点数据,就立马处理掉,立马分发到各个存储节点来响应分析、查询等,重点关注数据的吞吐量而不是访问速度)和处理超大文件的需求而开发的一个主从架构的分布式文件系统(分布式文件系统:一种允许文件透过网络在多台主机上分享的文件系统,可让多机器上的多用户分享文件和存储空间);
2. 流式数据: 将数据序列化为字节流来存储;
3. 序列化:对文件进行切片就需要该文件支持序列化;
4. 存储文件,通过目录树定位文件;
6. 适合一次写入,多次读出的场景。一个文件只能有一个写者,只能进行append追加内容,不能修改。
优缺点
优点
1. 高容错性:数据保存了多个副本,一个副本丢失或者损坏,可以自动恢复,默认保存三个副本。
2. 适合处理大数据,可以处理的数据规模和文件规模巨大。
3. 可以构建在廉价机器上,数据保存多副本的机制提高了可靠性
4. 适合处理离线数据,不适合处理实时数据。
5. 可以处理:结构化(关系型)、半结构化(word,ppt)、非结构化(视频,音频)数据;
缺点
7. 不适合低延时的数据访问;(hadoop针对高数据吞吐量做了优化,牺牲了获取数据延迟)
8. 无法高效的对小文件进行存储。因为,大量的小文件会大量占用NameNode的内存来存储文件目录和块信息。并且会影响文件存储地址的寻址时间。解决办法:通过SequenceFile 将小文件合并。
9. 不支持并发写入和文件随机修改,只支持数据的追加,不能修改。
组成架构
HDFS 具有主/从架构。
NameNode(nn):
- 处理客户端的读写请求。
- 管理数据块(Block)的映射信息。每个文件的块列表和块所在的DataNode等;
- 配置副本策略;
- 储存文件的元数据(文件、目录自身的属性信息,例如文件名,目录名,修改信息等;文件记录的信息的存储相关的信息,例如存储块信息,分块情况,副本个数等;记录 HDFS 的 Datanode 的信息,用于 DataNode 的管理);
- 负责管理数据块的副本,按一定周期,接受来自每个DataNode的心跳信号和块状态报告。心跳用于判断datanode是否正常,块状态报告则关于某个datanode上存储的所有数据块的列表.。
DataNode(dn):
- 存储实际的数据块。
- 执行NameNode的下达的命令,执行数据块的读写操作。
- 在启动时向NameNode进行注册并周期性(默认6小时)的向NameNode上报所有块信息。
- 周期性的扫描自己节点块的信息(默认6小时)。
- 向DataNode维持(默认三秒)的心跳(带有 Block块的使用情况),NameNode返回心跳的结果(带有NameNode该给哪个DataNode的命令,如复制块数据到另一台机器,或删除某个块数据),如果超过十分钟+30秒(默认,超时时间 = 2* dfs.namenode.heartbeat.recheck-interval(超时时长,默认5分钟)+ dfs.heartbeat.interval(心跳时长,3s))NameNode没有收到某个DataNode的心跳,则认为该节点不可用,NameNode会检查不可用的DeadNode中的副本数据,复制到其他的DeadNode中。
- DataNode还有一个自检功能,数据块创建3周后,自动触发校验和运算,以保证集群中数据块的安全。
数据块(Block):
- HDFS中文件是分块存储的,数据块以文件的方式存储了实际数据;
- 默认存在三个副本;查看(hdfs fsck -locations),可以通过hdfs-site.xml配置文件修改(dfs.replication),可以通过命令修改已上传的文件副本数(hadoop fs -setrep -R 3 /),可以上传文件时指定(hdfs dfs -Ddfs.replication=1 -put core-site.xml /)
3.块的大小默认为128MB,最佳状态为:寻址时间为传输时间的1%。大小主要取决于磁盘传输速率(不宜太小也不宜太大)。机械硬盘一般设置为128MB,固态一般设置为256MB - 包含两个文件:一个是数据本身,另一个是数据快的长度,时间戳和数据快的校验和(CRC算法计算校验和,保证数据的完整性)
Secondary(2nn):
- 每隔一段时间对NameNode进行备份,并帮助NameNode进行Edits和Fsimage进行合并,生成新的Fsimage并拷贝到NameNode中。紧急情况下可辅助恢复NameNode。
- Edits(日志文件):记录HDFS文件系统的更新操作,客户端执行的操作会先被记录到Edits文件中,Edits文件只能追加内容。
- Fsimage(镜像):是元数据的一个持久化的检查点,包含 Hadoop 文件系统中的所有目录和文件元数据信息,但不包含文件块位置的信息。文件块位置信息只存储在内存中,是在 datanode 加入集群的时候,namenode 询问 datanode 得到的,并且间断的更新。
Client(客户端):
- 文件切分。文件上传HDFS的时候Client将文件切分成一个一个的Bock,然后进行上传;
- 与NameNode交互,获取文件的位置信息;
- 与DataNode交互,读取或者写入数据:
- Client提供一些命令来管理DFS,比NameNode格式化、磁盘整理等;
- Client可以通过一些命令来访问HDFS,比如:对HDFS增删改查操作;
工作流程
HDFS数据读写流程
HDFS数据写入流程
-
Client(客户端)先创建一个DistributedFileSystem(分布式的文件系统),向NameNode请求上传文件。
-
NameNode对Client请求上传文件路径的权限和结构(是否已经存在)进行检查,并给与Client回复。
-
Client收到NameNode的允许上传的回复,则向NameNode请求上传,文件切分生成的数据块(Block)。
-
NameNode收到Block上传的请求,通过机架感知算法计算出存储数据的节点(默认三个),回复给Client。
-
Client收到NameNode的回复后,创建FSDataOutputStream数据流系统,并向DataNode请求建立Block传输通道(只向一个DataNode请求,通过DataNode的节点距离和负载情况选择,然后由这个DataNode节点再向其他DataNode节点请求建立通道,通道建立成功,给请求建立通道的节点应答成功,所有节点应答成功后,由于Client建立通道的节点给Client回复应答成功)。
-
Client收到DataNode的应答成功信号,往第一个DataNode上传Block【先从磁盘读取数据(有一个一个与chunk大小相同的缓存ByteBuffer,读满或者强制flush后会计算出一个chunksum(校验码)】放到一个本地内存缓存中【chunk(512byte数据 )+chunksum (4byte校验位)】,从内存中读取chunk组成一个Packet【chunk + chunksum = 516byte,组合成一个packet(64k)】放入一个缓冲队列中,然后以Packet为单位,从缓冲队列中取出数据往DataNode上传(生产者消费者模式),第一个DataNode收到一个Packet就会传给后面的节点,每传一个Packet会放入一个ACK队列(缓冲队列)等待所有需要存储这个数据的DataNode节点全部应答成功后,在ACK队列中将这个数据删除。
6.1数据缓存说明:做了三层缓存chunk、packet、packetBufferQueue;
6.2数据安全:使用了一个ACK队列记录要上传的packet,防止传输过程中传输失败或异常导致数据丢失;
6.3使用了生产者消费者模式,来从packetBufferQueue中添加或取出数据,阻塞生产者的条件是packetBufferQueue+ACK之和超过一个Block的packet上限。 -
细节:
1.请求和应答是使用RPC的方式,客户端通过ClientProtocol与namenode:通信,namenode和datanode之间使用DatanodeProtocol交互。在设计上,namenode不会主动发起RPC,而是响应来自客户端或datanode的RPC请求。客户端和datanode之间是使用socket进行数据传输,和namenode之间的交互采用nio封装的RPC。
2.HDFS有自己的序列化协议。
3.在数据块传输成功后但客户端没有告诉namenode之前如果namenode宕机那么这个数据块就会丢失。
4.在流式复制时,逐级传输和响应采用响应队列来等待传输结果。队列响应完成后返回给客户瑞
5.在流式复制时如果有一台或两台(不是全部)没有复制成功,不影响最后结果,只不过datanode会定期向namenode汇报自身信息。如果发现异常namenode会指挥datanode删除残余数据和完善副本。如果副本数量少于某个最小值就会进入安全模式。
节点距离:两个节点到达最近的共同服务器的距离总和。
机架感知:
查看代码:hdfs dfsadmin -printTopology
官网说明:对于常见情况,当复制因子为三个时,HDFS的位置策略是在dataNode上,在本地计算机上放置一个副本,否则在随机datanode上,在其他(远程)机架中的节点上的另一个副本, ,以及同一远程机架中不同节点上的最后一个。该策略削减了机间写入流量,通常会改善写作绩效。机架故障的机会远低于节点故障。该策略不会影响数据可靠性和可用性保证。但是,由于仅将块放置在两个唯一的机架中,而不是三个。通过此策略,文件的复制品不会在机架上均匀分布。三分之一的复制品是在一个节点上,三分之二的复制品在一个架子上,另一个副本均匀分布在其余的架子上。该策略可改善读写性能,而不会损害数据可靠性或读写性能。
第一个保证读写效率,第二个保证可靠性,第三个在保证可靠性的条件下兼顾效率。
HDFS读数据
- Client创建DistributedFileSystem ----发送读请求(读取文件的路径)----> NameNode
- NameNode对请求信息进行检查(文件是否存在,访问权限等),可以读 -----返回文件的元数据(文件元数据信息,文件块位置信息等)----->Client
- Client创建FSDataOutputStream数据流系统,然后根据NameNode回复的信息(构成文件的文件块顺序、文件块位置等)串行读取数据(DataNode以chunk为单位输出,Client以Packet为单位接收,先在本地缓存,然后写入目标文件)。读取数据时存在多个副本,读取节点根据节点距离和负载情况进行选择。
NameNode和SecondaryNameNode工作机制
NameNode工作:
- 第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载Fsimage和Edits文件到内存(将Fsimage文件读入内存,加载Edits里面的更新操作)。保证内存中的元数据是最新的、同步的。
中的元数据信息是最新的、同步的。 - seen_txid,保存的是一个事务ID,这个事务ID是EditLog最新的一个结束事务id,当NameNode重启时,会顺序遍历从edits_0000000000000000001到seen_txid所记录的txid所在的日志文件,进行元数据恢复,如果该文件丢失或记录的事务ID有问题,会造成数据块信息的丢失;
- clent对元数据进行增删改的请求。
- NameNode中的Edits文件记录操作日志,更新滚动日志(往后追加不能修改)。
- 在内存中对元数据进行增删改。
Secondary NameNode工作:
- Secondary NameNode询问NameNode是否需要CheckPoint。触发条件:周期时间(默认一小时)到了,Edits数据(默认一百万条)满了。
- Secondary NameNode请求执行CheckPoint。
- NameNode保存当前的Edits文件,并生成一个新的Edits文件NewEdits,之后的操作记录到NewEdits中。
- 将滚动前的Fsimage和Edits文件拷贝到Secondary NameNode。
- Secondary NameNode加载Fsimage和Edits文件到内存,并合并。
- 生成新的镜像文件fsimage.chkpoint,并将fsimage.chkpoint通过RPC传回NameNode。
- NameNode将fsimage.chkpoint重新命名成fsimage。
- 之后NameNode将fsimage和NewEdits文件加载到内存就可以得到最新的元数据。
NameNode和Secondary NameNode相差最新的Edits,如果使用Secondary NameNode恢复NameNode数据,这部分的数据更新操作会丢失。
负载均衡
- 解决的问题:DataNode节点之间容易出现数据存储不平衡(数据倾斜)的情况,例如:当集群内新增、删除节点、某个节点的数据块损坏、或者某个节点的存储量达到饱和值时都会导致数据倾斜的情况。当存在数据倾斜时,使用MapReduce进行分布式运算时,如果运算任务如果分配到存储数据很少的节点上,会导致网络带宽的消耗,分配到存储数据很多的节点时,会导致得到运算结果所需要的时长增加。
- 原则:当HDFS负载不均衡时,需要对HDFS进行数据的负载均衡调整,即对各DataNode节点上数据的存储分布进行调整。从而,让数据均匀的分布在各个DataNode上,均衡IO性能。它应该满足以下几个原则:
1.数据平衡不能导致数据块减少,数据块备份丢失;
2.管理员可以中止数据平衡进程;
3.每次移动的数据量以及占用的网络资源,必须是可控的(不影响Hadoop使用);
4.数据均衡过程,不能影响namenode的正常工作; - 运行步骤:
(1)数据均衡服务(Rebalancing Server)首先要求 NameNode 生成 DataNode 数据分布分析报告,获取每个DataNode磁盘使用情况;
(2)Rebalancing Server汇总需要移动的数据分布情况;
——2.1 HDFS会把当前的DataNode节点,根据设定的阈值和当前集群的平均值,将其划分到Over(高于阈值,数据过多)、Above(高于平均值)、Below(低于平均值)、Under(低于阈值,数据过少)四个组中。在移动数据块的时候,Over组、Above组中的块向Below组、Under组移动。
(3)计算具体数据块迁移路线图。数据块迁移路线图,确保网络内最短路径(节点距离最近,提高数据传输效率);
(4)开始数据块迁移任务,Proxy Source Data Node复制一块需要移动数据块;
(5)将复制的数据块复制到目标DataNode上(通过校验码保证数据的准确性);
(6)删除原始数据块;
(7)目标DataNode向Proxy Source Data Node确认该数据块迁移完成;
(8)Proxy Source Data Node向Rebalancing Server确认本次数据块迁移完成。然后继续执行这个过程,直至集群达到数据均衡标准; - 运行
4.1 启动start-balancer.sh
-threshold:判断集群是否平衡的阈值,可以不指定,默认为10。
4.2 停止 stop-balancer.sh
4.3 在hdfs-site.xml文件中可以设置数据均衡占用的网络带宽限制(确保hadoop可以正常使用):
<property>
<name>dfs.balance.bandwidthPerSec</name>
<value>1048576</value>
</property>
4.5 定时任务
00 22 * * 5 hdfs balancer -Threshold 5 >>/home/logs/balancer_`date +"\%Y\%m\%d"`.log
安全模式
- 安全模式指在不加载第三方设备驱动情况下启动机器,便于检测与修复
- 应用场景:①启动或者重新启动hdfs时;②HDFS维护升级时
- 操作:
退出安全模式:hdfs dfsadmin -safemode leave
进入安全模式 :hdfs dfsadmin -safemode enter
查看安全模式状态:hdfs dfsadmin -safemode get
等待,直到安全模式结束:hdfs dfsadmin -safemode wait
文件系统检查
hdfs fsck 【文件路径】
-move: 移动损坏的文件到/lost+found目录下
-delete: 删除损坏的文件
-files: 输出正在被检测的文件
-openforwrite: 输出检测中的正在被写的文件
-includeSnapshots: 检测的文件包括系统snapShot快照目录下的
-list-corruptfileblocks: 输出损坏的块及其所属的文件
-blocks: 输出block的详细报告
-locations: 输出block的位置信息
-racks: 输出block的网络拓扑结构信息
-storagepolicies: 输出block的存储策略信息
-blockId: 输出指定blockId所属块的状况,位置等信息
API实现步骤和源码(参考)
部分配置设置
- Secondary NameNode和NameNode,CheckPoint条件设置(hdfs-site.xml):
1.1 时间:< name > dfs.namenode.checkpoint.period< /name >
1.2 操作次数:< name > dfs.namenode.checkpoint.txns < /name >
1.3 检查一次操作次数间隔时长:< name > dfs.namenode.checkpoint.check.period< /name> - DataNode向NameNode汇报节点信息周期时间和扫描自己节点块信息列表的时间设置:
2.1汇报节点信息周期时间:< name> dfs.blockreport.intervalMsec < /name>
2.2扫描自己节点块信息列表的周期时间:< name>dfs.datanode.directoryscan.interval< /name> - DataNode掉线时限参数设置:
3.1超时时长(毫秒): < name>dfs.namenode.heartbeat.recheck-interval< /name>
3.2心跳时长(秒)< name>dfs.heartbeat.interval</ name>
基本Shell命令和API操作
基本文件系统Shell命令(官方文档):
hadoop fs == hdfs dfs
- 上传
1.1 从本地剪切:hadoop fs -moveFromLocal 【本地文件路径】 【HDFS路径】
1.2 从本地拷贝:hadoop fs -copyFromLocal 【本地文件路径】 【HDFS路径】
1.3 从本地拷贝:hadoop fs put 【本地文件路径】 【HDFS路径】
1.4 追加一个文件到另一个文件末尾:hadoop fs -appendToFile 【追加文件路径】 【待追加文件路径】 - 下载
2.1:hadoop fs -copuToLocal 【HDFS文件路径】 【本地路径】
2.2:hadoop fs -get 【HDFS文件路径】 【本地路径】 - 显示目录信息:hadoop fs -ls 【查看目录路径】
- 查看文件内容:hadoop fs -cat 【文件路径】
- 显示文件末尾1kb数据:hadoop fs -tail 【文件路径】
- 创建路径:hadoop fs -mkdir 【目录路径】
- 拷贝文件:hadoop fs -cp 【原文件路径】【文件路径】
- 移动文件:hadoop fs -mv 【文件路径】 【移动到(路径)】
- 删除文件或文件夹:hadoop fs -rm 【文件路径】
9.1 hadoop fs -rm -r【文件路径】(递归删除) - 统计文件大小:hadoop fs -du 【文件目录路径】
- 查询某一个文件所占用块数及相关的数据信息:hdfs fsck 【文件路径】 -files -locations -includeSnapshots -blocks -racks -storagepolicies
- 设置HDFS中的文件副本数量: hadoop fs -setrep 【副本数量】 【修改文件的路径】
- 文件权限操作:
12.1 权限设置:hadoop fs -chmod 666 【文件路径】
12.2 文件所属者设置:hadoop fs -chown xrl:xrl 【文件路径】 - 查看Fsimage和Edits,hadoop-3.3.1/data/tmp/dfs/name/current目录下:
13.1 hdfs oiv -p 文件类型 -i镜像文件 -o 转换后文件输出路径
13.1.1 hdfs oiv -p XML -i fsimage_0000000000000000025 -o /opt/module/hadoop-3.3.1/fsimage.xml
13.1.2 cat /opt/module/hadoop-3.3.1/fsimage.xml
13.2 hdfs oev -p 文件类型 -i编辑日志 -o 转换后文件输出路径
13.2.1 hdfs oev -p XML -i edits_0000000000000000012-0000000000000000013 -o /opt/module/hadoop-3.3.1/edits.xml
13.2.2 cat /opt/module/hadoop-3.3.1/edits.xml - version查看版本:hadoop version
- classpath查看类路径: hadoop classpath
HDFS命令 (参考)(官方文档)
- 格式化、启动、停止参考上文中VM集群配置的基本步骤中的基本测试;
- hdfs dfsadmin 命令集
- hdfs fsck 运行HDFS文件系统检查工具
- hdfs getconf 命令集
- hdfs jar 运行jar文件。用户可以把他们的Map Reduce代码捆绑到jar文件中,使用这个命令执行。
- hdfs job 用于和Map Reduce作业交互和命令。
- hdfs balancer
API操作:
HA(High Available)机制
解决问题
只有一个NameNode节点时,如果NameNode挂掉时,集群基本不可用。(单点故障)
NameNode的内存有限(内存受限)
NameNode高可用(HA)
架构图
- 使用了两个NameNode架构,解决了单点故障问题;
- 借助了共享存储系统(JournalNode集群)来保证元数据的同步,共享存储系统类型一般有几类,如:Shared NAS+NFS、BookKeeper、BackupNode 和 Quorum Journal Manager(QJM)
- 使用了zookeeper来进行选举active节点;
QJM(Quorum Journal Manager)共享存储机制和主备切换机制(参考)
配置修改
配置zookeeper集群
- 进入conf目录,修改zoo_sample.cfg并重命名zoo.cfg:mv zoo_sample.cfg zoo.cfg;
- 修改zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
# 数据存储地址,提前创建这个目录(注意目录权限)
dataDir=/opt/module/zookeeper-3.7.0/zkData
# 配置zookeeper集群的服务器编号以及对应的主机名、通信端口号(心跳端口号)和选举端口号
server.1=hadoop102:2888:3888
server.2=hadoop103:2888:3888
server.3=hadoop104:2888:3888
clientPort=2181
- 在dataDir=/opt/module/zookeeper-3.7.0/zkData这个目录下创建myir文件,haoop102设置1,103设置2,以此类推;
- 修改环境变量/etc/profile.d/my_env.sh
export ZK_HOME=/opt/module/zookeeper-3.7.0
export PATH=$PATH:$ZK_HOME/bin
- 编写启动、停止脚本
#!/bin/bash
case $1 in
"start"){
for i in hadoop102 hadoop103 hadoop104
do
echo ---------- zookeeper $i 启动 ------------
ssh $i "/opt/module/zookeeper-3.7.0/bin/zkServer.sh start"
done
};;
"stop"){
for i in hadoop102 hadoop103 hadoop104
do
echo ---------- zookeeper $i 停止 ------------
ssh $i "/opt/module/zookeeper-3.7.0/bin/zkServer.sh stop"
done
};;
"status"){
for i in hadoop102 hadoop103 hadoop104
do
echo ---------- zookeeper $i 状态 ------------
ssh $i "/opt/module/zookeeper-3.7.0/bin/zkServer.sh status"
done
};;
esac
- 运行
配置文件修改
- core-site.xml
<configuration>
<!-- 指定NameNode:的地址 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://xrlhadoop</value>
</property>
<!-- 指定hadoop数据的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-3.3.1/data</value>
</property>
<!-- 配置HDFS网页登录使用的静态用户为xrl-->
<property>
<name>hadoop.http.staticuser.user</name>
<value>xrl</value>
</property>
<!--zookeeper集群地址,集群以逗号进行分隔-->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<!-- hadoop链接zookeeper的超时时长设置 -->
<property>
<name>ha.zookeeper.session-timeout.ms</name>
<value>2000</value>
<description>ms</description>
</property>
</configuration>
- hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!--权限配置, 可以控制各用户之间的权限,这里先关掉 -->
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
<!--指定hdfs的nameservice为cluster1,需要和core-site.xml中的保持一致
dfs.ha.namenodes.[nameservice id]为在nameservice中的每一个NameNode设置唯一标示符。
配置一个逗号分隔的NameNode ID列表。这将是被DataNode识别为所有的NameNode。
例如,如果使用"cluster1"作为nameservice ID,并且使用"nn1"和"nn2"作为NameNodes标示符-->
<property>
<name>dfs.nameservices</name>
<value>xrlhadoop</value>
</property>
<!-- xrlhadoop下面有2个NameNode,分别是nn1,nn2-->
<property>
<name>dfs.ha.namenodes.xrlhadoop</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.xrlhadoop.nn1</name>
<value>hadoop102:8020</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.xrlhadoop.nn1</name>
<value>hadoop102:50070</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.xrlhadoop.nn2</name>
<value>hadoop104:8020</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.xrlhadoop.nn2</name>
<value>hadoop104:50070</value>
</property>
<!-- 指定NameNode的edits元数据的共享存储位置。也就是JournalNode列表
该url的配置格式:qjournal://host1:port1;host2:port2;host3:port3/journalId
journalId推荐使用nameservice,默认端口号是:8485 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop102:8485;hadoop103:8485;hadoop104:8485/xrlhadoop</value>
</property>
<!-- 指定JournalNode在本地磁H的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/journal/node/local/data</value>
</property>
<!-- 开启NameNode失败自动切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置失败自动切换实现方式 -->
<property>
<name>dfs.client.failover.proxy.provider.xrlhadoop</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence
shell(/bin/true)
</value>
</property>
<!-- 使用sshfence隔离机制时需要ssh免登陆 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<!-- 配置sshfence隔离机制超时时间 -->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
<property>
<name>ha.failover-controller.cli-check.rpc-timeout.ms</name>
<value>60000</value>
</property>
</configuration>
启动步骤
- Hadoop处于关闭状态;
- 安装系统插件:yum -y install psmisc;
- 启动zookeeper;
- 删除所有节点的$HADOOP_HOME下的:rm -rf data/ logs/ ;
- 启动JN:hadoop-daemon.sh start journalnode
- 格式化NameNode:在一台namenode( namenode1或namenode2)中执行格式化命令:hdfs namenode -format
- 在另一台namenode同步数据前先要启动 第10步中格式化的 namenode:hadoop-daemon.sh start namenode
- 在其它没有格式化的namenode上执行:hdfs namenode -bootstrapStandby
- 在一台namenode上执行格式化zookeeper:hdfs zkfc -formatZK
- 测试zk是否成功格式,且启动 :zkCli.sh -server hadoop102:2181
- 脚本启动zk集群和Hadoop集群:zk.sh start / myhadoop.sh start
- 用jpsall脚本查看各个服务启动情况:DFSZKFailoverController
(故障恢复,它与namenode在一个节点上,当一个节点失败时,自动恢复) - 查看:http://hadoop102:50070,http://hadoop104:50070 一个为Active一个为Standby
- 关闭为Active的NameNode节点:hadoop-daemon.sh stop namenode,观察Standby是否转为Active;
YARN高可用(HA)
修改配置文件yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<!-- 环境变量的继承 -->
<!--<property>
<name>yarn.nodemanager.env-whitelist</name>
<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
</property>
<!-- 开启日志聚集功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 设置日志聚集服务器地址 -->
<property>
<name>yarn.log.server.url</name>
<value>http://hadoop102:19888/jobhistory/logs</value>
</property>
<!-- 设置日志保留时间为7天 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
<property>
<name>yarn.application.classpath</name>
<value>/opt/module/hadoop-3.3.1/etc/hadoop:/opt/module/hadoop-3.3.1/share/hadoop/common/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/common/*:/opt/module/hadoop-3.3.1/share/hadoop/hdfs:/opt/module/hadoop-3.3.1/share/hadoop/hdfs/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/hdfs/*:/opt/module/hadoop-3.3.1/share/hadoop/mapreduce/*:/opt/module/hadoop-3.3.1/share/hadoop/yarn:/opt/module/hadoop-3.3.1/share/hadoop/yarn/lib/*:/opt/module/hadoop-3.3.1/share/hadoop/yarn/*</value>
</property>
<!--开启高可用-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 指定RM的cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>xrlyarn</value>
</property>
<!-- 指定RM的名字 -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 分别指定RM的地址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop103</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop104</value>
</property>
<!-- 指定zk集群地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
</property>
<!--Reducer获取数据的方式-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 启用自动恢复 -->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!-- 制定resourcemanager的状态信息存储在zookeeper集群上 -->
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<!-- 解决hadoop执行MapReduce程序时Ha和yarn的冲突 YarnRuntimeException: java.lang.NullPointerException -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop103:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop104:8088</value>
</property>
</configuration>
解决hadoop执行MapReduce程序时Ha和yarn的冲突 YarnRuntimeException: java.lang.NullPointerException
启动步骤
- 关闭集群
- 删除删除所有节点的$HADOOP_HOME下的:rm -rf data/ logs/ ;
- 删除journalnode的数据:/opt/journal/node/local/data/下的xrlhadoop;
- 启动所有节点上的JND;
- 格式化一个NameNode:hadoop namenode -format
- 启动namenode:hadoop-daemon start namenode
- 在另一个NameNode上同步格式好的NameNode:hdfs namenode -bootstrapStandby
- 启动所有节点:myhadoop.sh start
- http://hadoop104:8088/ 访问 ResourceManager;注意观察进入的时哪个节点;
- 关闭网页所访问的那个节点的 ResourceManager,yarn-daemon.sh stop resourcemanager;刷新网页,无法访问到网页;改用另一个节点访问http://hadoop103:8088/成功访问,说明配置成功。