• hdfs内幕解析


    1.hdfs的架构以及block块和副本机制

      hdfs分布式文件系统也是一个主从架构,主节点是我们的namenode,负责整个集群以及维护集群的元数据信息。从节点是datanode,主要负责文件数据存储。

      hdfs将所有的文件全部抽象为block块来进行存储,不管文件大小,全部一视同仁都是以block块的形式进行存储,方便我们的分布式文件系统对文件的管理。

      在hadoop1文件的block块默认的大小是64M,而在hadoop2中文件的block块大小默认是128M。block块大小可以通过hdfs-site.xml当中的配置进行指定。

      <property>

             <name>dfs.block.size</name>

             <value>块大小 以字节为单位</value>//只写数值就可以

      </property>

      1)抽象成数据块的好处

        a)一个文件有可能大于集群中任意一个磁盘,大文件可以拆成多个block块完成存储

        b)使用块抽象而不是文件可以简化存储子系统

        c)块非常适合用于数据备份进而提供数据容错能力个可用性

      2)块缓存

        通常datanode从磁盘中读取块,但对于访问频繁的文件,其对应的块可能被显示的缓存在datanode的内存中,以堆外块缓存的形式存在。默认情况下,一个块仅缓存在一个datanode的内存中,当然可以针对每个文件配置datanode的数量。作业调度器通过在缓存块的datanode上运行任务,可以利用块缓存的优势提高读操作的性能    

      3)hdfs文件权限验证

        hdfs的文件权限机制与linux系统的文件权限机制类似

        r:read、w:write、x:execute  权限x对于文件表示忽略,对于文件夹表示是否有权访问其内容

        如果linux系统用户a使用hadoop命令创建一个文件,name这个文件在hdfs当中的owner就是a

        hdfs文件权限的目的是防止好人做错事,而不是阻止坏人做坏事。hdfs相信你告诉我你是谁你就是谁    

      4)hdfs的副本因子

        为了保证block块的安全性,也就是数据的安全性,在hadoop2当中,文件默认保存三个副本,我们可以修改副本数以提高数据的安全性

        在hdfs-site.xml 当中修改一下配置属性,即可更改文件的副本数,需要重新启动

        <property>

          <name>dfs.replication</name>

          <value>3</value>

        </property>

        命令修改

           hdfs dfs -setrep num file:指定文件修改副本数、及时生效

    2.hdfs的读写流程

      1)hdfs的写入流程

        

        创建文件

        ①HDFS clinet 调用DistributedFileSystem.create()

        ②RPC远程调用namenode的create(),会在hdfs的目录树中指定的路径添加新文件,并返回给client FSDataOutPutStream,他是DFSOutPutStream的子类

        (每次写入一个block,所有以下流程重复执行,直到文件所有的block都写入成功)

        建立数据流管道pipeline:

        ③client调用FSDataOutPutStream.write()写数据(每次写一个块)

        ④DFSOutPutStream通过RPC调用namenode的addblock(),向namenode申请一个空数据块

        ⑤addBlock返回locatedBlock对象,此对象包含了当前的block要存储在哪三个datanode

        ⑥客户端根据位置信息建立流管道(蓝色线)

        向数据流管道写当前的块数据

        ⑦写数据时,现将数据写入一个检验块chunk中,写满512字节后,对此chunk计算校验值

        ⑧将chunk与对应的校验值一起写入packet中,一个packet是64k

        ⑨源源不断地带着校验的chunk写入packet,packet写满后,将packet写入data queue

        ⑩packet从data queue中取出,沿着pipeline发送到dn1,再从dn1发送到dn2,再从dn2发送到dn3

        ⑪同时packet也会保存一份到 ack queue

        ⑫packet到达dn3后做校验,将校验结果逆着pipeline返回到dn2,dn2做校验传送到dn1,dn1也做校验结果返回到client

        ⑬客户端根据校验结果进行操作,如果返回成功则将保存在ack queue中的packet移除,如果失败则将packet从ack移除在加到data queue队尾

        ⑭block一个个packet传出,当此block发送完成,即dn1,dn2,dn3都有了block的完整副本,三个datanode分别发送RPC消息调用namenode的blockReceivedAndDeleted()更新namenode中datanode与block的映射关系,关闭pipeline数据流管道。

        循环执行 ③ ~ ④ ,当文件所有的block都发送成功继续执行⑮

        ⑮文件的所有block发送成功,调用DFSDataOutPutStream.Close()

        ⑯客户端调用namenode的complete(),告知namenode提交这个文件所有的块数据,也就是整个文件的写入流程

        写入的问题:

          如果期间有datanode挂掉,data queue通知namenode创建新的datanode,并将现在主datanode的数据复制到新的datanode,续传data      

      2)hdfs的读取流程

        

        ①client通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件所在的地址

        ②挑选一台datanode(就近原则,然后随机)服务器,请求读取数据

        ③datanode开始传输数据给客户端(从磁盘里读取数据输入流,以packet单位来做校验)

        ④客户端以packet单位接收,现在本地缓存,然后写入目标文件

  • 相关阅读:
    c# 复制整个文件夹的内容,Copy所有文件
    c# 创建文件夹
    c# 访问共享文件
    sublimit 编辑器 设置默认的编码
    WPF xml配置文件里面的大于小于号转义
    c# datatable 分组
    WPF 耗时操作时,加载loging 动画 (BackgroundWorker 使用方法)
    WPF DEV gridcontrol 自定义计算列(TotalSummary)
    postgresql 创建gin索引
    WPF DEV gridcontrol当前项的数据导出为mdb文件
  • 原文地址:https://www.cnblogs.com/dan2/p/12655022.html
Copyright © 2020-2023  润新知