五、Hadoop三大组件-HDFS详解

五、Hadoop三大组件-HDFS详解

IT-风油精 1,113 2023-01-10

1、hdfs目录结构

文件夹名称 作用
bin 存放对hadoop相关服务(HDFS,YARN)进行操作的脚本
sbin 存放启动或停止hadoop相关服务的脚本
etc hadoop的配置文件目录,存放hadoop的配置文件
lib 存放hadoop的本地库(对数据进行压缩解压缩功能)
share 存放hadoop的依赖jar包和文档,文档可以被删除掉

2、各个配置文件的作用

core-site.xml 核心配置文件,主要定义了我们文件访问的格式 hdfs:// ;
hadoop-evn.sh 主要配置我们的java路径 ;
hdfs-site.xml 主要定义配置我们的hdfs的相关配置 ;
mapred-site.xml 主要定义我们的mapreduce相关的一些配置 ;
slaves 控制我们的从节点在哪里 datanode nodemanager在哪些机器上 ;
yarm-site.xml 配置我们的resourcemanager资源调度 。

2.1、core-site.xml

<configuration>
    <!-- 指定namenode的hdfs协议的文件系统通信地址,默认是file:///本地文件系统  需要我们改成 hdfs://分布式文件存储系统 -->
    <!-- 可以指定一个主机+端口,也可以指定为一个namenode服务(这个服务内部可以有多台namenode实现ha的namenode服务) -->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop01:9000</value>
    </property>

    <!-- 临时数据存放的位置 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/usr/local/hadoop-2.8.3/tmp</value>
    </property>

    <!-- 缓冲区大小,实际工作中根据服务器性能动态调整 -->
    <property>
        <name>io.file.buffer.size</name>
        <value>4096</value>
    </property>
    
    <!--  开启hdfs的垃圾桶机制,删除掉的数据可以从垃圾桶中回收,单位分钟  10080 相当与7天  60*24*7-->
    <property>
        <name>fs.trash.interval</name>
        <value>10080</value>
    </property>

    <!-- 故障转移需要的zookeeper集群设置一下-->
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>jokerq1:2181,jokerq2:2181,jokerq3:2181</value>
    </property>
    
</configuration>

2.2、hdfs-site.xml

<configuration>
    <!-- NameNode 数据的存放地点。也就是namenode元数据存放的地方,记录了hdfs系统中文件的元数据-->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/usr/local/hadoop-2.8.3/data/name</value>
    </property>

    <!-- NameNode 的访问地址 -->
    <property>
        <name>dfs.namenode.http-address</name>
        <value>node01:50070</value>
    </property>
    
    <!-- DataNode 数据的存放地点。也就是block块存放的目录了-->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/usr/local/hadoop-2.8.3/data/data</value>
    </property>

    <!-- HDFS 的副本数设置。也就是上传一个文件,其分割为block块后,每个block的冗余副本个数-->
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    
    <!-- HDFS 的权限控制 -->
    <property>
        <name>dfs.permissions</name>
        <value>false</value>
    </property>
    
    <!-- 文件存储的block块大小 -->
    <property>
        <name>dfs.blocksize</name>
        <value>134217728</value>
    </property>
    
    <!-- secondary NameNode 的http通讯地址-->
    <property>
        <name>dfs.secondary.http.address</name>
        <value>hadoop01:50090</value>
    </property>
    
    <!-- secondary NameNode 的访问地址 -->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>node01:50090</value>
    </property>

    <!-- 元数据操作日志的存放位置 edits的存放位置 -->
    <property>
        <name>dfs.namenode.edits.dir</name>
        <value>file:///export/servers/hadoop-2.7.5/hadoopDatas/nn/edits</value>
    </property>

    <!-- 元数据检查点保存的位置 -->
    <property>
        <name>dfs.namenode.checkpoint.dir</name>
        <value>file:///export/servers/hadoop-2.7.5/hadoopDatas/snn/name</value>
    </property>

    <property>
        <!-- 开启hdfs的web访问接口。默认端口是50070 , 一般不配 , 使用默认值-->
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
    </property>
