HDFS进阶笔记1

4. 核心概念block

4.1 数据块block

4.1.1 HDFS block块

  • 向HDFS上传文件,是按照128M为单位,切分成一个个block,分散的存储在集群的不同数据节点datanode上

  • 问:HDFS中一个44M大小的块会不会占据128M的空间?

    • 小于一个块大小的文件不会占据整个块的空间
  • 问:这样存储有没有问题?

4.2 block副本
  • 因为HDFS是用普通的商用服务器搭建起来的;所以有节点出问题的可能性;

  • 那么如果每个block只有一份的话,当block所在的节点宕机后,此block将无法访问,进而导致文件无法完整读取

  • 为保正数据的可用及容错,HDFS设计成每个block共有三份,即三个副本

  • 如何设置副本数?

    • replication = 3

    • hdfs-site.xml

    <property>
    	<name>dfs.replication</name>
    	<value>3</value>
    </property>
    
4.3 机架存储策略
  • 实际机房中,会有机架,每个机架上若干服务器

  • 第一块:在本机器的HDFS目录下存储Block的第一个副本。
    第二块:在不同Rack(机架,暂且称为r1)的某个DataNode(称为dn2)上存储Block的第二个副本。
    第三块:在dn2所在机架r1下,找一台其它的datanode节点,存储Block的第三个副本。
    更能多副本:随机节点

了解下服务器参数:https://item.jd.com/4564487.html

机架:https://item.jd.com/16829137698.html

4.4 block的一些操作
  • 设置文件副本数,有什么用?

    • 数据分块存储和副本的存放,是保证可靠性和高性能的关键

    • 方式一:使用命令设置文件副本数;动态生效,不需要重启hadoop集群

      hadoop fs -setrep -R 4 /path
      
    • 方式二:修改配置文件hdfs-site.xml,需要重启hadoop集群才能生效

      <property>
      	<name>dfs.replication</name>
      	<value>4</value>
      </property>
      
  • HDFS提供了fsck命令,用于检查HDFS上文件和目录的健康状态、获取文件的block信息和位置信息

[hadoop@node01 ~]$ hdfs fsck
  • 查看文件中损坏的块
[hadoop@node01 ~]$ hdfs fsck /tmall-201412-1w.csv -list-corruptfileblocks
  • 查看文件的块基本信息
hdfs fsck /02-041-0029.mp4 -files -blocks -locations
  • 删除损坏的文件
[hadoop@node01 ~]$ hdfs fsck  /tmall-201412-1w.csv -delete
4.5 小结
  • HDFS上的文件分块存储
  • 每个块有3个副本
  • 考虑机架存储策略
  • 关于block的一些常用命令:hdfs fsck

5. HDFS架构

  • 大多数分布式框架都是主从架构
  • HDFS也是主从架构Master|Slave或称为管理节点|工作节点
5.1 NameNode

5.1.1 文件系统

  • file system文件系统:操作系统中负责管理和存储文件信息的软件;具体地说,它负责为用户创建文件,存入、读取、修改、转储、删除文件等
  • 读文件 =>>找到文件 =>> 在哪 + 叫啥?
  • 元数据
    • 关于文件或目录的描述信息,如文件所在路径、文件名称、文件类型等等,这些信息称为文件的元数据metadata
  • 命名空间
    • 文件系统中,为了便于管理存储介质上的,给每个目录、目录中的文件、子目录都起了名字,这样形成的层级结构,称之为命名空间
    • 同一个目录中,不能有同名的文件或目录
    • 这样通过目录+文件名称的方式能够唯一的定位一个文件

5.1.2 HDFS-NameNode

  • HDFS本质上也是文件系统filesystem,所以它也有元数据metadata;
  • 元数据metadata保存在NameNode内存
  • NameNode作用
    • HDFS的主节点,负责管理文件系统的命名空间,将HDFS的元数据存储在NameNode节点的内存中
    • 负责响应客户端对文件的读写请求
  • HDFS元数据
    • 文件目录树、所有的文件(目录)名称、文件属性(生成时间、副本、权限)、每个文件的块列表、每个block块所在的datanode列表

    • 每个文件、目录、block占用大概150Byte字节的元数据;所以HDFS适合存储大文件,不适合存储小文件

    • HDFS元数据信息以两种形式保存:①编辑日志edits log②命名空间镜像文件fsimage

      • edits log:HDFS编辑日志文件 ,保存客户端对HDFS的所有更改记录,如增、删、重命名文件(目录),这些操作会修改HDFS目录树;NameNode会在编辑日志edit日志中记录下来;
      • fsimage:HDFS元数据镜像文件 ,即将namenode内存中的数据落入磁盘生成的文件;保存了文件系统目录树信息以及文件、块、datanode的映射关系,如下图

