本文主要详述了HDFS的组成结构,客户端上传下载的过程,以及HDFS的高可用和联邦HDFS等内容。若有不当之处还请留言指出。

当数据集大小超过一台独立的物理计算机的存储能力时,就有必要对它进行分区,并存储到若干台独立的计算机上。Hdfs是Hadoop中的大规模分布式文件存储系统。

HDFS的特点

  • HDFS文件系统可存储超大文件

1)HDFS是一种文件系统,自身也有块(block)的概念,其文件块要比普通单一磁盘上文件系统大的多,hadoop1.0上默认是 64MB,2.0默认是128MB。与其他文件系统不同的是,HDFS中小于一个块大小的文件不会占据整个块的空间。

2)HDFS上的块之所以设计的如此之大,其目的是为了最小化寻址开销。如果块设置得足够大,从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。

3)HDFS文件的所有块并不需要存储在一个磁盘上,因此可以利用集群上任意一个磁盘进行存储,由于具备这种分布式存储的逻辑,所以可以存储超大的文件。

  • HDFS同一时刻只允许一个客户端对文件进行追加写操作(不支持多个写入者的操作,也不支持在文件的任意位置修改),这样避免了复杂的并发管理功能,但也限制了系统性能。

  • 运行在普通廉价的机器上

Hadoop 的设计对硬件要求低,无需昂贵的高可用性机器上,因为在 HDFS 设计中充分考虑到了数据的可靠性、安全性和高可用性。

  • HDFS适合存储大文件并为之提供高吞吐量的顺序读/写操作,不太适合大量随机读的应用场景,也不适合存大量小文件的应用场景。HDFS是为高吞吐量应用优化的,会以提高时间延迟为代价,因此不适合处理低时延的数据访问的应用。

HDFS体系架构

  • HDFS 是一个主/从(Master/Slave)体系架构,由于分布式存储的性质,集群拥有两类节点 NameNode 和 DataNode。

  • NameNode(名称节点):系统中通常只有一个,中心服务器的角色,管理存储和检索多个 DataNode 的实际数据所需的所有元数据,响应客户请求。

  • DataNode(数据节点):系统中通常有多个,是文件系统中真正存储数据的地方,在NameNode 统一调度下进行数据块的创建、删除和复制。

NameNode

NameNode负责整个分布式文件系统的元数据,包括文件目录树,文件到数据块Block的映射关系等。这些数据保存在内存里,同时这些数据还以两个文件形式永久保存在本地磁盘上:命名空间镜像文件(fsimage)和编辑日志文件(editlog)。fsimage是内存命名空间元数据在外存的镜像文件,editlog文件则记录着用户对文件的各种操作记录,当客户端对hdfs中的文件进行新增或者修改操作,操作记录首先被记入editlog文件中,当客户端操作成功后,相应的元数据会更新到内存meta.data中,防止发生意外导致丢失内存中的数据。fsimage和editlog两个文件结合可以构造出完整的内存数据。

NameNdoe还负责对DataNode的状态监控。DataNode定期向NameNode发送心跳以及所存储的块的列表信息。NameNode可以知道每个DataNode上保存着哪些数据(Block信息),DataNode是否存活,并可以控制DataNode启动或是停止。若NameNode发现某个DataNode发生故障,会将其存储的数据在其他DataNode机器上增加相应的备份以维护数据副本(默认为3,可在配置文件中配置)保持不变。

如果NaneNode服务器失效,集群将失去所有的数据。因为我们将无从知道哪些DataNode存储着哪些数据。因此NameNode的高可用,容错机制很重要。

DataNode

DataNode负责数据块的实际存储和读/写工作。在hadoop1.0时,DataNode的数据块默认大小为64M,2.0版本后,块的默认大小为128M。当客户端上传一个大文件时,HDFS会自动将其切割成固定大小的Block,每个块以多份的形式存储在集群上,默认为3份。

  • Datanode掉线判断

datanode进程死亡或者网络故障造成datanode无法与namenode通信,namenode不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。HDFS默认的超时时长为10分钟+30秒。如果定义超时时间为timeout,则超时时长的计算公式为:

timeout  = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval
而默认的heartbeat.recheck.interval 大小为5分钟,dfs.heartbeat.interval默认为3秒。
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的单位为毫秒,dfs.heartbeat.interval的单位为秒。

配置文件

<property>
#NameNode向DataNode发起的请求,要求其发送心跳信息的时间间隔
<name>heartbeat.recheck.interval</name>
<value>8000</value>
</property>
<property>
#DataNode发送心跳的时间间隔
<name>dfs.heartbeat.interval</name>
<value>3</value>
</property>
  • 数据副本块数量与默认数量不同

      <property>
    #DataNode默认60分钟向NameNode提交自己的Block信息
    <name>dfs.blockreport.intervalMsec</name>
    <value>3600000</value>
    </property>

    如果一台DataNode经过10分30秒(默认)后没有给NameNode发送心跳信息,而被NameNode判断为死亡,NameNode会马上将其上的数据备份到集群中其他机器上。当这个DataNode节点排除故障后,重新回到集群中,该节点上还保存着原来那批数据,而默认的配置情况下,DataNode会每隔60分钟向NameNode发送一次Block信息,在这段时间内,集群中会有某些数据块多出一个备份。在NameNode收到该节点的Block信息后,它发现数据备份多了才会命令某些DataNode删除掉多余的备份数据。

客户端上传文件

步骤详解:

1)向namenode请求上传文件

2)namenode检查客户端要求上传的文件是否已存在,父目录是否存在

3)namenode响应客户端是否可以上传文件

4)若第3步获得可以上传的信息,客户端向namenode发出请求,询问第一块block该上传到哪里

5)namenode查询datanode信息(忙碌情况,远近情况等)

6)namenode返回3个datanode地址给客户端

7)客户端请求与最近的一个datanode节点(假设为datanode1)建立传输通道,并告知其还要传给datanode2和datanode3。datanode1会请求与datanode2建立连接,datanode2会请求与datanode3建立连接。

8)datanode3响应datanode2的连接请求,通道建立成功。同理,datanode2响应datanode1,datanode1响应客户端。

9)客户端收到通道建立成功的消息后,开始向datanode1发送block1的数据,以一个个package(64k)为单位通过通道向datanode1写数据,datanode1收到数据会将其存在本地缓存中,一边向datanode2传数据,一边将缓存中的数据保存到磁盘上。

10)客户端在传送数据时会有一个package的应答队列,datanode1每收到一个package后就向客户端发回消息(datanode1不用等待datandoe2发回应答信息才给客户端发送信息,客户端只保证datanode1收到了数据就行,后面的事它交给了datanode1)

11)当一个block传输完成之后,客户端再次请求namenode上传第二个block

NameNode如何选择DataNode

客户端在上传数据时,请求namenode告诉其应该往哪几个datanode上传副本。namenode需要综合考虑datanode的可靠性,写入带宽,读出带宽等因素。默认情况下,在运行客户端的那个节点上存放第1个副本,如果客户端运行在集群之外,则随机选择一个节点存放第1块,但namenode会尽量选择那些情况好的datanode(存储不太满,当时不太忙,带宽比较高)。第2个副本存放在与第1个副本所在机架不同的另一个机架上的datanode中(随机选择另一机架上的另一情况较好的datanode),第3个副本存在与第2个副本相同机架但不同datanode的另一个datanode上。

所有有关块复制的决策统一由 NameNode 负责,NameNode 会周期性地接受集群中数据节点 DataNode 的心跳和块报告。一个心跳的到达表示这个数据节点是正常的。一个块报告包括该数据节点上所有块的列表。

客户端下载文件

步骤详解:

1)跟namenode通信,请求下载某个数据。

2)namenode查询元数据信息以及block位置信息。

3)将数据所在的datanode信息返回给客户端。

4)客户端根据数据所在的datanode,挑选一台距离自己最近的datanode,并向其发出下载文件的请求(若所需数据不在一台datanode上保存,则分别向多台datanode发出请求)。

5)datanode响应客户端请求,将数据返回给客户端。

6)从多个datanode获得的数据不断在客户端追加,形成完整的数据

NameNode与Secondary NameNode

因为namenode上保存着整个hdfs集群上的所有元数据信息,如果namenode宕机,集群将失去所有数据,因此对namenode实现容错十分重要,Hadoop为此提供了两种机制。

