分布式文件系统HDFS

发布于 2022-04-05  820 次阅读


HDFS 简介

HDFS (Hadoop Distributed File System),Hadoop分布式文件系统。是Apache Hadoop核心组件之一。

优势

  1. 处理超大文件
  2. 处理非结构化数据
  3. 流式数据访问模式 ( 一次写入,多次读取 )
  4. 运行于廉价的商用机器集群
  5. 发生故障时能继续运行且不被用户察觉

局限性

  1. 不适合处理低延迟数据访问
  2. 无法高效存储大量小文件
  3. 不支持多用户写入及任意修改同一个文件

特性

  1. 高容错,可扩展性及可配置性强
  2. 跨平台性
  3. shell命令行接口
  4. Web界面

实现目标

  1. 检测和快速恢复硬件故障
  2. 流式数据访问
  3. 大规模数据集
  4. 简化一致性模型
  5. 移动计算代价比移动数据代价低
  6. 异构软硬件平台间的可移植性

HDFS 相关概念

1. 命名空间 Namespace

HDFS支持传统的层次型文件组织结构。用户可以创建目录,然后将文件保存在这些目录里。文件系统名字空间的层次结构和大多数现有的文件系统类似:用户可以创建、删除、移动或重命名文件。

2. 主从架构

HDFS采用master/slave架构。一般一个HDFS集群是有一个NameNode和一定数目的DataNode组成。NameNode是HDFS主节点, DataNode是HDFS从节点,两种角色各司其职,共同协调完成分布式的文件存储服务。

HDFS 核心设计

1. 分块存储

HDFS中的文件在物理上是分块存储(block)的,块的大小可以通过配置参数来规定(参数位于hdfs-default.xml中: dfs. blocksize)。默认大小是128M (1.x是64MB,2.x和3.x是128MB)。

根据集群参数(网络传输速率、块查询时间)对HDFS块大小进行设置

  1. HDFS文件块大小设置主要取决于磁盘传输速率。目前通过Namenode对HDFS元数据进行寻址的时间约为 10ms,即查找到目标block的时间为 10ms。
  2. 寻址时间为传输时间的1%时,则为最佳状态。因此,传输时间为10ms/0.01 = 1000ms = 1s
  3. 目前磁盘的传输速率普遍为 100MB/s。

因此,block大小为1s * 100MB/s = 100MB。
又因为电脑底层数据采用二进制存储,所以目前的block块官方大小设置为128MB。

同理,磁盘的传输速率普遍为 200MB/s 时,block块大小设置为1s * 200MB/s = 200MB => 256MB。

设置集群Block的备份数

方法一:配置文件hdfs-site.xml

<property>
    <name>dfs.replication</name>
    <value>x</value>
    <!-- x为修改的冗余因子 -->
</property>

方法二:通过命令修改备份数

bin/hadoop fs -setrep -R x /
(x为修改的冗余因子)

注意:方法二可以改变整个HDFS里面的备份数,不需要重启HDFS系统,而方法一需要重启HDFS系统才能生效。

1.如何分块

  • 当我们遇到一个大的数据时,HDFS会将它拆分成许多个小的数据块(Block),以便分布式存储。
  • 数据块容量太小不合适,寻址困难。
  • 数据块容量太大也不合适,容易产生外部碎片。

2.如何备份

分好块后,为了保证容错性(软硬件出错导致的数据丢失之类),HDFS需要对数据块进行备份(冗余存储)。Hadoop默认一个数据块备份3个副本,分布策略如下:

  • 第一个副本:随机挑选一台磁盘不太满,CPU不太忙的节点。
  • 第二个副本:放置在于第一个副本不同的机架的节点上。
  • 第三个副本:与第二个副本相同机架的节点。
  • 更多副本:随机节点。

3.检测数据(块)损坏流程

  1. 数据节点会周期性向主节点汇报自己的块列表信息。
  2. 汇报信息前,数据节点会通过验证校验码去筛选是否存在数据块的数据损失,如果发现数据块数据有所损失,则不上报。
  3. 主节点通过对比自己的块列表和数据节点上报的信息,知道数据块的损坏情况,并更新自己的块表。

2. 安全模式(SafeMode)

安全模式是Hadoop集群的一种保护模式.
NameNode在启动时会自动进入安全模式,也可以手动进入。
当系统处于安全模式时,会检查数据块的完整性。

