hdfs的一些重要知识点

HDFS的一些重要知识点

hdfs将文件存放在哪里?
datanode 用户的文件存放在datanode上,放在配置的目录dfs.datanode.data.dir下
namenode 管理元数据(文件路径、副本数、文件的blockid,位置等信息)

1.HDFS读写流程
##写流程
精简
1.客户端向Name Node请求上传文件
2.Name Node查询元数据信息,看路径是否存在后回应可以上传
3.客户端请求NameNode上传第一块block,指定副本数量,bloksize等参数
4.Name Node收到请求后,找到若干台datanode信息,返回第一块数据的存放节点
5.客户端跟第一个datanode发出请求建立数据传输通道,第一个dn会向第二个dn发送连接请求,直到pipeline建立成功
6.pipeline建立成功后,客户端就开始向第一个dn传输第一块block的数据,第一个向第二个传,第二个向第三个传
7.客户端向Name Node返回上传的状态,成功的话,namenode更新元数据,将文件写到磁盘
8.待第一块block上传成功后,继续请求namenode上传第二块
源码版

  1. 客户端通过对DistributeFileSystem 对象调用create()函数来创建文件。
  2. DistributedFileSystem 对namenode创建一个rpc调用,在文件系统的命名空间中创建一个新文件,但是此时该文件中还没有相应的数据块,namenode执行各个不同的检查以确保这个文件不存在,并且客户端有创建该文件的权限。如果这些检查均通过,namenode就会为创建新文件记录一条记录,否则,文件创建失败并向客户端抛出一个IoException异常。
  3. DistributeFileSystem向客户端返回一个FSDataOutrputStream对象,由此客户端可以开始写入数据。就像读取事件一样,FSDataOutputStream封装一个DFSoutPutstream对象,该对象负责处理datanode和namenode之间的通信。
  4. 在客户端写入数据时,DFSOutputStream将它分成一个个的数据包(packet),并写入内部队列,成为数据队列(data queue)。dataStreamer处理数据队列,它的责任是根据datanode列表来要求namenode分配适合的新块来存储数据备份。这一组datanode构成一个管道(pip管道)//我们假设副本数是3,所以管道中有3个节点。dataStream将数据包流式传输到管道中第一个datanode,该datanode存储数据包之后,并将它发送到管道中第二个datanode中,同样操作,第二个datanode 将数据包存储后给第三个datanode。//
  5. DFSOoutputStream也维护着一个内部数据包队列来等待datanode的收到确认回执,称为"确认队列"(ack queue)。当收到管道中所有的datanode确认信息后,该数据包才会从确认队列删除。
    //如果在数据写入期间,datanode发生故障,则执行以下操作,这对与写入数据的客户端是透明的。首先关闭管道,确认把队列中的任何数据包都添回数据队列的最前端,以确保故障节点下游的datanode不会漏掉任何一个数据包。为存储在另一个正常datanode的当前数据块制定一个新的标识,并将该标识传送给namenode。以便故障datanode在恢复后可以删除存储的部分数据块。从管道中删除故障数据节点并且把余下的数据块写入管道中剩余的两个正常的datanode。namenode注意到块副本量不足时,会在另一个节点上创建一个新的副本。后续的数据块继续正常接受处理。//
  6. 客户端完成数据的写入后,会对数据流调用close()方法。
  7. 该操作将剩余的所有数据包写入datanode管道中,并在联系namenode发送文件写入完成信号之前,等待确认。namenode已经知道文件由哪些块组成(通过DataStreamer询问数据块的分配),所以它在返回成功只需要等待数据块进行最小量的复制。

##读流程
精简
1.客户端向NameNode请求下载文件
2.Name Node返回下载文件的元数据(严格按照数据块的存储信息,顺序)
3.客户端拿到block信息后,从第一个block开始,找到最近的一台datanode
4.客户端跟这台datanode发出读取数据的请求,建立文件传输通道,开始接收数据到客户端本地
5. 客户端以packet为单位接收,先在本地缓存,然后写入目标文件
6.接收完一个block后,在重复以上过程找到另一个datanode接收下一个block
源码

  1. 客户端通过调用FileSystem对象的open()方法来打开希望读取的文件,对于HDFS来说,这个对象是DistributedFileSystem的一个实例
  2. DistributedFileSystem通过使用远程过程调用(RPC)来调用 namenode,以确定文件起始块的位置
  3. 对于每一个块,namenode返回存有该块副本的datanode地址。此外,这些datanode根据它们与容户端的距离来排序。如果该客户端本身就是一个datanode,那么该客户端将会从保存有相应数据块复本的本地datanode读取数据。DistributedFileSystem类返回一个 FSDataInputStream对象给客户端以便读取数据。FSDataInputStream类转而封装DFSInputStream对象,该对象管理着 datanode和 namenode的 I/O。接着,客户端对这个输入流调用 read()方法
  4. 存储着文件起始几个块的datanode地址的 DFSInputStream随即连接距离最近的文件中第一个块所在的datanode。通过对数据流反复调用 read()方法,可以将数据从 datanode传输到客户端
  5. 到达块的末端时, DFSInputStream:关闭与该 datanode的链接,然后寻找下一个块的最佳datanode
  6. 所有这些对于客户端都是透明的,在客户看来它一直在读取一个连续的流。客户端从流中读取数据时,块是按照打开 DFSInputStream与datanode新建连接的顺序读取的。它也会根据需要询问 namenode来检索下一批数据块的 datanode的位置. 一旦客户端完成读取.就对FSDataInputStream调用close()方法