说明:

①为hdfs-site.xml中属性dfs.namenode.edits.dir的值决定;用于namenode保存edits.log文件

②为hdfs-site.xml中属性dfs.namenode.name.dir的值决定;用于namenode保存fsimage文件

5.2 DataNode
  • DataNode数据节点的作用
    • 存储block以及block元数据到datanode本地磁盘;此处的元数据包括数据块的长度、块数据的校验和、时间戳
5.3 SeconddaryNameNode
  • 为什么引入SecondaryNameNode

    • 为什么元数据存储在NameNode在内存中?

    • 这样做有什么问题?如何解决?

    • HDFS编辑日志文件 editlog:在NameNode节点中的编辑日志editlog中,记录下来客户端对HDFS的所有更改的记录,如增、删、重命名文件(目录);

    • 作用:一旦系统出故障,可以从editlog进行恢复;

    • 但editlog日志大小会随着时间变在越来越大,导致系统重启根据日志恢复的时候会越来越长;

    • 为了避免这种情况,引入检查点机制checkpoint,命名空间镜像fsimage就是HDFS元数据的持久性检查点,即将内存中的元数据落磁盘生成的文件;

    • 此时,namenode如果重启,可以将磁盘中的fsimage文件读入内容,将元数据恢复到某一个检查点,然后再执行检查点之后记录的编辑日志,最后完全恢复元数据。

    • 但是依然,随着时间的推移,editlog记录的日志会变多,那么当namenode重启,恢复元数据过程中,会花越来越长的时间执行editlog中的每一个日志;而在namenode元数据恢复期间,HDFS不可用。

    • 为了解决此问题,引入secondarynamenode辅助namenode,用来合并fsimage及editlog

  • SecondaryNameNode定期做checkpoint检查点操作

    • 创建检查点checkpoint的两大条件:
      • SecondaryNameNode每隔1小时创建一个检查点
      • 另外,Secondary NameNode每1分钟检查一次,从上一检查点开始,edits日志文件中是否已包括100万个事务,如果是,也会创建检查点
    • Secondary NameNode首先请求原NameNode进行edits的滚动,这样新的编辑操作就能够进入新的文件中
    • Secondary NameNode通过HTTP GET方式读取原NameNode中的fsimage及edits
    • Secondary NameNode读取fsimage到内存中,然后执行edits中的每个操作,并创建一个新的统一的fsimage文件
    • Secondary NameNode通过HTTP PUT方式将新的fsimage发送到原NameNode
    • 原NameNode用新的fsimage替换旧的fsimage,同时系统会更新fsimage文件到记录检查点的时间。
    • 这个过程结束后,NameNode就有了最新的fsimage文件和更小的edits文件
  • SecondaryNameNode一般部署在另外一台节点上

    • 因为它需要占用大量的CPU时间
    • 并需要与namenode一样多的内存,来执行合并操作
  • 如何查看edits日志文件

    hdfs oev -i edits_0000000000000000256-0000000000000000363 -o /home/hadoop/edit1.xml
    
  • 如何查看fsimage文件

    hdfs oiv -p XML -i fsimage_0000000000000092691 -o fsimage.xml  
    
  • checkpoint相关属性

    属性解释
    dfs.namenode.checkpoint.period3600秒(即1小时)The number of seconds between two periodic checkpoints.

| dfs.namenode.checkpoint.txns | 1000000 | The Secondary NameNode or CheckpointNode will create a checkpoint of the namespace every ‘dfs.namenode.checkpoint.txns’ transactions, regardless of whether ‘dfs.namenode.checkpoint.period’ has expired. |
| dfs.namenode.checkpoint.check.period | 60(1分钟) | The SecondaryNameNode and CheckpointNode will poll the NameNode every ‘dfs.namenode.checkpoint.check.period’ seconds to query the number of uncheckpointed transactions. |

5.4 心跳机制

