Hadoop系列 (三):HDFS详细介绍

Hadoop系列文章

Hadoop系列 (一):在CentOS中搭建hadoop环境(伪分布式)

Hadoop系列 (二):完全分布式搭建(腾讯云服务器+阿里云服务器)

Hadoop系列 (三):HDFS详细介绍

Hadoop系列 (四):Yarn详细介绍

Hadoop系列 (五):MapReduce详细介绍

Hadoop系列 (六):Spark搭建

Hadoop系列 (七):ZooKeeper详细介绍

HDFS简介

HDFS( Hadoop Distributed File System ),意为:Hadoop分布式文件系统。是Apache Hadoop核心组件之一,作为大数据生态圈最底层的分布式存储服务而存在。

用于存储和管理文件,通过统一的命名空间(类似于本地文件系统的目录树)。

HDFS是分布式的,服务器集群中各个节点都有自己的角色和职责。

HDFS基本概念

  1. HDFS是用Java语言实现的、分布式的、可扩展的文件系统。

  2. HDFS是Hadoop的三大核心(HDFS、MapReduce、YARN)和四大模块(Hadoop Common、Hadoop HDFS、Hadoop MapReduce、Hadoop YARN)之一。

  3. HDFS主要应用于海量数据的存储。

  4. HDFS的基本存储单位:块,块是最小的数据读写单位,默认存储块大小为128M。块的大小可以在配置文件hdfs-site.xml中修改。块的默认单位是Byte,每个块都有自己的全局唯一ID。HDFS就是以块为单位在集权服务器上分配存储的。

  5. 块的好处就是:一个文件的大小可以大于集群中任一磁盘容量;块适合于数据备份,极大的提高了集群的容错能力和可用性。

分布式文件系统特点

  1. 高可靠:按位存储,就近原则分配数据,会把数据分配到离它最近的数据节点(DateNode)上。

  2. 高扩展:集群节点可以根据业务需求随时扩展和缩减。

  3. 高效性:可以在各个集群节点之间动态移动数据,保证集群各节点之间的动态平衡。

  4. 高容错:自动保存多个副本(默认3个,可自行修改),并且能够将失败的任务重新分配,解决故障,成本低。

  5. 不适合存储小文件

  6. 不适合低延迟的数据访问(多用于离线数据分析)

HDFS设计目标

  1. 故障检测和自动快速恢复是HDFS的核心架构目标。因为HDFS可能有成百上千的服务器组成,每一个组件都有可能出现故障。

  2. 相较于数据访问的反应时间,更注重数据访问的高吞吐量。HDFS被设计成用于批处理,而不是用户交互式的。

  3. 典型的HDFS文件大小是GB到TB的级别。所以,HDFS被调整成支持大文件(Large Data Sets) 。它应该提供很高的聚合数据带宽,一个集群中支持数百个节点,一个集群中还应该支持千万级别的文件。

HDFS架构

HDFS采用master/slave架构。一个HDFS集群是由一个Namenode和一定数目的Datanodes组成。

  1. NameNode: 是Master节点,中心服务器。管理数据映射,处理客户端的读写请求,配置副本策略。Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录
  2. DataNode: 是Slave节点,负责存储client发来的数据,执行读写操作。在Namenode的统一调度下进行数据块的创建、删除和复制。
  3. SecondaryNameNode: 分担NameNode工作量,是NameNode的冷备份。
  4. 热备份: 系统处于正常运转状态下的备份,假如b是a的热备份,一旦a出现故障,b可以马上运行代替工作。
  5. 冷备份: 与热备份对应,一旦a出现故障,冷备份c不能马上代替a,但c上存储a的一些信息,可以减少损失。
  6. edits: 元素据的操作日志。
  7. fsimage: 是内存命名空间元数据在外存的镜像文件。
  8. editlog: 是各种元数据操作的 write-ahead-log 文件,在体现到内存数据变化前首先会将操作记入 editlog 中,以防止数据丢失。

注:fsimage 和 editlog是在磁盘保存两个元数据管理文件

HDFS应用场景

适合场景:大文件、数据流式访问、一次写入多次读取、高容错等。

不适合场景:小文件、交互式访问、频繁修改、低延迟处理等。

