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写数据流程
(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读数据流程
(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的合并。
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这个文件就是实时更新的文件
2NN的元数据存储
/opt/module/hadoop-3.1.3/data/namesecondary/current
6、Fsimage和Edits解析
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、集群安全模式
(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工作机制
(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。
11、DataNode掉线时参数设置
需要注意的是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>