第一种是在配置文件里配置namenode的工作目录为多个,这样可以将元数据信息存到多块磁盘上,或是多台机器上,甚至可以将元数据存在远程挂载的网络文件系统中(NFS),可以通过配置使namenode在多个文件系统上实时保存元数据。这样一来,namenode的工作目录所在的磁盘损坏后,还有其他磁盘上的数据可用。

第二种是运行一个辅助namenode,被称为secondary namenode(第二名称节点)。secondary namenode的职责并不是作为namenode的热备份机,其主要作用是定期从namenode拉取fsimage和editlog,并将两者合并成新的fsimage,将新的fsimage返回给namenade。这种方式,一方面可以避免namenode上的编辑日志过大,另一方面将合并操作放在secondary namenode上可以节省namenode的cpu时间和内存,减轻namenode的工作压力,让namenode更专注于自己的本职工作。secondary namenode中保存的fsimage数据总是会滞后于namenode内存中的元数据,所以在namenode宕机后,难免会有部分的数据丢失。(可以把NFS上的namenode元数据复制到secondary namenode上,使其成为新的namenode,并不损失任何数据)

Secondary NameNode的工作

secondary namenode将namenode上积累的所有editlog下载到本地,并加载到内存进行merge,这个过程称为checkpoint。

步骤详解:

1)secondary namenode通知namenode要进行checkpoint了。(定时,或是namenode上的editlog数量达到一定规模)。

2)namenode做准备。

3)secondary namenode将namenode的editlogs下载到本地磁盘上。

4)secondary namenode将editlogs和fsimage加载到内存中,进行合并产生新的fsimage。

5)secondary namenode将新的fsimage传回给namenode(覆盖namenode上旧的fsimage文件),并将其保存到本地磁盘上覆盖掉旧的fsimage。

注意点:

  • a表示,hdfs上数据的更新修改等操作都会先写入编辑日志文件,再更新到内存里。
  • secondary namenode节点只有在启动后,第一次进行checkpoint时才会将namenode的editlog和fsimage都下载到自己的本地磁盘,再进行合并。后期的checkpoint都只会下载editlog文件,而不会下载fsimage,因为自己磁盘上保存的fsimage和namenode上的是一样的。

NameNode高可用(High Availability,HA)

即使将namenode内存中的元数据备份在多个文件系统中,并通过secondary namenode的checkpoint功能防止namenode的数据丢失,但依然无法实现namenode的高可用。namenode一旦失效,整个系统将无法提供服务,管理员通过冷启动的方式让新的namenode上线需要一段等待的时间(几十分钟,甚至更长)。新的namenode在响应服务前必须经历以下以下步骤:将元数据导入内存;重做编辑日志文件;接收到足够多的来自datanode的数据块报告并退出安全模式(数据块的位置信息不保存在元数据中,需要namenode启动时在datanode向其汇报的块信息中获取)。

针对以上问题,hadoop的2.x版本提出了namenode的HA解决方案。

1)主控服务器由一主(Active NameNode,ANN)一从(Standby NameNode,SNN)两台服务器构成。

2)ANN响应客户端请求,SNN作为ANN的热备份机,同步ANN保存的元数据,在ANN失效时转换成新的ANN,快速提供服务。

3)ANN和SNN之间通过高可用的共享存储系统保持数据一致(ANN将数据写入共享存储系统,SNN一直监听共享系统,一旦数据发生改变就将其加载到自己内存中)

4)datanode同时向ANN和SNN汇报心跳和block信息。

5)故障转移控制器(Failover Contraller,FC),监控ANN和SNN的状态,并不断向ZK集群汇报心跳信息。

6)ZK集群"选举领导者",一旦发现ANN失效,就重新选举SNN作为新的领导者,FC通知其转变为新的ANN。Hadoop刚启动时,两台NameNode都是SNN,zk集群通过选举产生领导者作为ANN。

7)snn负责做checkpoint。

NameNode联盟(联邦HDFS)

1)namenode的内存数据包括两块内容,命名空间和数据块池(在namenode联盟中这两块数据相加被称为命名空间卷)。