HDFS三大组件

NameNode

NameNode是一个中心服务器,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。Namenode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录。

NameNode的工作机制如下:

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

SecondaryNameNode

Secondary NameNode并不是 NameNode 的热备机,而是定期从 NameNode 拉取 fsimageeditlog文件,并对两个文件进行合并,形成新的 fsimage 文件并传回 NameNode,这样做的目的是减轻 NameNode 的工作压力,本质上 SNN 是一个提供检查点功能服务的服务点。

SecondaryNameNode工作机制如下:

  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

DataNode

负责数据块的实际存储和读写工作,Block 默认是64MB(HDFS2.0之后改成了128MB),当客户端上传一个大文件时,HDFS 会自动将其切割成固定大小的 Block,为了保证数据可用性,每个 Block 会以多备份的形式存储,默认是3份。

其作用大概有以下几点:

  1. 用来存储数据块
  2. 处理真正的读写
  3. 定期向NameNode发送心跳报告和块的位置信息

数据块在DataNode上存储,每个DataNode只知道自己节点上存储了哪些块,并不知道这些块属于哪个文件(即位置),NameNode是知道的。

NameNode记录的磁盘中的元数据信息不包含数据块存储位置的信息,但包含文件和数据块的对应关系

HDFS机制

心跳机制

HDFS为集群主从模式,主节点NameNode,从节点DataNode,两者之间是需要通信的。DataNode会定期向NameNode发送心跳报告,报告自己的存活状态和自己存储块的信息

如果一个DataNode宕机了,NameNode怎么判定DataNode一定宕机了?10次心跳报告收不到,如果10次都接收不到,这个时候NameNode会主动检查,向DataNode发送检查报告,检查DataNode是否真的宕机了。一次检查报告可能存在网络延时或者通信问题,NameNode会发送两次检查,如果两次检查都没有得到回应,这个时候才认为datanode宕机。

一次报告时间为3s

[hadoop@master hadoop]$ vim /opt/hadoop/etc/hadoop/hdfs-site.xml 

内容:

<property>
  <name>dfs.heartbeat.interval</name>
  <value>3</value>
  <description>Determines datanode heartbeat interval in seconds</description>
</property>

一次检查时间:300000ms

<property>
    <name>dfs.namenode.heartbeat.recheck-interval</name>
  	<value>300000</value>
    <description>This time decides the interval to check for expired datanodes. With this value and dfs.heartbeat.interval, the interval of deciding the datanode is stale or not is also calculated. The unit of this configuration is millisecond.</description>
</property>
  

负债均衡

其实就是节点的增加或减少,或者节点的磁盘使用率高低的问题,主要就是通过网络进行数据的迁移工作以达到高可用率

触发命令:

# 磁盘的利用率差值大于5%时会触发负载均衡
[hadoop@master sbin]$ sh $HADOOP_HOME/sbin/start-balancer.sh -t 5%

安全模式

安全模式下集群处于一个自我保护的状态,会进行块的检查和复制的工作。

命令:

hdfs dfsadmin [-safemode enter | leave | get | wait]
#  enter 进入安全模式 /leave 离开安全模式 /wait 等待安全模式退出 /get 获取当前安全模式的状态

HDFS元数据中包含了以下信息:抽象目录树、数据和块的对应关系、块的存储位置

元数据存储位置:在磁盘和内存存储。

磁盘:读写性能比较低,只存储抽象目录树及数据和块的对应关系,没有存储块的位置。

内存:包含元数据的所有信息。读写快,但机器宕机,内存中的元数据就丢失了。

当集群第一次启动的时候,将磁盘元数据加载到内存中,如果磁盘元数据过大,会造成加载到内存的时间过长,所以磁盘只存储抽象目录树 、数据和块的映射关系两部分,元数据中的数据块存储的位置信息是通过DataNdoe的心跳报告获取的.

集群在启动的时候NameNode,会接收DataNode的心跳报告,心跳报告中还包含数据块的存储位置信息。这时候NameNode就可以获取DataNode的数据块的存储状况。

集群启动流程:

  1. NameNode将元数据加载到内存中。
  2. NameNode接收DataNode的心跳报告:获取DataNode的存货状态,及块的存储信息。
  3. 启动SecondaryNameNode