工作原理:

  1. NameNode启动的时候,会开一个ipc server在那里
  2. DataNode启动后向NameNode注册,每隔3秒钟向NameNode发送一个“心跳heartbeat
  3. 心跳返回结果带有NameNode给该DataNode的命令,如复制块数据到另一DataNode,或删除某个数据块
  4. 如果超过10分钟NameNode没有收到某个DataNode 的心跳,则认为该DataNode节点不可用
  5. DataNode周期性(6小时)的向NameNode上报当前DataNode上的块状态报告BlockReport;块状态报告包含了一个该 Datanode上所有数据块的列表

心跳的作用:

  1. 通过周期心跳,NameNode可以向DataNode返回指令

  2. 可以判断DataNode是否在线

  3. 通过BlockReport,NameNode能够知道各DataNode的存储情况,如磁盘利用率、块列表;跟负载均衡有关

  4. hadoop集群刚开始启动时,99.9%的block没有达到最小副本数(dfs.namenode.replication.min默认值为1),集群处于安全模式,涉及BlockReport;

心跳相关配置

属性解释
dfs.heartbeat.interval3Determines datanode heartbeat interval in seconds.
  • block report
More Actions属性解释
dfs.blockreport.intervalMsec21600000 (6小时)Determines block reporting interval in milliseconds.
  • 查看hdfs-default.xml默认配置文件
5.5 负载均衡
  • 什么原因会有可能造成不均衡?

    • 机器与机器之间磁盘利用率不平衡是HDFS集群非常容易出现的情况
    • 尤其是在DataNode节点出现故障或在现有的集群上增添新的DataNode的时候
  • 为什么需要均衡?

    • 提升集群存储资源利用率
    • 从存储与计算两方面提高集群性能
  • 如何手动负载均衡?

$HADOOP_HOME/sbin/start-balancer.sh -t 5%	# 磁盘利用率最高的节点若比最少的节点,大于5%,触发均衡
5.6 小结
  • NameNode负责存储元数据,存在内存中
  • DataNode负责存储block块及块的元数据
  • SecondaryNameNode主要负责对HDFS元数据做checkpoint操作
  • 集群的心跳机制,让集群中各节点形成一个整体;主节点知道从节点的死活
  • 节点的上下线,导致存储的不均衡,可以手动触发负载均衡

6. HDFS读写流程

6.1 数据写流程