2)命名空间中保存的内容包括文件或目录的拥有者,修改日期,以及文件被切分为哪几个块等信息,但不包括块到底是存储在哪些datanode中的信息(block位置信息)。

3)数据块池中保存着block位置信息(namenode刚启动时并没有block位置信息,是由datanode向其发送的block块信息中获取的)

4)datanode很好地支持水平扩展,但单一namenode受内存空间限制,使得HDFS中所能容纳的最大文件数量受到限制(一个大文件和一个小文件的元数据所占内存空间大小是基本相同,所以不适合存小文件,会很快占满namenode的内存)。

5)单一namanode使得所有来自客户端的请求都由一台服务器响应,很容易达到其性能上线,无法实现性能上的水平扩展。

6)单一namenode无法隔离来自不同客户的请求(比如本地实验时,对namenode的负载影响会导致正常用户的访问请求受到延迟等)

由于单一namenode存在以上4,5,6所述的问题,hadoop2.0给出了namenode联盟的解决方案,实现对namenode的水平扩展。

1)将一个大的命名空间切割成若干子命名空间,每个namenode管理命名空间中的一部分(如一个namenode管理/user下的所有文件,另一个管理/test下的所有文件)。

2)每个namenode单独管理自己的命名空间和数据块池(也可将所有数据块池抽离出来,由另外的服务器集群来担任此功能),两两之间不进行通信,一个namenode宕机不会影响其他namenode工作。

3)所有datanode被所有namenode共享,还是担任存储数据的功能。每个数据块的信息保存在唯一的某个数据块池中。

4)所有datanode都要注册每一个namenode,为每个namenode提供存储数据的服务。

5)每个datanode向所有的namenode发送心跳和block信息,每个namenode再根据自己的子命名空间维护自己的数据块池。

namenode的安全模式

namenode刚启动时将fsimage加载到内存里,而fsimage里没有块的位置信息,所以此时namenode的内存中没有block的位置信息。namenode会等待所有datanode向它汇报自己的块的位置信息,只有当namenode的内存中获取到了足够多(可配置)的块的位置信息,它才会退出安全模式,正常提供服务。