集群在执行以上过程的时候不允许外界对集群进行操作,此时集群处于安全模式,即集群处于安全模式的时候加载元数据和获取DataNode的心跳报告,如果集群处于维护状态或升级状态也可以手动将集群设置安全模式状态。

安全模式下可以进行ls查询、cat查看、get操作,但不能进行创建目录、上传、修改文件名、追加内容。总之,只要不修改元数据的操作都可以进行。

机架策略

HDFS存储块副本份数,默认情况的下:副本3份。

相同的副本不可能存储在同一个节点上,存在一个节点没有意义。

第一个副本:放在客户端所在机器,如果客户端不是集群中的节点任意选一台存放。

第二个副本:放在和第一个副本不同机架的任意节点上。防止机架断电。

第三个副本:放在与第二个副本相同机架的不同节点上

实际生产中机架很多个,数据中心也可能有很多,备份的数据中心。从不同节点,不同机架,不同数据中心去配置,主要思想是用空间换数据安全

元数据管理

存储方式

元数据:1、抽象目录树 2、数据和块的映射关系 3、数据库存储的位置信息。

NameNode对数据管理采用三种存储方式:

  1. 内存元数据:元数据的全部信息(1、2、3)
  2. 磁盘元数据镜像文件:元数据部分信息(1、2)
  3. 数据操作日志文件(可以通过日志运算出元数据)。

存储机制

  1. 内存中有一份完整的元数据(matedate)
  2. 磁盘中有一个元数据镜像文件(fsimage),fsimage是HDFS文件系统存于硬盘中的元数据检查点,里面记录了自最后一次检查点之前HDFS文件系统中所有目录和文件的序列化信息。
  3. 用于斜街内存mete data和持久化元数据镜像fsimage之间的操作日志(edits文件),edits保存了自最后一次检查点之后所有针对HDFS文件系统的操作,比如:增加文件、重命名文件、删除目录等等。

这两种文件存放在${dfs.namenode.name.dir}/current/目录下,文件名以edits_和fsimage_命名,该目录为NameNode上的本地目录。为了保证这两种元数据文件的高可用性,一般的做法,将dfs.namenode.name.dir设置成以逗号分隔的多个目录,这多个目录至少不要在一块磁盘上,最好放在不同的机器上。

hdfs-site.xml中可以看到具体路径:

 <!--指定datanode数节点位置-->
        <property>
                <name>dfs.datanode.data.dir</name>
                <value>/opt/hadoop/hadoopDatas/datanodeDatas</value>
                <final>true</final>
        </property>

        <!--指定namenode元数据存放位置-->
        <property>
                <name>dfs.namenode.dir</name>
                <value>/opt/hadoop/hadoopDatas/namenodeDatas</value>
                <final>ture</final>
        </property>

        <!--指定SecondaryNameNode的主机和端口-->
        <property>
                <name>dfs.namenode.secondary.http-address</name>
                <value>slave1:9868</value>
        </property>

        <!--指定namenode的edits文件的存放位置-->
        <property>
                <name>dfs.namenode.edits.dir</name>
                <value>/opt/hadoop/dfs/hadoopDatas/nn/edits</value>
        </property>
<!--配置检查点目录-->
        <property>
                <name>dfs.namenode.checkpoint.dir</name>
                <value>/opt/hadoop/hadoopDatas/snn/name</value>
        </property>

        <property>
                <name>dfs.namenode.checkpoint.edits.dir</name>
                <value>/opt/hadoop/hadoopDatas/dfs/snn/edits</value>
        </property>

元数据信息

根据上述hdfs-site.xml配置信息,可以看到

/opt/hadoop/dfs/hadoopDatas/nn/edits/current的文件夹中有3种文件,在/opt/hadoop/hadoopDatas/snn/name/current的文件中有1种文件。

这些文件就是元数据信息。