</configuration>

2.3、hadoop-env.sh

# The java implementation to use.
export JAVA_HOME=/usr/local/jdk1.8.0_102

2.4、mapred-site.xml

<configuration>
    <!-- 指定mr框架为yarn方式,Hadoop二代MP也基于资源管理系统Yarn来运行 -->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    
    <!-- 开启mapreduce的小任务模式,用于调优 -->
    <property>
        <name>mapreduce.job.ubertask.enable</name>
        <value>true</value>
    </property>
    
    <!-- 配置mapreduce的jobhistory内部通讯地址。可以查看我们所有运行完成的任务的一些情况 -->
    <property>    
        <name>mapreduce.jobhistory.address</name>
        <value>hadoop01:10020</value>    
    </property>

    <!-- 配置mapreduce 的jobhistory的访问地址 -->
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>hadoop02:19888</value>
    </property>
    
</configuration>

2.5、Yarn-Site.xml

<configuration>
    <!-- 指定我们的resourceManager运行在哪台机器上面 -->
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>hadoop01</value>
    </property>

    <!-- NodeManager的通信方式 -->
    <property>
        <name>yarn.nodemanager.aux-services</name>
        <value>mapreduce_shuffle</value>
    </property>

    <!-- 日志的聚合功能,方便我们查看任务执行完成之后的日志记录 -->
    <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
    </property>
    <!-- 聚合日志的保存时长 -->
    <property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>604800</value>
    </property>

    <!--yarn总管理器的IPC通讯地址-->
    <property>
        <name>yarn.resourcemanager.address</name>
        <value>hadoop01:8032</value>
    </property>

    <!--yarn总管理器调度程序的IPC通讯地址-->
    <property>
        <name>yarn.resourcemanager.scheduler.address</name>
        <value>hadoop01:8030</value>
    </property>

    <!--yarn总管理器的IPC通讯地址-->
    <property>
        <name>yarn.resourcemanager.resource-tracker.address</name>
        <value>hadoop01:8031</value>
    </property>

    <!--yarn总管理器的IPC管理地址-->
    <property>
        <name>yarn.resourcemanager.admin.address</name>
        <value>hadoop01:8033</value>
    </property>

    <!--yarn总管理器的web http通讯地址-->
    <property>
        <name>yarn.resourcemanager.webapp.address</name>
        <value>singlehost:8088</value>
    </property>
    
</configuration>

3、HDFS写数据流程

图片-1673336845509
(1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在。
(2)NameNode返回是否可以上传。
(3)客户端请求第一个 Block上传到哪几个DataNode服务器上。
(4)NameNode返回3个DataNode节点,分别为dn1、dn2、dn3。
(5)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。
(6)dn1、dn2、dn3逐级应答客户端。
(7)客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
(8)当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)。

4、HDFS读数据流程