【图文详解】HDFS基本原理的更多相关文章

  1. 图文详解 HDFS 的工作机制及其原理

    大家好,我是大D. 今天开始给大家分享关于大数据入门技术栈--Hadoop的学习内容. 初识 Hadoop 为了解决大数据中海量数据的存储与计算问题,Hadoop 提供了一套分布式系统基础架构,核心内 ...

  2. Apache版本的Hadoop HA集群启动详细步骤【包括Zookeeper、HDFS HA、YARN HA、HBase HA】(图文详解)

    不多说,直接上干货! 1.先每台机器的zookeeper启动(bigdata-pro01.kfk.com.bigdata-pro02.kfk.com.bigdata-pro03.kfk.com) 2. ...

  3. 执行bin/hdfs haadmin -transitionToActive nn1时出现,Automatic failover is enabled for NameNode at bigdata-pro02.kfk.com/192.168.80.152:8020 Refusing to manually manage HA state的解决办法(图文详解)

    不多说,直接上干货! 首先, 那么,你也许,第一感觉,是想到的是 全网最详细的Hadoop HA集群启动后,两个namenode都是standby的解决办法(图文详解) 这里,nn1,不多赘述了.很简 ...

  4. Flume启动时报错Caused by: java.lang.InterruptedException: Timed out before HDFS call was made. Your hdfs.callTimeout might be set too low or HDFS calls are taking too long.解决办法(图文详解)

    前期博客 Flume自定义拦截器(Interceptors)或自带拦截器时的一些经验技巧总结(图文详解) 问题详情 -- ::, (agent-shutdown-hook) [INFO - org.a ...

  5. Flume启动报错[ERROR - org.apache.flume.sink.hdfs. Hit max consecutive under-replication rotations (30); will not continue rolling files under this path due to under-replication解决办法(图文详解)

    前期博客 Flume自定义拦截器(Interceptors)或自带拦截器时的一些经验技巧总结(图文详解)   问题详情 -- ::, (SinkRunner-PollingRunner-Default ...

  6. Hadoop集群搭建安装过程(三)(图文详解---尽情点击!!!)

    Hadoop集群搭建安装过程(三)(图文详解---尽情点击!!!) 一.JDK的安装 安装位置都在同一位置(/usr/tools/jdk1.8.0_73) jdk的安装在克隆三台机器的时候可以提前安装 ...

  7. MapReduce工作原理图文详解 (炼数成金)

    MapReduce工作原理图文详解 1.Map-Reduce 工作机制剖析图: 1.首先,第一步,我们先编写好我们的map-reduce程序,然后在一个client 节点里面进行提交.(一般来说可以在 ...

  8. 大数据学习系列之五 ----- Hive整合HBase图文详解

    引言 在上一篇 大数据学习系列之四 ----- Hadoop+Hive环境搭建图文详解(单机) 和之前的大数据学习系列之二 ----- HBase环境搭建(单机) 中成功搭建了Hive和HBase的环 ...

  9. 大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解

    引言 在之前的大数据学习系列中,搭建了Hadoop+Spark+HBase+Hive 环境以及一些测试.其实要说的话,我开始学习大数据的时候,搭建的就是集群,并不是单机模式和伪分布式.至于为什么先写单 ...

  10. 全网最详细的HA集群的主节点之间的双active,双standby,active和standby之间切换的解决办法(图文详解)

    不多说,直接上干货! 1. HA集群的主节点之间的双standby的解决办法: 全网最详细的Hadoop HA集群启动后,两个namenode都是standby的解决办法(图文详解) 2. HA集群的 ...

随机推荐

  1. Linux服务器Jboss运行环境搭建步骤和开机自动启动脚本编写运行

    Jboss运行环境:Linux+Jdk+Jboss+jsp系统 Jboss软件说明:类似于Tomcat,就是一个跑Jsp系统的环境,他的站点路径跟Tomcat类似,Tomcat存放站点文件到webap ...

  2. Ext JS 6应用程序Build后出现“c is not a constructor return new c(a[0])”的处理

    概述 在对Ext JS 6的应用程序打包后,时不时会出现以下错误: 由于是压缩后出现的错误,要进行调试也无从下手,因而这个错误会令新手手足无措,不知道是怎么回事. 错误原因 造成该错误的主要原因是要创 ...

  3. Mybatis事务(三)事务工厂

    在前面一篇博客Mybatis事务(一)事务管理方式中我们提到,mybatis及spring提供了三个事务实现类:JdbcTransaction.ManagedTransaction和SpringMan ...

  4. Chipmunk Rigid Bodies:cpBody

    Chipmunk刚体支持3种不同的类型: Dynamic(动态),Static(静态)以及Kinematic(混合态)刚体.它们拥有不同的行为和性能特征. 动态刚体是默认的刚体类型.它们可以对碰撞做出 ...

  5. iOS屏幕适配-iOS笔记

    学习目标 1.[了解]屏幕适配的发展史 2.[了解]autoResizing基本用法 3.[掌握]autoLayout 的基本用法 4.[掌握]autoLayout代码实现 5.[理解]sizeCla ...

  6. C# 基于密码的身份验证报错问题System.Net.NetworkCredential

    今天碰到个很奇怪的问题,在用下面这段代码调试时获取身份验证时居然报错,更奇怪的是本地VS中调试正常而在虚机上调试就报错了 ClientCredentials clientCredentials = n ...

  7. Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局

    Android实训案例(八)--单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局 阿法狗让围棋突然就被热议了,鸿洋大神也顺势出了篇五子棋单机游戏的视频,我看到了就像膜拜膜拜,就 ...

  8. 开源视频平台:ViMP

    ViMP是一个开源的视频平台,可以用于建立自己的视频门户.可以用于VoD系统,网络学习系统,企业内部视频系统的搭建. 这一阵子一直在研究网络视频平台.发现这类的开源系统相对来说还是比较少的,因此在发现 ...

  9. Java-collections总结

    纸上得来终觉浅,绝知此事要躬行  --陆游    问渠那得清如许,为有源头活水来  --朱熹 类Collections是一个包装类.它包含有各种有关集合操作的静态多态方法.此类不能实例化,就像一个工具 ...

  10. 线性表链式存储设计与实现 - API实现

    基本概念 链式存储定义 为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息. 表头结点 链表中的第一个结点,包含指向第一个数据元素的指针以 ...