hadoop dfsadmin -safemode leave //强制NameNode退出安全模式hadoop dfsadmin -safemode enter //进入安全模式
hadoop dfsadmin -safemode get   //查看安全模式状态
hadoop dfsadmin -safemode wait  //等待,一直到安全模式结束

3.负载均衡

机器与机器之间磁盘利用率不平衡是HDFS集群非常容易出现的情况,尤其是在DataNode节点出现故障或在现有的集群上增添新的DataNode的时候。
分析数据块分布和重新均衡DataNode上的数据分布的工具
HADOOP_HOME/bin 目录下D的 start-balancer.sh 脚本就是该任务的启动脚本:

$HADOOP_HOME /bin/start-balancer.sh -threshold

参数:

  • -threshold
    默认值为10,取值范围 0 ~ 100
    理论上,该参数越小,整个集群越均衡

DataNode 分组

HDFS 根据阈值设定情况,将当前DataNode节点分组。

  1. over组
    DataNode使用空间比例 > 集群平均使用空间比例 + 设定的阈值空间比
  2. Above组
    集群平均使用空间比例 + 设定的阈值空间比 > DataNode使用空间比例 > 集群平均使用空间比例
  3. Below组
    集群平均使用空间比例 - 设定的阈值空间比 < DataNode使用空间比例 < 集群平均使用空间比例
  4. Under组
    DataNode使用空间比例 < 集群平均使用空间比例 - 设定的阈值空间比

4. 心跳机制

  1. hdfsmaster/slave结构,master包括NameNodeResourceManagerslave包括DataNodeNodeManager
  2. master启动时会开启一个IPC服务,等待slave连接
  3. slave启动后,会主动连接IPC服务,并且每隔3秒链接一次,这个时间是可以调整的,设置heartbeat,这个每隔一段时间连接一次的机制,称为心跳机制。slave通过心跳给master汇报自己信息,master通过心跳下达命令。
  4. NameNode通过心跳得知DataNode状态。ResourceManager通过心跳得知NodeManager状态
  5. 当master长时间没有收到slave信息时,就认为slave挂掉了。

检测数据节点损坏流程

  1. 数据节点通过向主节点发送心跳保持与其联系(3秒一次)。
  2. 如果主节点10分钟没有收到数据节点的心跳,则认为其已经意外丢失,主节点会开始复制他在其他数据节点上的备份数据块,重新备份。

5. 机架感知

大型Hadoop集群是以机架的形式来组织的
同一个机架上不同节点间的网络状况比不同机架之间的更为理想
默认情况下,Hadoop的机架感知是没有被启用的
启用机架感知功能,在NameNode所在机器的core-site.xml中配置一个选项:

<property>
    <name>topology.script.file.name</name>
    <value>/path/to/script</value>
    <!-- value的值是一个脚本 -->
</property> 

核心组件

1. NameNode 名称节点

也称主节点,作为中心服务器,主要负责接受客户端的读写请求。在主节点的统一调度下进行数据块的创建、删除和复制等操作,主节点的元数据信息会在启动后加载到内存里,以便快速查询。

名称节点负责管理分布式文件系统的命名空间(Namespace),保存了两个核心数据结构FsImage和EditLog。

FsImage用于维护文件系统树以及文件树中所有文件和文件夹的元数据(文件自身属性:文件名称、权限、修改时间、文件大小、冗余因子、数据块大小,文件块位置映射信息:记录文件块和DataNode间的映射信息,即哪个块位于哪个节点上)。

EditLog操作日志文件记录了所有针对文件的创建、删除、重命名等操作。

2. DataNode 数据节点

数据节点是分布式文件系统HDFS的工作节点,负责文件的存储和读取,会根据客户端或者名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表(必须向主节点汇报心跳、块列表和其他确认信息ack)。
每个数据节点中的数据会被保存到各自节点的本地Linux文件系统中。

3. SecondNameNode 第二名称节点

并不是主节点的备份文件,但是是备用主节点。

它主要为了帮助主节点分担压力,类似主节点的“助手”。它的主要工作是在主节点忙时,帮助主节点合并Edits ,减少NameNode流程如下图。


  1. secondarynamenode通知namenode切换edits文件
  2. secondarynamenode从namenode获得fsimage和edits(通过http)
  3. secondarynamenode将fsimage载入内存,然后开始合并edits
  4. secondarynamenode将新的fsimage发回给namenode
  5. namenode用新的fsimage替换旧的fsimage

