zoukankan      html  css  js  c++  java
  • 理解HDFS

    HDFS

    HDFS (Hadoop Distributed FileSystem) 是 Hadoop 分布式文件系统,以流式数据访问模式来存储超大文件,运行与商业硬件集群上,管理网络中跨多台计算机存储的文件系统,是分布式计算中数据管理的的基础。

    流式数据访问模式 : 指的是数据不是一次性获取过来,而是一点一点获取,处理流式数据也会一点一点处理。(全部接收在处理的话,延迟会很大)

    (1)HDFS优点

    1. 高容错性:数据自动保存多个副本。它通过增加副本的形式,提高容错性,某一个副本丢失以后,它可以自动恢复
    2. 适合批处理
    3. 适合处理大数据
    4. 易于构建在廉价的机器上
    5. 流式数据访问

    (2)HDFS不适合的领域

      1.低延时数据访问

        比如毫秒级的来存储数据,这是不行的,它做不到。它适合高吞吐率的场景,就是在某一时间内写入大量的数据。但是它在低延时的情况下是不行的,比如毫秒级以内读取数据,这样它是很难做到的。

        HDFS是单Master的,所有的对文件的请求都要经过它,当请求多时,肯定会有延时。

      2.小文件存储

        存储大量小文件的话,它会占用 NameNode大量的内存来存储文件、目录和块信息(元信息)。这样是不可取的,因为NameNode的内存总是有限的。小文件存储的寻道时间会超过读取时间,它违反了 HDFS的设计目标。

      3、并发写入、文件随机修改

        一个文件只能有一个写,不允许多个线程同时写。仅支持数据 append(追加),不支持文件的随机修改。

    (3)HDFS针对缺点的改善措施

    • HDFS不适合低延时数据访问,可以使用缓存或者多Master节点设计降低Client的数据访问压力
    • 存储小文件问题

      1、利用SequenceFile、MapFile、Har等方式归档小文件,这个方法的原理就是把小文件归档起来管理,HBase就是基于此的。对于这种方法,如果想找回原来的小文件内容,那就必须得知道与归档文件的映射关系。

      2、横向扩展,一个Hadoop集群能管理的小文件有限,那就把几个Hadoop集群拖在一个虚拟服务器后面,形成一个大的Hadoop集群。google也是这么干过的。

      3、多Master设计,正在研发中的GFS II也要改为分布式多Master设计,还支持Master的Failover,而且Block大小改为1M,有意要调优处理小文件。(Alibaba DFS的设计,也是多Master设计,它把Metadata的映射存储和管理分开了,由多个Metadata存储节点和一个查询Master节点组成。

    (4)HDFS概念

      1、数据块(block)

       每个磁盘都有默认的数据块大小,是磁盘进行读写的最小单位,构建与单个磁盘之上的文件系统通过磁盘数据块进行管理文件系统的块。类似于磁盘文件系统,HDFS中也有数据块的概念,HDFS文件系统也被划分为多个块,块作为独立单元。

       HDFS数据块特点:HDFS中的块大小比文件系统的块大,一般默认64MB(Hadoop2中默认为128MB),而文件系统为几千字节。HDFS小于一个块大小的文件不会占据整个块的空间

      2、namenode

       HDFS集群上有两类节点:管理节点namenode和工作节点datanode。

       namenode管理文件系统的命名空间,维护整个文件系统的所有的目录和文件,以命名空间镜像文件(fsimage)和编辑日志文件(edits)的形式永久的存储在本地。namenode也记录着每个块所在的数据节点信息(不是永久存储,数据启动时由数据节点重建)
         没有namecode节点,文件系统将无法使用,namenode节点服务的机器毁坏的话,文件系统的所有文件将会全部丢失。因此需要做好容错机制。
       第一种机制:备份namenode的元数据文件
       第二种机制:运行一个辅助的namenode服务
     
      3、datanode
        datanode是HDFS中的工作节点,根据需要存储和检索数据块(受客户端或者nodenode的调用),另外datanode会定期的将发送节点中所存储的数据块信息

      4、secondarynamenode

        secondarynamenode辅助后台程序,与namenode通信,以便定期保存namenode的元数据快照。(namenode的备份容错机制)

      5、联邦HDFS

        namenode在内存中保存着每个文件和每个数据块的引用关系(元数据信息),对于一个拥有大量数据的集群来说,namenode节点上的内存将成为限制横向扩展的瓶颈。在Hadoop2中,引入的联邦HDFS系统允许系统添加namenode实现扩展。每个namenode管理着系统文件命名空间的一部分(例如一个namenode管理着 /usr目录下的所有文件,另一个namenode管理着 /share目录下的所有文件)

        在联邦环境下,每个namenode维护一个命名空间卷(包括数据源和文件的所有数据块的数据块池),命名空间卷之间是相互独立的,一个namenode的失效不会影响另外一个namenode,因此集群中的datanode需要注册每个namenode。

    (6)HDFS结构

    HDFS 采用的是Master/Slave架构存储数据,其中主要的组件:Client、namenode、datanode、secondarynamenode

    Client:客户端

    1. 切分文件:文件上传 HDFS 的时候,Client 将文件切分成 一个一个的Block,然后进行存储
    2. 与 NameNode 交互,获取文件的位置信息
    3. 与 DataNode 交互,读取或者写入数据
    4. Client 提供一些命令来访问或者管理 HDFS,比如启动或者关闭HDFS

    Namenode:Master节点(管理节点)

    1. 管理着HDFS文件系统的命名空间,维护整个文件系统的目录和文件(以命名空间镜像文件fsimage和编辑日志文件edits存在在本地)
    2. 记录每个数据库所在你节点的信息(不是永久存储,数据启动时由数据节点重新创建)
    3. 作为一个管理节点,监控datanode节点的运行状况

    Datanode:Slave节点(工作节点)

    1. 文件存储的地方。
    2. 定期发送节点中所存储的节点信息给namenode,让namenode了解datanode是否健康运行(默认3s)

    secondarynamenode:namenode辅助节点,做日志合并,备份namenode节点作用(并非热备份),secondarynamenode和namenode同时运行,一般来说都是运行在不同的机器上,namenode宕机,   secondarynamenode并不能马上替换namenode提供服务。

    1.  辅助 NameNode,分担其工作量。
    2. ​ 定期合并 fsimage和fsedits,并推送给NameNode。
    3. ​ 在紧急情况下,可辅助恢复 NameNode。

    (7)HDFS读写流程

    Client端将数据写入到HDFS

    1. 使用HDFS提供的客户端Client, 向远程的Namenode发起RPC请求
    2. Namenode会检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会为文件创建一个记录, 否则会让客户端抛出异常。Namenode创建一些元数据信息(datanode和数据块的引用信息)
    3. 当客户端开始写入文件的时候, 客户端会将文件切分成多个packets, 并在内部以数据队列“data queue( 数据队列) ”的形式管理这些packets, 并向Namenode申请blocks, 获取用来存储replications的合适的datanode列表, 列表的大小根据Namenode中replication的设定而定
    4. 客户端开始以pipeline( 管道) 的形式将packet写入所有的replications中。 客户端把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, 保持replications设定的数量
    7. 客户端完成数据的写入后, 会对数据流调用close()方法, 关闭数据流
    8. 只要写入了dfs.replication.min的复本数( 默认为1),写操作就会成功, 并且这个块可以在集群中异步复制, 直到达到其目标复本数(replication的默认值为3),因为namenode已经知道文件由哪些块组成, 所以它在返回成功前只需要等待数据块进行最小量的复制

    客户端读取HDFS数据

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

     (8)Namenode结构

      在了解Namenode结构之前,我们先看下存储在namenode节点上的元数据信息。

      

      上图的元数据信息描述为有一个文件a.log,有三个备份,文件a.log分为两个数据块,数据块blk_1、blk_2,blk_1块在{h0,h1,h3}三个datanode 上,blk_2在{h0,h2,h4}三个datanode上

       namenode在格式化之后,会在l临时文件夹(hadoop.tmp.dir 设置,默认在/tmp/hadoop-${user.name})目录下创建一个dfs目录,如下:

      

     VERSION:是一个java properties文件,包含HDFS版本信息。

          namespaceID:文件系统的唯一标识(文件 首次格式化的时候创建,任何datanode注册到namenode之前是不知道namespaceID这个值,以此可以判断鉴别新建的datanode)
          cTime:namenode存储系统的创建时间。刚刚格式化的系统值为0,文件系统升级之后,会更新到新的时间戳
          storageType:表示存储目录包含的是namenode还是datanode
          layoutVersion:是一个负整数,表示持久性数据结构的版本。
     edits:编辑日志文件。文件系统客户端执行写入或者修改操作的时候,这些操作首先被记录到edits中,之后在namenode的内存也会维护这些元数据。是一个appendlog
     fsimage:是存储文件元数据的镜像文件,是一个永久性检查点。
     fstime:最近一次checkpoint的时间
     
     namenode的元数据操作
        文件系统客户端在执行写操作或者修改操作的时候,首先记录在namenode中edits日志文件中,然后将元数据同步到namenode的内存中

    1、Namenode始终在内存中保存metedata,用于处理“读请求。当namenode启动的时候,加载fsimage文件到内存,并且将editslog文件逐条加载到内存。然后生成新的空的editslog和新的数据最全的fsimage文件。

    2、当客户端进行读写操作时,首先将日志记录到editslog,然后将日志加载到内存。

    3、成功后,editslog同步到文件系统。

    4、Fsimage是映像文件,是内存中元数据的checkpoint点,是一个序列化文件,不能在硬盘上直接修改。

    SecondaryNameNode日志合并(创建检查点)

      当 edits文件的 大小和时间超过阀值,触发checkpoint时
    (1)secondarynamenode会请求namenode停止使用edits文件,创建一个新的日志文件edits.new,将新的操作写入到edits.new中
    (2)secondarynamenode从namenode获取edits和fsimage(通过http get)
    (3)secondarynamenode将fsimage载入内存,并执行edits中的操作,生成新的fsimage文件fsimage.ckpt
    (4)secondarynamenode将新的fsimage文件fsimage.ckpt发送给namenode(通过http post)
    (5)namenode接收到新的fsimage文件 fsimage.ckpt,替换旧的fsimage文件,新的edits文件edits.new替换edits文件,同时更新fstime文件,记录最新的checkpoint时间,fsimage更新了,这样edits就不会越来越大
     
    checkpoint配置
    什么时候触发secondarynamenode日志合并?

    在core-site.xml中配置fs.checkpoint.period 指定两次checkpoint的最大时间间隔,默认3600秒。fs.checkpoint.size    规定edits文件的最大值,一旦超过这个值则强制checkpoint,不管是否到达最大时间间隔。默认大小是64M。

    (9)Datanode结构

     DataNode职责:

      提供真实文件数据的存储服务。

      文件块(block):最基本的存储单位。默认64M。(Hadoop2默认128MB)

             对于文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block。HDFS默认Block大小是64MB,以一个256MB文 件,共有256/64=4个Block.

      不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。

      在Hadoop集群中,默认是有三个副本(dfs.replication配置的是HDFS存储时的备份数量),HDFS创建副本的策略一般是:

    • 第一块:本地
    • 第二块:同一机架上的不同机器
    • 第三块:同一机房的不同机架上的机器

      如果备份的副本设置的更多,例如备份4个的话,可能第四块在不同机房的机器上...

     datanode目录结构

      

    VERSION文件和namenode的VERSION文件差不多

      

      namespaceID是datanode首次访问namenode时获取的。

      storageID,对每个datanode是唯一的,可以根据这个属性区分datanode  

    blk_* :表示HDFS Block文件(原始的真实数据)
    blk_*.meta : 表示对应blk_* Block文件的元数据。【datanode定期发送给namenode的元数据信息就是这些】

    块文件的目录扩展

    当目录下的块文件增加到一定的规模的时候,datanode会创建一个子目录存储块文件和块文件元数据。dfs.datanode.numblocks属性设置,控制超过多少数据时,创建子目录存储块文件和元数据,dfs.data.dir属性指定磁盘上的不同目录,这样数据块以轮转的方式(round-robin)写到各个目录中。(同一个datanode上的数据块不会重复,只有不同datanode的数据块才可能会重复)
     
    (10)安全模式
    namenode启动时,首先就将fsimage文件载入内存,并执行编辑日志(edits)中的各项操作。一旦成功创建了元数据的映像,则会创建一个新的fsimage文件(不需要借助secondarynamenode)和一个空的编辑日志edits,此时namenode监听RPC和HTTP请求,但是namenode此时运行在安全模式下。在安全模式下,namenode文件系统对于客户端是只读的 。(严格来讲是访问文件系统元数据的操作是肯定执行的 ,例如展示文件系统目录,对于读文件操作,只有在集群中datanode中的块是可用时,才可以读取,但是对于修改操作,例如修改权限等都会失败)
     
    场景:
    启动一个刚刚格式化的HDFS集群的时候,由于文件系统中还没有块,所以不会进入安全模式。
    如果满足"最小副本条件",namenode会在30秒后退出安全模式(最小副本条件:指的是文件系统中99.9%的块都满足最小副本级别)
    最小副本级别:默认是1,dfs.replication.min属性设置。
     
    进入/退出安全模式
    1、查看是否处于安全模式
    hdfs dfsadmin -safemode get //hdfs dfsadmin是hdfs管理员命令

    2、退出安全模式

    在执行修改和写入操作的时候,需要先退出安全模式

    hdfs dfsadmin -safemode wait
    #command to read or write
     
    3、进入安全模式
    在维护和升级集群的时候非常关键,需要进入安全模式,防止在维护和升级期间的写入和修改操作。
    hdfs dfsadmin -safemode enter

    4、 离开安全模式

    hdfs dfsadmin -safemode leave

     安全模式的下属性

    属性名称 类型 默认值 说明
    dfs.replication.min int 1 最小副本级别:成功执行写操作的最小副本数目
    dfs.safemode.threshold.pct float 0.999 最小副本条件:在namenode退出安全模式之前,满足最小副本级别的比例。设置高于1,永远不会退出安全模式,设置为0或者过小,可能会使得namenode无法启动安全模式
    dfs.safemode.extention int 30 000 在满足最小副本条件之后,namenode还需要处于安全模式的时间(毫秒),对于小集群来说,可以设置为0

     (11)HDFS 命令行

      HDFS有很多接口可以和HDFS交互(java API等),命令行是最简单的,也是入门学习需要了解的。

    常用命令

      hadoop fs 和 hdfs dfs 都可以,但是推荐使用hdfs dfs 

      通过hadoop fs -help 查看

    Usage: hadoop fs [generic options]
        [-appendToFile <localsrc> ... <dst>]
        [-cat [-ignoreCrc] <src> ...]
        [-checksum <src> ...]
        [-chgrp [-R] GROUP PATH...]
        [-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
        [-chown [-R] [OWNER][:[GROUP]] PATH...]
        [-copyFromLocal [-f] [-p] [-l] [-d] <localsrc> ... <dst>]
        [-copyToLocal [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-count [-q] [-h] [-v] [-t [<storage type>]] [-u] [-x] <path> ...]
        [-cp [-f] [-p | -p[topax]] [-d] <src> ... <dst>]
        [-createSnapshot <snapshotDir> [<snapshotName>]]
        [-deleteSnapshot <snapshotDir> <snapshotName>]
        [-df [-h] [<path> ...]]
        [-du [-s] [-h] [-x] <path> ...]
        [-expunge]
        [-find <path> ... <expression> ...]
        [-get [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-getfacl [-R] <path>]
        [-getfattr [-R] {-n name | -d} [-e en] <path>]
        [-getmerge [-nl] [-skip-empty-file] <src> <localdst>]
        [-help [cmd ...]]
        [-ls [-C] [-d] [-h] [-q] [-R] [-t] [-S] [-r] [-u] [<path> ...]]
        [-mkdir [-p] <path> ...]
        [-moveFromLocal <localsrc> ... <dst>]
        [-moveToLocal <src> <localdst>]
        [-mv <src> ... <dst>]
        [-put [-f] [-p] [-l] [-d] <localsrc> ... <dst>]
        [-renameSnapshot <snapshotDir> <oldName> <newName>]
        [-rm [-f] [-r|-R] [-skipTrash] [-safely] <src> ...]
        [-rmdir [--ignore-fail-on-non-empty] <dir> ...]
        [-setfacl [-R] [{-b|-k} {-m|-x <acl_spec>} <path>]|[--set <acl_spec> <path>]]
        [-setfattr {-n name [-v value] | -x name} <path>]
        [-setrep [-R] [-w] <rep> <path> ...]
        [-stat [format] <path> ...]
        [-tail [-f] <file>]
        [-test -[defsz] <path>]
        [-text [-ignoreCrc] <src> ...]
        [-touchz <path> ...]
        [-truncate [-w] <length> <path> ...]
        [-usage [cmd ...]]

     HDFS管理员命令

    hdfs dfsadmin 

     可参照:https://blog.csdn.net/jjshouji/article/details/79087601

     笔摘主要是对HDFS理论的上的了解,具体的操作还是需要多多实战操作...

     参考:https://blog.csdn.net/dpengwang/article/details/79297435

        《Hadoop权威指南》

  • 相关阅读:
    HDU 1728 逃离迷宫
    程序猿求职之道(《程序猿面试笔试宝典》)之不想签约,但也不想轻易放弃机会,怎么办?
    职场生涯(—)
    Python学习笔记24:Django搭建简单的博客站点(二)
    &quot;高可用方案工具包&quot; high availability toolkit 1.1
    [Swift]LeetCode421. 数组中两个数的最大异或值 | Maximum XOR of Two Numbers in an Array
    [Swift]LeetCode420. 强密码检验器 | Strong Password Checker
    [Swift]LeetCode419. 甲板上的战舰 | Battleships in a Board
    [Swift]LeetCode417. 太平洋大西洋水流问题 | Pacific Atlantic Water Flow
    [Swift通天遁地]七、数据与安全-(11)如何检测应用程序中的内存泄露
  • 原文地址:https://www.cnblogs.com/xiaojianfeng/p/9661305.html
Copyright © 2011-2022 走看看