namenode和secondary namenode的工作目录存储结构完全相同,所以,当namenode故障退出需要重新恢复时,可以从secondary namenode的工作目录中将fsimage拷贝到namenode的工作目录,以恢复namenode的元数据

可以通过hdfs的一个工具来查看edits中的信息:
–>bin/hdfs oev -i edits -o edits.xml

2.namenode工作机制

主架构,负责管理元数据(文件,名称,副本,存储位置)只有一个节点

(1)Namenode始终在内存中保存metedata,用于处理“读请求”

(2)到有“写请求”到来时,namenode会首先写editlog到磁盘,即向edits文件中写日志,成功返回后,才会修改内存,并且向客户端返回

(3)Hadoop会维护一个fsimage文件,也就是namenode中metedata的镜像,但是fsimage不会随时与namenode内存中的metedata保持一致,而是每隔一段时间通过合并edits文件来更新内容。Secondary namenode就是用来合并fsimage和edits文件来更新NameNode的metedata的。

2.2namenode怎样感知block位置信息:

fsimage元数据里面并没有block所在的位置信息,只有文件的blockid信息。
但是在集群运行时,整个集群中的所有datanode会定期向namenode汇报自身所持有的block信息。
namenode收到这些信息后,就会向内存中的元数据结构中维护block信息。
同时namenode也就知道了那些block缺少副本,那些block多余副本,就能采取相应的措施,补全缺少的,删除冗余的。

##2.3 元数据管理

NameNode对数据的管理采用了三种存储形式:
内存元数据(NameSystem)
磁盘元数据镜像文件
数据操作日志文件(可通过日志运算出元数据)

##2.3.1 元数据存储机制

1、内存中有一份完整的元数据(内存 meta data)

2、磁盘有一个“准完整”的元数据镜像(fsimage)文件(在NameNode的工作目录中)

3、用于衔接内存metadata和持久化元数据镜像fsimage之间的操作日志(edits文件)注意:当客户端对hdfs中的文件进行新增或修改操作,操作记录首先被记入edits日志文件中,当客户端操作成功后,相应的元数据会更新到内存metadata中

2.4.namenode职责

1、负责客户端请求的响应
2、元数据的管理(查询,修改)

##2.5.namenode启动流程

  • NameNode启动的时候首先将fsimage(镜像)载入内存,并执行(replay)编辑日志editlog的的各项操作

  • 一旦在内存中建立文件系统元数据映射,则创建一个新的fsimage文件(这个过程不需SecondaryNameNode) 和一个空的editlog

  • 在安全模式下,各个datanode会向namenode发送块列表的最新情况

  • 此刻namenode运行在安全模式。即NameNode的文件系统对于客户端来说是只读的。(显示目录,显示文件内容等。写、删除、重命名都会失败)

  • NameNode开始监听RPC和HTTP请求

    解释RPC:RPC(Remote Procedure Call Protocol)——远程过程通过协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议

  • 系统中数据块的位置并不是由namenode维护的,而是以块列表形式存储在datanode中

  • 在系统的正常操作期间,namenode会在内存中保留所有块信息的映射信息

(1) 加载镜像文件,还原了checkpoint时间节点前的元数据(包含目录结构,文件大小,块的大小,块的id等等信息),不包含块的存储位置
(2) 加载edits文件,还原了checkpoint时间节点到集群停止的元数据,不包含块的存储位置。(至此namenode还原的元数据唯一缺失的就是块的存储位置)
(3) blockreport阶段,datanode启动,向namendoe汇报自己所管理的块及块的id,namenode根据块的ID还原块的存储位置
(4) 在blockreport结束后,集群会判断,datanode的启动数量(可设置,默认为0),丢失的块的占比(可设置,默认0.999f)是否满足退出安装模式的条件,如果满足,30秒后退出安全模式。在安全模式下namenode会删除多余的块
(副本数为3,结果实际存储4个。ps:这种情况发生在datanode宕机,集群把宕机的datanode管理的块进行了复制,
而宕机的datanode又重新启动了)还会复制低于副本数的块