什么时候checkpiont?

  • fs.checkpoint.period 指定两次checkpoint的最大时间间隔,默认3600秒。
  • fs.checkpoint.size 规定edits文件的最大值,一旦超过这个值则强制checkpoint,不管是否到达最大时间间隔。

HDFS Shell

hadoop dfs 只能操作HDFS文件系统(包括与Local FS间的操作)。(已经弃用—)
hdfs dfs 只能操作HDFS文件系统相关(包括与Local FS间的操作)。(市面上常用
hadoop fs 可操作任意文件系统,不仅仅是HDFS文件系统。(官方推荐

1. 创建一个或多个指定目录(文件夹)

hadoop fs -mkdir [-p] [paths]

  • path 为代创建目录
  • -p 递归创建

2. 显示指定文件或文件夹的详细信息

hadoop fs -ls [-h] [-R] [path]

  • -h 人性化显示文件/文件夹大小size(如:不加-h时显示47340,加后显示46.2KB)
  • -R 递归显示所有文件的详细信息

3. 上传文件[localsrc]到指定目录[dst]

hadoop fs -put [-f] [-p] [loaclsrc] [dst]

  • -f 覆盖目标文件(如果文件已经存在)
  • -p 保留访问和修改时间、所有的权限
  • dst 目标文件系统(HDFS)路径

hadoop fs -moveFromLocal [loaclsrc] [dst]

  • 和-put功能相同,只不过上传结束后,源数据会被删除(文件的移动)

4. 查看 HDFS 文件内容

hadoop fs -cat [dst]

  • 读取指定文件全部内容,显示在标准输出控制台上
  • 注意:对于大文件内容的读取,慎重

hadoop fs -head [file]

  • 查看文件前1KB的内容

hadoop fs -tail [-f] [file]

  • 查看文件最后1KB的内容
  • -f可以可以动态查看文件中的追加内容

5. 下载HDFS文件到本地

hadoop fs -get [-f] [-p] [src] [loacldst]

  • 下载文件到本地文件系统指定目录,locakdst必须是目录
  • -f 覆盖目标文件(如果文件已存在)
  • -p 保留访问和修改时间、所有权限

hadoop fs -getmerge [-nl] [-skip-empty-file] [src] [localdst]

  • 对[src]中所有文件进行合并,并写入本地系统的指定文件中
  • -nl 在每个文件末尾添加一个换行符
  • skip-empty-file跳过空文件

6. 将文件从源路径[sec]复制到目标路径[dst]

hadoop fs -cp [-f] [src] [dst]

  • -f覆盖目标文件(如果文件已经存在)

7. 追加数据到HDFS文件中

hadoop fs -appendToFile [loaclsec] [dst]

  • 将给定本地文件的内容追加到dst文件
  • dst如果不存在,将创建该文件
  • 如果localsrc-,则从标准输入中读取

8. 查看磁盘空间

hadoop fs -df [-h] [path]

  • 显示文件系统的容量,可以空间和已用空间

9. 查看HDFS文件使用空间量du

hadoop fs -du [-s] [-h] [path]

  • 由于HDFS冗余存储,文件大小不等于占用磁盘空间
  • -s表示显示指定路径文件长度的汇总摘要,而不是单个文件的摘要

10. HDFS数据移动操作

hadoop fs -mv [src] [dst]

  • 移动文件到指定文件夹下
  • 可以用该命令移动数据,实现重命名文件

11. HDFS文件副本个数

hadoop fs -setrep [-R] [-w] [rep] [path]

  • 修改副本数(冗余因子)
  • -R递归改变目录下所有文件的副本系数
  • -w客户端是否等待副本修改完毕

HDFS Java客户端操作

客户端核心类

Configuration 配置对象类,用于加载或设置参数属性

FileSystem文件系统基类。针对不同文件系统有不同的具体实现。该类封装了文件系统的相关操作方法。

模板

public class myHDFS {
    private FileSystem fs = null;
    private Configuration conf = null;

    //构造函数
    @Before
    public void init() throws URISyntaxException, IOException, InterruptedException {
        //入口网址
        URI uri=new URI("hdfs://localhost:9000");
        //配置文件
        conf = new Configuration();
        //conf.set("dfs.replication","1");
        //给用户名称修改成自己的用户名
        String user="buyunaihe";
        //文件系统对象
        fs = FileSystem.get(uri,conf,user);
    }

    //操作
    @Test
    public void solve() throws IOException{

    }

    //析构函数
    @After
    public void close() throws IOException {
        if(fs != null)
            fs.close();
    }
}

创建文件夹

    @Test
    public void solve() throws IOException{
        if(fs.exists(new Path("/hdfs"))
            fs.mkdirs(new Path("/hdfs"))
    }
    //fs.exists(Path) 判断文件夹是否存在

上传与下载文件

    @Test
    public void put() throws IOException{
        Path src = new Path("/Users/hdfs.txt");
        Path dst = new Path("/");
        //src是本地路径,dst是目标路径
        fs.copyFromLocalFile(src,dst);
        //第一个参数表示是否删除源文件,第二个参数表示是否覆盖目标文件(若目标文件已存在)
        fs.copyFromLocalFile(false,true,src,dst);
    }

    @Test
    public void get() throws IOException{
        Path src = new Path("/Users/hdfs.txt");
        Path dst = new Path("/");
        //src是hdfs源路径,dst是本地目标路径
        fs.copyToLocalFile(src,dst);
        //第一个参数表示是否删除源文件,第四个参数表示是否使用RawLocalFileSystem作为本地文件系统
        fs.copyToLocalFile(false,src,dst,true);
    }

HDFS 的运行机制

HDFS中数据流的读写

1. RPC实现流程

一个典型的RPC框架主要包括以下几个部分:

  • 通信模块:两个相互协作的通信模块实现请求--应答协议。
  • 代理程序:客户端和服务器端均包含代理程序。
  • 调度程序:调度程序接受来自通信模块的请求消息,并根据其中的标志选择一个代理程序处理。

一个RPC请求从发送到获取处理结果,所经历的步骤如下:

  1. 客户程序以本地方式调用系统产生的Stub程序
  2. 该Stub程序将函数调用信息按照网络通信模块的要求封装成消息包,并交给通信模块发送到远程服务器端
  3. 远程服务器端接收到此消息后,将此消息发送给相应的Stub程序
  4. Stub程序拆封消息,形成被调过程要求的形式,并调用对应的函数
  5. 被调用函数按照所获参数执行,并将结果返回给Stub程序
  6. Stub将此结果封装成消息,通过网络通信模块逐级地传送给客户程序

2. RPC Server实现模型

Server:RPC Server实现了一种抽象的RPC服务,同时提供Call队列。

RPC Server结构

  • Server.Listener:RPC Server的监听者,用来接收RPC Client的连接请求和数据,其中将数据封装成CALL后PUSH到CALL队列中。
  • Server.Handler:RPC Server的CALL处理者,和Server.Listener通过CALL队列交互。
  • Server.Responder:RPC Server响应者,Server.Handler按照异步非阻塞的方式向RPC Client发送响应,如果有未发送出去的数据,交由Server.Responder来处理完成。
  • Server.Connection:RPC Server数据的接收者。提供接收数据,解析数据包的功能。
  • Server.Call:持有客户端的Call信息。

RPC Server的主要流程

RPC Server作为服务的提供者主要有两部分组成:接收Call调用和处理Call调用。
接收Call调用负责接收来自RPC Client的调用请求,编码成Call对象放入到Call队列中,这一过程有Server.Listener完成。具体步骤如下:

  1. Listener线程监听RPC Client发过来的数据
  2. 当有数据可以接收时,调用Connection的readAndProcess方法
  3. Connection边接受数据边处理数据,当接到一个完整的Call包,则构建一个Call对象,PUSH到Call 队列中,有Handler来处理Call队列中的所有Call处理完的Call调用负责处理Call队列中的每一个调用请求,由Handler线程来完成。
  4. Handler线程监听Call队列,如果Call队列非空,按FIFO规则从Call队列中取出Call
  5. 将Call交给RPC.Server来处理
  6. 借助JDK提供的Method,完成对目标方法的调用,目标方法由具体的业务逻辑实现
  7. 返回响应。Server.Handler按照异步非阻塞的方式向RPC Client发送响应,如果有未发送出的数据,则交由Server.Responder来完成。

3. 文件的读取

详细过程:

  1. 使用HDFS提供的客户端Client,向远程的Namenode发起RPC请求
  2. Namenode会视情况返回文件的部分或者全部block列表,对于每个block,Namenode都会返回有该block拷贝的DataNode地址;
  3. 客户端Client会选取离客户端最近的DataNode来读取block;如果客户端本身就是DataNode,那么将从本地直接获取数据;
  4. 读取完当前block的数据后,关闭当前的DataNode链接,并为读取下一个block寻找最佳的DataNode;
  5. 当读完列表block后,且文件读取还没有结束,客户端会继续向Namenode获取下一批的block列表;
  6. 读取完一个block都会进行checksum验证,如果读取datanode时出现错误,客户端会通知Namenode,然后再从下一个拥有该block拷贝的datanode继续读。

简略描述:

  1. 客户端向NameNode发起请求,需要获取名字为1的数据块。
  2. NameNode中保存了该数据块存储的位置,将DataNode的信息返回给客户端。
  3. 客户端就近的方式去从DataNode获取数据。
  4. 如果某个DataNode无法访问。
  5. 从另一个DataNode中去获取数据。

4. 文件的写入

详细描述:

  1. 使用HDFS提供的客户端Client,向远程的Namenode发起RPC请求
  2. Namenode会检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会为文件创建一个记录,否则会让客户端抛出异常;
  3. 当客户端开始写入文件的时候,客户端会将文件切分成多个packets,并在内部以数据队列“data queue(数据队列)”的形式管理这些packets,并向Namenode申请blocks,获取用来存储replicas的合适的datanode列表,列表的大小根据Namenode中replication的设定而定;
  4. 开始以pipeline(管道)的形式将packet写入所有的replicas中。开发库把packet以流的方式写入第一个datanode,该datanode把该packet存储之后,再将其传递给在此pipeline中的下一个datanode,直到最后一个datanode,这种写数据的方式呈流水线的形式。
  5. 最后一个datanode成功存储之后会返回一个ack packet(确认队列),在pipeline里传递至客户端,在客户端的开发库内部维护着"ack queue",成功收到datanode返回的ack packet后会从"ack queue"移除相应的packet。
  6. 如果传输过程中,有某个datanode出现了故障,那么当前的pipeline会被关闭,出现故障的datanode会从当前的pipeline中移除,剩余的block会继续剩下的datanode中继续以pipeline的形式传输,同时Namenode会分配一个新的datanode,保持replicas设定的数量。
  7. 客户端完成数据的写入后,会对数据流调用close()方法,关闭数据流。
  8. 只要写入了dfs.replication.min的复本数(默认为1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数(dfs.replication的默认值为3),因为namenode已经知道文件由哪些块组成,所以它在返回成功前只需要等待数据块进行最小量的复制。

简略描述:

  1. 客户端向NameNode发起请求,需要存储数据Data。
  2. 因为NameNode中是记录了所有DataNode的相关信息的,而数据最终要保存的地方就是DataNode,所以NameNode会返回可用的DataNode的信息给客户端。
  3. 将Data分为1和2这两个数据块。
  4. 客户端会将数据块存储到NameNode返回给他的DataNode1中去。
  5. 因为数据块需要存储多份,所以DataNode之间会相互传输来进行存储。
  6. DataNode存储完数据后,会反馈给NameNode,NameNode会将对应的DataNode的相关信息进行更新。

HDFS的HA机制

在Hadoop 2.0之前,在HDFS 集群中 NameNode 存在单点故障 (SPOF)。对于只有一个 NameNode 的集群,如果 NameNode 机器出现故障(比如宕机或是软件、硬件升级),那么整个集群将无法使用,直到 NameNode 重新启动。

HDFS 的 HA 功能通过配置 Active/Standby 两个 NameNodes 实现在集群中对NameNode 的热备份来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将>热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将 NameNode 很快的切换到另外一台机器。

HA流程

  1. 在一个典型的HDFS(HA) 集群中,使用两台单独的机器配置为NameNodes 。在任何时间点,确保NameNodes 中只有一个处于Active 状态,其他的处在Standby 状态。其中ActiveNameNode 负责集群中的所有客户端操作,StandbyNameNode 仅仅充当备机,保证一旦ActiveNameNode 出现问题能够快速切换。
  2. 为了能够实时同步Active和Standby两个NameNode的元数据信息(实际上editlog),需提供一个共享存储系统,可以是NFS、QJM(Quorum Journal Manager)或者Bookeeper,Active Namenode将数据写入共享存储系统,而Standby监听该系统,一旦发现有新数据写入,则读取这些数据,并加载到自己内存中,以保证自己内存状态与Active NameNode保持基本一致,如此这般,在紧急情况下standby便可快速切为active namenode。
  3. 为了实现快速切换,Standby 节点获取集群的最新文件块信息也是很有必要的。为了实现这一目标,DataNode 需要配置NameNodes 的位置,并同时给他们发送文件块信息以及心跳检测。

注意:Secondary NameNode。它不是HA,它只是阶段性的合并edits和fsimage,以缩短集群启动的时间。当NameNode失效的时候,Secondary NN并无法立刻提供服务,Secondary NN甚至无法保证数据完整性:如果NN数据丢失的话,在上一次合并后的文件系统的改动会丢失。

HDFS的Federation机制

在Hadoop 2.0之前,HDFS的单NameNode设计带来诸多问题,包括单点故障、内存受限,制约集群扩展性和缺乏隔离机制(不同业务使用同一个NameNode导致业务相互影响)等,为了解决这些问题,除了用基于共享存储的HA解决方案我们还可以用HDFS的Federation机制来解决这个问题。

什么是Federation机制

HDFS Federation是指HDFS集群可同时存在多个NameNode,这些NameNode分别管理一部分数据,且共享所有DataNode的存储资源。

可解决单NameNode存在的问题

  1. HDFS集群扩展性。多个NameNode分管一部分目录,使得一个集群可以扩展到更多节点,不再像1.0中那样由于内存的限制制约文件存储数目。
  2. 性能更高效。多个NameNode管理不同的数据,且同时对外提供服务,将为用户提供更高的读写吞吐率。
  3. 良好的隔离性。用户可根据需要将不同业务数据交由不同NameNode管理,这样不同业务之间影响很小。

需要注意的,HDFS Federation并不能解决单点故障问题,也就是说,每个NameNode都存在在单点故障问题,你需要为每个namenode部署一个backup namenode以应对NameNode挂掉对业务产生的影响。

Federation架构

  1. 为了水平扩展namenode,federation使用了多个独立的namenode/namespace。这些namenode之间是联合的,也就是说,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。分布式的datanode被用作通用的数据块存储存储设备。每个datanode要向集群中所有的namenode注册,且周期性地向所有namenode发送心跳和块报告,并执行来自所有namenode的命令。
  2. 一个block pool由属于同一个namespace的数据块组成,每个datanode可能会存储集群中所有block pool的数据块。
  3. 每个block pool内部自治,也就是说各自管理各自的block,不会与其他block pool交流。一个namenode挂掉了,不会影响其他namenode。
  4. 某个namenode上的namespace和它对应的block pool一起被称为namespace volume。它是管理的基本单位。当一个namenode/nodespace被删除后,其所有datanode上对应的block pool也会被删除。当集群升级时,每个namespace volume作为一个基本单元进行升级。

多命名空间管理

Federation中存在多个命名空间,如何划分和管理这些命名空间非常关键。在Federation中并采用“文件名hash”的方法,因为该方法的locality非常差,比如:查看某个目录下面的文件,如果采用文件名hash的方法存放文件,则这些文件可能被放到不同namespace中,HDFS需要访问所有namespace,代价过大。为了方便管理多个命名空间,HDFS Federation采用了经典的Client Side Mount Table。

如图所示,下面四个深色三角形代表一个独立的命名空间,上方浅色的三角形代表从客户角度去访问的子命名空间。各个深色的命名空间Mount到浅色的表中,客户可以访问不同的挂载点来访问不同的命名空间,这就如同在Linux系统中访问不同挂载点一样。这就是HDFS Federation中命名空间管理的基本原理:将各个命名空间挂载到全局mount-table中,就可以做将数据到全局共享;同样的命名空间挂载到个人的mount-table中,这就成为应用程序可见的命名空间视图。

Federation的不足

HDFS Federation并没有完全解决单点故障问题。虽然namenode/namespace存在多个,但是从单个namenode/namespace看,仍然存在单点故障:如果某个namenode挂掉了,其管理的相应的文件便不可以访问。Federation中每个namenode仍然像之前HDFS上实现一样,配有一个secondary namenode,以便主namenode挂掉一下,用于还原元数据信息。