/opt/hadoop/dfs/hadoopDatas/nn/edits/current的文件夹中:

  1. 历史日志文件:编辑完成的日志文件

    日志文件:记录客户端对元数据操作的日志,只记录操作信息, 比如某一个用户对一个目录执行了某一种操作。
    在这里插入图片描述

  2. 正在编辑的日志文件:目前对元数据修改的操作记录的文件。
    在这里插入图片描述

  3. 合并点记录文件:seen_txid
    在这里插入图片描述

    对元数据修改后不会立马对fsimage产生影响,需要空闲的时候把editsfsimage合并,产生最新的元数据信息,合并的依据就是seen_txid

    一般是正在编辑的日志文件的编号和fsimage合并,此时cat seen_txid的结果是67696,因为edits_inprogress_0000000000000067695。历史的日志文件已经合并完成

  4. 镜像文件:真实的元数据信息经过序列化的结果(序列化的目的是压缩大小),集群启动的时候会加载这个文件,加载的时候会反序列化。

    该文件目录:[hadoop@master ~]$ cd /opt/hadoop/hadoopDatas/snn/name/current
    在这里插入图片描述

FsImage与edits详解

所有的元数据信息都保存在了FsImage与Eidts文件当中,这两个文件就记录了所有的数据的元数据信息,元数据信息的保存目录配置在了hdfs-site.xml当中。

关于Edits:

  1. 客户端对hdfs进行写文件时,会首先被记录在edits文件中
  2. edits修改时元数据也会更新。
  3. 每次hdfs更新时edits先更新后,客户端才会看到最新信息。

关于FsImage:

  1. fsimage是namenode中关于元数据的镜像,一般称为检查点,是NameNode是完整的镜像

  2. fsimage内容很大,如果每次都加载到内存的话生成树状拓扑结构,这是非常耗内存和CPU。所以**,一般开始时对NameNode的操作都放在edits中**。

  3. fsimage内容包含了NameNode管理下的所有DataNode中文件,block文件及block所在的DataNode的元数据信息。随着edits内容增大,就需要在一定时间点和fsimage合并

查看元数据信息:

fsimage和edits是经过序列化的,非文本的,因此无法直接查看。hdfs提供了查看这两种文件的工具。

  1. 命令hdfs oev,用于查看edits文件
[hadoop@master current]$ pwd
/opt/hadoop/dfs/hadoopDatas/nn/edits/current
[hadoop@master current]$ hdfs oev -i edits_0000000000000067701-0000000000000067702 -o myedit.xml -p XML

# 会生成一个myedit.xml文件,包含edits的所有信息
# -i,必须参数,输入edits文件,如果是xml后缀,表示XML格式,其他表示二进制
  1. 命令hdfs oiv,用于将fsimage文件转换成其他格式的,如文本文件、XML文件。
    在这里插入图片描述

元数据合并Checkpoint

每隔一段时间,会由Secondary NameNode将Namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge,这个过程称为checkpoint。

checkpoint操作的触发条件配置参数,在hdfs-site.xml文件配置。

在这里插入图片描述

触发合并条件:

  1. 时间节点:每隔一小时(3600s)合并
  2. 元数据条数:当达到100万条

合并的过程:根据edits的操作日志改变fsimage的元数据信息

合并流程:

  1. SecondaryNameNode(snn)向NameNode发送请求,是否checkpoint
  2. 当满足合并的条件是,NameNode返回snn同意合并。
  3. 开始checkpoint。
  4. 将正在编辑的日志文件回滚(由编辑状态变成编辑完成状态),同时生成一个新的正在编辑的日志文件。
  5. snn把fsimage和历史日志文件拉取到自己的节点上,如果不是第一次checkpoint,那么这次拉取的日志文件是合并点记录的。
  6. snn把edits和fsimage文件加载到内存中进行合并,合并的文件叫fsimage.checkpoint
  7. snn把合并后的fsimage.checkpoint文件发送给NameNode,snn中也保留一份。
  8. NameNode将fsimage.checkpoint文件重命名为fsimage,替换原来的fsimage。

Checkpoint的作用:

NameNode和Secondary NameNode或者 Standby NameNode的工作目录存储结构完全相同,所以,当NameNode故障退出需要重新恢复时,可以从 Secondary NameNode的工作目录中将fsimage拷贝到namenode的工作目录,以恢复NameNode的元数据。


版权声明:本文为EricLeiy原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。