##3.secondary namenode的工作机制,日志合并步骤

辅助节点,用于合并两类文件

SecondaryNameNode它的职责是合并NameNode的edit logs到fsimage文件中

首先,SecondaryNameNode定时到NameNode去获取edit logs,并更新到fsimage上。一旦它有了新的fsimage文件,SecondaryNameNode将其拷贝回NameNode中。NameNode在下次重启时会使用这个新的fsimage文件,从而减少重启的时间。

Secondary NameNode的整个目的是在HDFS中提供一个检查点。它只是NameNode的一个助手节点。这也是它在社区内被认为是检查点节点的原因。

(1)secondary通知namenode切换edits文件

(2)secondary从namenode获得fsimage和edits(通过http)

(3)secondary将fsimage载入内存,然后开始合并edits

(4)secondary将新的fsimage发回给namenode

(5)namenode用新的fsimage替换旧的fsimage

##4.datanode工作机制

从架构,存储真实数据的节点,存在多个

存储管理用户的文件块数据定期向namenode汇报自身所持有的block信息(通过心跳信息上报汇报的目的是,namenode如果长时间接收不到一个datanode的心跳后,说明该datanode宕机了,该datanode的数据块就被namenode拿不到了,需要从其他机上拿该datanode的数据块副本。)

(1)提供真实文件数据的存储服务。 (2)文件块(block):最基本的存储单位。对于文件内容而言,一个文件的长度大小是size,那么从文件的0偏移开始,按照固定的大小,顺序对文件进行划分并编号,划分好的每一个块称一个Block。HDFS默认Block大小是128MB,以一个256MB文件,共有256/128=2个Block. dfs.block.size (3)不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间 (4)Replication。多复本。默认是三个。hdfs-site.xml的dfs.replication属性

##4.1Datanode工作职责:

1、存储管理用户的文件块数据
2、定期向namenode汇报自身所持有的block信息(通过心跳信息上报)

4.2Datanode掉线判断时限参数

datanode进程死亡或者网络故障造成datanode无法与namenode通信,namenode不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。HDFS默认的超时时长为10分钟+30秒。如果定义超时时间为timeout,则超时时长的计算公式为:

​ timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval。

​ 而默认的heartbeat.recheck.interval 大小为5分钟,dfs.heartbeat.interval默认为3秒。

需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的单位为毫秒,dfs.heartbeat.interval的单位为秒。所以,举个例子,如果heartbeat.recheck.interval设置为5000(毫秒),dfs.heartbeat.interval设置为3(秒,默认),则总的超时时间为40秒。

##4.3 元数据checkpoint

每隔一段时间,会secondary NameNode 将NameNode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge,这个过程称作 checkpoint

checkpoint

hdfs元数据是怎么存储的?

1、内存中有一份完整的元数据
2、磁盘有一个“准完整”的元数据镜像
3、当客户端对hdfs中的文件进行新增或者修改操作,响应的记录首先被记入edits这种log日志中,当客户端操作成功后,相应的元数据会更新到内存中
4、每隔一段时间,会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge(这个过程称为checkpoint)

checkpoint操作的触发条件配置参数:(hdfs-site.xml)

​ dfs.namenode.checkpoint.check.period=60 #检查触发条件是否满足的频率,60秒
dfs.namenode.checkpoint.dir=file://${hadoop.tmp.dir}/dfs/namesecondary #secondary namenode的本地工作目录
dfs.namenode.checkpoint.max-retries=3 #最大重试次数
dfs.namenode.checkpoint.period=3600 #两次checkpoint之间的时间间隔3600秒
dfs.namenode.checkpoint.txns=1000000 #两次checkpoint之间最大的操作记录

5 HA

HA的运作机制
(1)hadoop-ha集群运作机制介绍
所谓HA,即高可用(7*24小时不中断服务)
实现高可用最关键的是消除单点故障
hadoop-ha严格来说应该分成各个组件的HA机制

同时出现两个active状态namenode的术语叫:

脑裂 brain split

防止脑裂有两种方式

1 、ssh发送kill指令

2、 调用用户自定义脚本程序

(2)HDFS的HA机制
通过双namenode消除单点故障
双namenode协调工作的要点:
A、元数据管理方式需要改变:
内存中各自保存一份元数据
Edits日志只能有一份,只有Active状态的namenode节点可以做写操作
两个namenode都可以读取edits
共享的edits放在一个共享存储中管理(qjournal和NFS两个主流实现)
B、需要一个状态管理功能模块
实现了一个zkfailover,常驻在每一个namenode所在的节点
每一个zkfailover负责监控自己所在的namenode节点,利用zk进行状态标识
当需要进行状态切换时,由zkfailover来负责切换
切换时需要防止brain split现象的发生

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值