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

    1,HDFS体系结构
    ··· HDFS是采用master/slaves即主从结构模型来管理数据的。这种模型主要由四部分组成,分别是Client、NameNode、DataNode、SecondaryNameNode。一个HDFS集群包括一个 NameNode(HA除外)和若干个 DataNode以及一个SecondaryNameNode。其中,NameNode是名称节点,负责管理HDFS的文件命名空间和处理client的请求。DataNode负责保存实际的数据,并负责管理客户端的读写请求,在NameNode的调度下进行数据的增删改查和复制;DataNode会定期向NameNode发送心跳包来汇报自己的存活信息和块的信息。用户在使用Client进行 I/O操作时,与使用普通文件系统一样,但是在HDFS内部,HDFS会将存入的文件进行分块并保存在若干个DataNode上。SecondaryNameNode负责帮助把NameNode上的edit文件合并到fsimage文件,再发送给NameNode,实现冷备份。
     
    2,HDFS组件
    ··· NameNode
        · 管理系统的命名空间,并用fsimage和edit来保存。
        · 在内存中保存块的位置信息。
        · 实施副本冗余策略,以及处理客户端的请求。
    ··· DataNode
        · 保存实际的数据。
        · 提供数据的读写。
        · 心跳机制(3秒)。汇报自身信息和数据信息。
    ··· SecondaryNameNode
        · 帮助NameNode合并fsimage和edit文件。
        · 实现冷备份。
        · 检查点机制。
    ··· Client
        · 为用户访问HDFS提供接口。可以不属于HDFS集群。
        · 与NameNode交互,获取文件块的位置。
        · 与DataNode交互,读写数据。
        · 上传时分块,读取时分片。
     
    3,HDFS工作机制
    ··· 心跳机制
        · DataNode通过心跳机制向NameNode汇报自身存活信息(3秒);启动时会汇报数据块信息,此后每隔一个小时汇报一次
        · NameNode通过心跳机制向DataNode发送指令。
        · NameNode启动后会开启一个IPC服务,等待DataNode节点连接。DataNode启动后就会主动连接。
        · 如果主节点长时间没有收到从节点发来的信息,就会认为从节点挂了。
        · 超时时间:2*recheck + 10*heartbeat;recheck默认是5分钟,heartbeat默认是30秒,所以超时时间为10分钟30秒。
    ··· 检查点机制
        · SecondaryNameNode负责合并fsimage和edit文件;减少edit文件大小,缩短启动时间,更快的推出安全模式。
        · 两个文件的合并周期,称之为检查点机制。
        · 在hdfs-site.xml中配置。默认1个小时合并一次;或者txid执行次数达到100万次,每1小时检查一次txid文件。
     
    ··· 机架感知
        · 在部署hadoop集群时,节点之间的距离会影响数据备份的速度。
        · 第一个副本在client所在的节点,如果client在集群外,则随机选一个。
        · 第二个副本与第一个副本在不同的机架,节点随机选一个。
        · 第三个副本与第二个副本在同一个机架,但是在不同的节点。
     
    4,HDFS启动过程
    ··· NameNode启动时会将fsimage读入内存,然后执行editLog文件中的各项操作,使内存中的元数据保持最新。然后创建一个新的fsimage文件和一个空的editLog文件,此后的操作都写入新的editLog文件中。在这个过程中NameNode处于安全模式,只能对外提供读操作,不能进行写操作;启动结束后就可以进入正常状态,可读写。
    ··· 集群模式启动时会启动slaves文件中记录的主机中的DataNode进程。DataNode启动时会主动向NameNode发送自己保存的块的信息,此后每隔一个小时发送一次。
     
    5,读数据流程
    ··· 1,client通过FileSystem对象的open方法来打开要读取的文件(编写的代码),对于HDFS来说,这个对象是DistributedFileSystem,他通过RPC调用NameNode,来确定文件起始块的位置。
    ··· 2,对于每一个块,NameNode会返回存有该块的DataNode的地址,并按照距离client的远近来排序。
    ··· 3,DistributedFileSystem是的实例会返回一个FSDataInputStream对象给client,以便读取数据;然后client就可以调用FSDataInputStream实例的read方法来获取数据。
    ··· 4,FSDataInputStream随即连接与第一个块距离最近的DataNode,通过反复调用read方法将数据从DataNode传输到client;当传输到块的末端时,FSDataInputStream关闭与DataNode的连接,并寻找下一个块的最佳DataNode。
    ··· 5,读取时是按块读取的,当client读取完成时就会调用FSDataInputStream的close方法。
    ··· 6,如果读取的过程中出现错误,数据损坏,则会到其他DataNode副本上读取数据,并将损坏的DataNode汇报给NameNode。
     
    6,写数据流程
    ··· 1,client通过FileSystem对象的create方法来创建一个新文件;对于hdfs系统,DistributedFileSystem对NameNodeRPC创建一个RPC调用,在文件系统的命名空间中新建一个文件,此时该文件中还没有相应的数据块。
    ··· 2,NameNode执行各种不同的检查,以确保这个文件不存在,以及客户端有创建文件的权限。如果检查失败则向客户端抛出一个IOException;如果成功,则DistributedFileSystem向客户端返回一个FSDataOutputStream对象,于是客户端就可以开始写数据了。
    ··· 3,客户端在写入数时,FSOutputStream将它分成一个个数据包(packet),并写入内部的 数据队列(data queue)。DataStreamer线程负责处理数据队列,向NameNode请求上传一个block(0~128M),NameNode这时会为这个文件分配一个数据块,并返回给客户端一组DataNode。
    ··· 4,以默认3个副本为例,这三个DataNode会构成一个管道;DataStreamer将数据流式传输到管道中的第一个DataNode的内存中,这个DataNode在把数据包写入到本地磁盘的同时,会将这个数据包发送到第二个DataNode;同样,第二个DataNode也会发送给第三个DataNode。DateStreamer在将一个个packet流式传输到第一个DataNode后,还会将此packet移动到 确认队列(ack queue)中。DataNode写入数据成功后,会向ResponseProcessor线程发送一个成功的信息回执,当收到所有DataNode的确认信息后,ResponseProcessor线程会将该数据包从确认队列中删除。
    ··· 5,如果任何DataNode在写入数据时发生故障。首先会关闭管道,然后把确认队列中的所有数据移动到数据队列中的最前端,以确保故障节点下游DataNode的不会漏掉 任何一个数据包;为一个正常的DataNode的当前数据块创建一个标识,并把该标识传给NameNode,以便故障DataNode在恢复后可以删除保存的部分数据块;删除故障的DataNode,正常的两个DataNode构成新的管道,并把余下的数据写入新的管道中;NameNode发现副本不足,会在一个新的DataNode上创建副本。
     
     
     
    7,DataStreamer线程与Packet
    ··· 1,client会写数据到流内部的一个缓冲区中,然后数据被分成多个packet,每个packet的大小是64k字节;而每个packet又由一组chunk和这组chunk对应得checksum组成,每个chunk大小为512字节,而checksum是对chunk计算的校验和。
    ··· 2,当client写入的流数据达到一个packet的长度时,这个packet就会被构建出来,然后放入dataQueue队列中;然后DataStreamer会不断的从dataQueue队列中取出packet,发送到DataNode管道中的第一个DataNode,并将该packet从dataQueue队列移动到ackQueue队列。
    ··· 创建packet:client写数据时,当长度满足一个chunk大小(512B)时,便会创建一个packet对象,然后向packet对象中写checksum和实际数据;每满足一个chunk时就会向packet对象中写入上诉信息;直到    达到一个packet大小(64KB),就会将该packet放入dataQueue队列中,等待DataStreamer线程取出。
     
     
     
    注意事项
        · client(客户端)就是我们写代码所在的机器,可以不属于HDFS集群。
        · HDFS中的分块是实际的物理分块,而MapReduce中的分片是逻辑分片。
        · hdfs中不适合存储小文件,因为一个块的元数据大约为150字节,1亿个块无论大小都会占用20G左右的内存。
        · 由于fsimage的访问承受能力有限,所以先把修改操作保存到edit文件,再在空闲时合并到fsimage。
        · hdfs的安全模式相当于维护模式,不允许添加和修改hdfs上的文件。默认是关闭的可以通过hdfs dfsadmin -safemode          enter打开(enter | leave | get | wait)。
        · NameNode的fsimage不会保存块在哪个DataNode,即NameNode不会在磁盘中保存块的位置信息,而是在每次启            动时由DataNode汇报块的信息,然后NameNode将这些信息保存在内存中。
  • 相关阅读:
    OleDbCommand 的用法
    递归求阶乘
    C#重写窗体的方法
    HDU 5229 ZCC loves strings 博弈
    HDU 5228 ZCC loves straight flush 暴力
    POJ 1330 Nearest Common Ancestors LCA
    HDU 5234 Happy birthday 01背包
    HDU 5233 Gunner II 离散化
    fast-IO
    HDU 5265 pog loves szh II 二分
  • 原文地址:https://www.cnblogs.com/shendeng23/p/12364061.html
Copyright © 2011-2022 走看看