图片-1673336896297
(1)客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
(2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。
(3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
(4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

5、NN和2NN工作机制

思考:NameNode中的元数据是存储在哪里的?
首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了。因此产生在磁盘中备份元数据的FsImage。

这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦NameNode节点断电,就会产生数据丢失。因此,引入Edits文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。

但是,如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。
图片-1673336932019

5.1、第一阶段:NameNode启动

(1)第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。
(2)客户端对元数据进行增删改的请求。
(3)NameNode记录操作日志,更新滚动日志。
(4)NameNode在内存中对元数据进行增删改。

5.2、第二阶段:Secondary NameNode工作

(1)Secondary NameNode询问NameNode是否需要CheckPoint。直接带回NameNode是否检查结果。
(2)Secondary NameNode请求执行CheckPoint。
(3)NameNode滚动正在写的Edits日志。
(4)将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode。
(5)Secondary NameNode加载编辑日志和镜像文件到内存,并合并。
(6)生成新的镜像文件fsimage.chkpoint。
(7)拷贝fsimage.chkpoint到NameNode。
(8)NameNode将fsimage.chkpoint重新命名成fsimage。

5.3、NN的元数据存储的路径

/opt/module/hadoop-3.1.3/data/name/current
edits_inprogress_00000000000000000130这个文件就是实时更新的文件
图片-1673336948069
2NN的元数据存储
/opt/module/hadoop-3.1.3/data/namesecondary/current
图片-1673336961371

6、Fsimage和Edits解析

图片-1673337032313
图片-1673337037938

7、CheckPoint时间设置

7.1、通常情况下,SecondaryNameNode每隔一小时执行一次。

hdfs-default.xml

<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
</property>

7.2、一分钟检查一次操作次数,3当操作次数达到1百万时,SecondaryNameNode执行一次。

<property>
  <name>dfs.namenode.checkpoint.txns</name>
  <value>1000000</value>
<description>操作动作次数</description>
</property>

<property>
  <name>dfs.namenode.checkpoint.check.period</name>
  <value>60</value>
<description> 1分钟检查一次操作次数</description>
</property >

8、集群安全模式

图片-1673337348415
(1)基本语法
集群处于安全模式,不能执行重要操作(写操作)。集群启动完成后,自动退出安全模式。

  • bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式状态)
  • bin/hdfs dfsadmin -safemode enter (功能描述:进入安全模式状态)
  • bin/hdfs dfsadmin -safemode leave (功能描述:离开安全模式状态)
  • bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式状态)

(2)案例
模拟等待安全模式

(3)查看当前模式
[atguigu@hadoop102 hadoop-3.1.3]$ hdfs dfsadmin -safemode get
Safe mode is OFF

(4)先进入安全模式
[atguigu@hadoop102 hadoop-3.1.3]$ bin/hdfs dfsadmin -safemode enter

(5)创建并执行下面的脚本
在/opt/module/hadoop-3.1.3路径上,编辑一个脚本safemode.sh
[atguigu@hadoop102 hadoop-3.1.3]$ touch safemode.sh
[atguigu@hadoop102 hadoop-3.1.3]$ vim safemode.sh

#!/bin/bash
hdfs dfsadmin -safemode wait
hdfs dfs -put /opt/module/hadoop-3.1.3/README.txt /

[atguigu@hadoop102 hadoop-3.1.3]$ chmod 777 safemode.sh
[atguigu@hadoop102 hadoop-3.1.3]$ ./safemode.sh

(6)再打开一个窗口,执行
[atguigu@hadoop102 hadoop-3.1.3]$ bin/hdfs dfsadmin -safemode leave

(7)观察

(8)再观察上一个窗口
Safe mode is OFF

(9)HDFS集群上已经有上传的数据了

9、DataNode工作机制

图片-1673337563412
(1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。

(2)DataNode启动后向NameNode注册,通过后,周期性(1小时)的向NameNode上报所有的块信息。

(3)心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。

(4)集群运行中可以安全加入和退出一些机器。

关闭datanode的命令
hdfs --daemon stop datanode

10、数据完整性

思考:如果电脑磁盘里面存储的数据是控制高铁信号灯的红灯信号(1)和绿灯信号(0),但是存储该数据的磁盘坏了,一直显示是绿灯,是否很危险?同理DataNode节点上的数据损坏了,却没有发现,是否也很危险,那么如何解决呢?
如下是DataNode节点保证数据完整性的方法。
(1)当DataNode读取Block的时候,它会计算CheckSum。
(2)如果计算后的CheckSum,与Block创建时值不一样,说明Block已经损坏。
(3)Client读取其他DataNode上的Block。
(4)DataNode在其文件创建后周期验证CheckSum。
图片-1673337608353

11、DataNode掉线时参数设置

图片-1673337630861
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的单位为毫秒,dfs.heartbeat.interval的单位为秒。

<property>
    <name>dfs.namenode.heartbeat.recheck-interval</name>
    <value>300000</value>
</property>
<property>
    <name>dfs.heartbeat.interval</name>
    <value>3</value>
</property>