hdfs是hadoop框架的一个核心组件,就是一个分布式文件系统,主要负责存储大数据集。
传统文件系统中的块 没有规定块的大小是统一的,因此有以下缺点 – 1. 负载不均衡: 每台机器上存储的文件大小非常不均匀,有的机器只存储很小的文件,有的机器存储很大的文件。 – 2. 网络瓶颈问题: 网络带宽本来就稀缺,用户在使用时,集中到某几台机器上读取文件,因此本来就已经很稀缺的网络带宽有被稀释了。
– hdfs的块大小统一,固定的。 – hdfs的块大小可以自定义 默认情况: hadoo1.x ---->64M hadoo2.x ---->128M hadoo3.x ---->256M – 块是hdfs的最小存储单元 – 块使用了副本的概念(提高数据的安全性,可靠性) – 块的多个副本一定是布局到不同的机器上的(一个机器不可能有一个块的两个副本 近远远 ) – 文件的最后一个块,通常是小于128M,实际大小是多少,就占磁盘多少空间。
1、块不能太大,太大就和传统文件系统一样,会出现负载不均衡,网络带宽瓶颈,多用户访问时,集中到某几台机器上,下载时间过长,下载速度过慢 2、块不能太小。原因如下: (1)最小化寻址开销时间 寻址时间一般在10ms左右,如果块太小,下载时间和寻址时间接近,不是最佳比例,一般选择1:100的比例,也就是1s能传输的文件大小作为一个块的大小。 (2)namenode的内存利用率 无论块的大小有多大,它的元数据的大小都是150字节左右,所以说存储大量小文件的话,会大大降低集群的 存储能力。
1、高容错,高可靠(机器宕机是常态)副本机制,一台节点副本丢失后,会自动恢复。 2、可以存储大数据集 3、利用集群并发计算分析,性能高 4、廉价机器,构建成本低
1、不适合低延迟数据访问(hdfs的延迟较高) 2、不适合存储小文件 3、不适合并发写入,以及文件的随机修改
1、管理集群文件的元数据 2、响应client的读写请求 3、实施副本冗余策略(自动恢复丢失的副本) 4、在内存中维护所有datanode存储的块的位置映射关系
1、真正存储数据的地方 2、执行数据块的读写操作 3、3秒一次的心跳机制(向namenode报告自己存储的块的信息以及自己的健康状况)
帮助namenode进行日志合并(fsimage和edits)
1、提供了各种语言操作hdfs的接口 2、和namenode进行交互,获取文件的存储位置(读、写) 3、和datanode进行交互,读写数据 4、上传文件时分块上传,下载文件时分片下载
命名空间镜像文件,它是文件系统元数据的一个完整的永久检查点,内部维护的是最近一次检查点的文件系统树和整棵树内部的所有文件和目录的元数据,如修改时间,访问时间,访问权限,副本数据,块大小,文件的块列表信息等等。 fsimage默认存储两份,是最近的两次检查点
集群正常运行时,客户端的所有的更新操作(如打开,关闭,创建,删除,重命名等)除了在内存中维护之外,还会被写到edit文件中。并不直接写入到fsimage中。(因为对于分布式文件系统而言,fsimage镜像文件通常都很大,如果直接将客户端操作添加到fsimage会很慢。相对而言,edit日志文件通常远远小于fsimage,一个edit最大64M。)
1、会生成集群的唯一标识 2、会生成块池的唯一标识 3、会生成fsimage文件,以及存储位置
1、生成edit文件 2、在每个datanode上生成存储块的目录
1、namenode将最近一次的fsimage和edit文件加载到内存中 2、进行checkpoint机制(满足条件才会进行 ) 3、进入安全模式(用户只读,不能进行其他操作),等待datanode的心跳反馈,当收到99.9%(可以设置)的块的至少一个副本后,15秒后退出安全模式。
1、当满足条件(1小时,64M,100万次操作),secondraynamenode会向namenode发出合并请求 2、收到请求后的namenode创建一个新的edit文件,并且将最新的fsimage和所有的edit文件发送给secondraynamenode。 3、secondraynamenode将fsimage和所有的edit文件加载到内存中,将两个文件进行合并 4、将合并后的新文件发送给namenode 5、namenode将收到的文件改名,并且将最旧的fsimage删除
Namenode启动时,首先要加载fsimage文件到内存,并逐条执行editlog文件里的事务操作,在这个期间一但在内存中成功建立文件系统元数据的映像,就会新创建一个fsimage文件(该操作不需要SecondaryNamenode)和一个空的editlog文件。在这个过程中,namenode是运行在安全模式下的,Namenode的文件系统对于客户端来说是只读的,文件修改操作如写,删除,重命名等均会失败。
系统中的数据块的位置并不是由namenode维护的,而是以块列表的形式存储在datanode中。在系统的正常操作期间,namenode会在内存中保留所有块位置的映射信息。在安全模式下,各个datanode会向namenode发送最新的块列表信息,如果满足“最小副本条件”,namenode会在30秒钟之后就退出安全模式,开始高效运行文件系统.所谓的最小副本条件指的是在整个文件系统中99.9%的块满足最小副本级别(默认值:dfs.replication.min=1)。
PS:启动一个刚刚格式化完的集群时,HDFS还没有任何操作呢,因此Namenode不会进入安全模式。
因为naemnode是不会在磁盘中保存数据块的位置等信息,(只在内存中),如果namenode重启或者关机,开机之后是没有数据块的信息的,所以使用心跳机制来向namenode发送数据块的信息。datanode通过心跳机制来向namenode发送自己的健康状态和数据块的信息,naemnode也可以通过心跳机制来对datanode下发一些指令。
2.8.2之前 近近远 2.8.2之后 近远远
近远远: 第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。 第二个副本与第一个副本不相同机架,随机一个节点进行存储 第三个副本与第二个副本相同机架,不同节点。
1、client调用distributedFileSystem对象调用RPC连接namenode,新建一个文件,此时该文件中没有数据块 2、namenode会检查集群中是否有这个文件,这个client是否有创建新文件的权限 3、如果这些检查全部通过,则分布式文件对象返回client一个DFSOutputStream数据流对象,如果没有通过则返回给client一个IOException。 4、client调用DFSOutputStream对象会将文件在内存中切分成一个个64kb大小的包,并且放到一个数据队列中 5、然后调用datastreamer线程和namenode进行通信根据负载情况返回副本个数的子节点,将这几个子节点连接起来 形成一个管道 6、datastreamer将包连续的传给第一个子节点,第一个节点保存之后再将包发给第二个节点,第二个节点保存之后再将包发给第三个节点,一直到最后一个节点。 7、在datastreamer向第一个节点发送包的时候同时将包移动到内存中的一个确认队列,当收到所有节点的接收成功的确认信息时,会将确认队列中的包删除 8、当第一个块的最后一个包传输完成后,会断开与datanode的连接,然后取第二个块的存储节点,重复以上步骤完成文件的上传 9、当所有块上传完毕之后,会向naemnode发送完成信息回执,namenode更新元数据
1、client调用DestributedFileSyst对象的open()方法打开想要读取的文件,namenode会检查此文件是否存在并且检查client是否拥有权限。远程调用namenode确认首个块的位置 2、namemode会根据拥有该文件的datanode和client的距离远近来排序,返回客户端最近的 那个节点 3、DistributedFileSystem对象会返回给client一个FsDataInputStream,然后FsDataInputStream调用read()方法开始读最近的第一个块所在的datanode 4、当读完之后,FsDataInputstream会关闭和datanode的连接,重复以上步骤读下一个块