6.1.1 详细流程

  • 创建文件:

    • HDFS客户端向HDFS写数据,先调用DistributedFileSystem.create()方法,在HDFS创建新的空文件
    • RPC(ClientProtocol.create())远程过程调用NameNode(NameNodeRpcServer)的create(),首先在HDFS目录树指定路径添加新文件
    • 然后将创建新文件的操作记录在editslog中
    • NameNode.create方法执行完后,DistributedFileSystem.create()返回FSDataOutputStream,它本质是封装了一个DFSOutputStream对象
  • 建立数据流管道:

    • 客户端调用DFSOutputStream.write()写数据
    • DFSOutputStream调用ClientProtocol.addBlock(),首先向NameNode申请一个空的数据块
    • addBlock()返回LocatedBlock对象,对象包含当前数据块的所有datanode的位置信息
    • 根据位置信息,建立数据流管道
  • 向数据流管道pipeline中写当前块的数据:

    • 客户端向流管道中写数据,先将数据写入一个检验块chunk中,大小512Byte,写满后,计算chunk的检验和checksum值(4Byte)
    • 然后将chunk数据本身加上checksum,形成一个带checksum值的chunk(516Byte)
    • 保存到一个更大一些的结构packet数据包中,packet为64kB大小
  • packet写满后,先被写入一个dataQueue队列中

    • packet被从队列中取出,向pipeline中写入,先写入datanode1,再从datanoe1传到datanode2,再从datanode2传到datanode3中
  • 一个packet数据取完后,后被放入到ackQueue中等待pipeline关于该packet的ack的反馈

    • 每个packet都会有ack确认包,逆pipeline(dn3 -> dn2 -> dn1)传回输出流
  • 若packet的ack是SUCCESS成功的,则从ackQueue中,将packet删除;否则,将packet从ackQueue中取出,重新放入dataQueue,重新发送

    • 如果当前块写完后,文件还有其它块要写,那么再调用addBlock方法(流程同上
  • 文件最后一个block块数据写完后,会再发送一个空的packet,表示当前block写完了,然后关闭pipeline

    • 所有块写完,close()关闭流
  • ClientProtocol.complete()通知namenode当前文件所有块写完了

6.1.2 容错

  • 在写的过程中,pipeline中的datanode出现故障(如网络不通),输出流如何恢复
    • 输出流中ackQueue缓存的所有packet会被重新加入dataQueue
    • 输出流调用ClientProtocol.updateBlockForPipeline(),为block申请一个新的时间戳,namenode会记录新时间戳
    • 确保故障datanode即使恢复,但由于其上的block时间戳与namenode记录的新的时间戳不一致,故障datanode上的block进而被删除
    • 故障的datanode从pipeline中删除
    • 输出流调用ClientProtocol.getAdditionalDatanode()通知namenode分配新的datanode到数据流pipeline中,并使用新的时间戳建立pipeline
    • 新添加到pipeline中的datanode,目前还没有存储这个新的block,HDFS客户端通过DataTransferProtocol通知pipeline中的一个datanode复制这个block到新的datanode中
    • pipeline重建后,输出流调用ClientProtocol.updatePipeline(),更新namenode中的元数据
    • 故障恢复完毕,完成后续的写入流程
6.2 数据读流程

6.2.1 基本流程

  • 1、client端读取HDFS文件,client调用文件系统对象DistributedFileSystem的open方法
  • 2、返回FSDataInputStream对象(对DFSInputStream的包装)
  • 3、构造DFSInputStream对象时,调用namenode的getBlockLocations方法,获得file的开始若干block(如blk1, blk2, blk3, blk4)的存储datanode(以下简称dn)列表;针对每个block的dn列表,会根据网络拓扑做排序,离client近的排在前;
  • 4、调用DFSInputStream的read方法,先读取blk1的数据,与client最近的datanode建立连接,读取数据
  • 5、读取完后,关闭与dn建立的流
  • 6、读取下一个block,如blk2的数据(重复步骤4、5、6)
  • 7、这一批block读取完后,再读取下一批block的数据(重复3、4、5、6、7)
  • 8、完成文件数据读取后,调用FSDataInputStream的close方法

6.2.2 容错

  • 情况一:读取block过程中,client与datanode通信中断

    • client与存储此block的第二个datandoe建立连接,读取数据
    • 记录此有问题的datanode,不会再从它上读取数据
  • 情况二:client读取block,发现block数据有问题

    • client读取block数据时,同时会读取到block的校验和,若client针对读取过来的block数据,计算检验和,其值与读取过来的校验和不一样,说明block数据损坏
    • client从存储此block副本的其它datanode上读取block数据(也会计算校验和)
    • 同时,client会告知namenode此情况;

7. Hadoop HA高可用

7.1 HDFS高可用原理
  • 对于HDFS ,NN存储元数据在内存中,并负责管理文件系统的命名空间和客户端对HDFS的读写请求。但是,如果只存在一个NN,一旦发生“单点故障”,会使整个系统失效。
  • 虽然有个SNN,但是它并不是NN的热备份
  • 因为SNN无法提供“热备份”功能,在NN故障时,无法立即切换到SNN对外提供服务,即HDFS处于停服状态。
  • HDFS2.x采用了HA(High Availability高可用)架构。
    • 在HA集群中,可设置两个NN,一个处于“活跃(Active)”状态,另一个处于“待命(Standby)”状态。
    • 由zookeeper确保一主一备(讲zookeeper时具体展开)
    • 处于Active状态的NN负责响应所有客户端的请求,处于Standby状态的NN作为热备份节点,保证与active的NN的元数据同步
    • Active节点发生故障时,zookeeper集群会发现此情况,通知Standby节点立即切换到活跃状态对外提供服务
    • 确保集群一直处于可用状态
  • 如何热备份元数据:
    • Standby NN是Active NN的“热备份”,因此Active NN的状态信息必须实时同步到StandbyNN。
    • 可借助一个共享存储系统来实现状态同步,如NFS(NetworkFile System)、QJM(Quorum Journal Manager)或者Zookeeper。
    • Active NN将更新数据写入到共享存储系统,Standby NN一直监听该系统,一旦发现有新的数据写入,就立即从公共存储系统中读取这些数据并加载到Standby NN自己内存中,从而保证元数据与Active NN状态一致。
  • 块报告:
    • NN保存了数据块到实际存储位置的映射信息,为了实现故障时的快速切换,必须保证StandbyNN中也包含最新的块映射信息
    • 因此需要给所有DN配置Active和Standby两个NN的地址,把块的位置和心跳信息同时发送到两个NN上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值