Hadoop之HDFS

Hadoop简介

http://hadoop.apache.org
分布式存储系统HDFS (Hadoop Distributed File System )POSIX
• 分布式存储系统
• 提供了 高可靠性、高扩展性和高吞吐率的数据存储服务
-分布式计算框架MapReduce
• 分布式计算框架(计算向数据移动)
• 具有 易于编程、高容错性和高扩展性等优点
-分布式资源管理框架YARN(Yet Another Resource Management)
• 负责集群资源的管理和调度

HDFS(分布式文件存储系统)

存储模式:字节
文件线性切割成块(Block):偏移量 offset (byte)
按照字节切割成块,默认大小是128M
Block分散存储在集群节点中
单一文件Block大小一致,文件与 文件可以不一致
Block可以设置副本数,副本分散在不同节点中
副本数不要超过节点数量
文件上传可以设置Block大小和副本数
已上传的文件Block副本数可以调整,大小不变
只支持一次写入多次读取,同一时刻只有一个写入者
可以append追加数据

架构模型:
文件元数据MetaData,文件数据
元数据
在对NameNode节点进行格式化时,调用了FSImage的saveFSImage()方法和FSEditLog.createEditLogFile()存储当前的元数据。Namenode主要维护两个文件,一个是fsimage,一个是editlog。
fsimage :保存了最新的元数据检查点,包含了整个HDFS文件系统的所有目录和文件的信息。对于文件来说包括了数据块描述信息、修改时间、访问时间等;对于目录来说包括修改时间、访问权限控制信息(目录所属用户,所在组)等。简单的说,Fsimage就是在某一时刻,整个hdfs 的快照,就是这个时刻hdfs上所有的文件块和目录,分别的状态,位于哪些个datanode,各自的权限,各自的副本个数等。
注意:Block的位置信息不会保存到fsimage,Block保存在哪个DataNode(由DataNode启动时上报)。
editlog :主要是在NameNode已经启动情况下对HDFS进行的各种更新操作进行记录,HDFS客户端执行所有的写操作都会被记录到editlog中

数据本身
(主)NameNode节点保存文件元数据:单节点(主备)posix
(从)DataNode节点保存文件Block数据:多节点
DataNode与NameNode保持心跳,提交Block列表
问题:为什么namenode不存储block块列表信息?
是因为有可能datenode是挂掉了
HdfsClient与NameNode交互元数据信息
HdfsClient与DataNode交互文件Block数据

NameNode

– 基于内存存储 :不会和磁盘发生交换
• 只存在内存中
• 持久化
– NameNode主要功能:
• 接受客户端的读写服务
• 收集DataNode汇报的Block列表信息
– NameNode保存metadata信息包括
• 文件owership和permissions
• 文件大小,时间
• (Block列表:Block偏移量),位置信息
• Block每副本位置(由DataNode上报)

DataNode

– 本地磁盘目录存储数据(Block),文件形式
– 同时存储Block的元数据信息文件
– 启动DN时会向NN汇报block信息
– 通过向NN发送心跳保持与其联系(3秒一次),如果NN 10分钟没有收到DN的心跳,则认为其已经lost,并copy其上的block到其它DN

HDFS优点:

– 高容错性
• 数据自动保存多个副本
• 副本丢失后,自动恢复
– 适合批处理
• 移动计算而非数据
• 数据位置暴露给计算框架(Block偏移量)
– 适合大数据处理
• GB 、TB 、甚至PB 级数据
• 百万规模以上的文件数量
• 10K+ 节点
– 可构建在廉价机器上
• 通过多副本提高可靠性
• 提供了容错和恢复 机制

HDFS缺点:

– 低延迟数据访问
• 比如毫秒级
• 低延迟与高吞吐率
– 小文件存取
• 占用NameNode 大量内存
• 寻道时间超过读取时间
– 并发写入、文件随机修改
• 一个文件只能有一个写者
• 仅支持append

NameNode持久化(重点)

– NameNode的metadate信息在启动后会加载到内存
– metadata存储到磁盘文件名为”fsimage”
– Block的位置信息不会保存到fsimage
– edits记录对metadata的操作日志。。。redis

NameNode在内存中保存着整个文件系统的名字空间和文件数据块映射(Blockmap)的映像。
如果NameNode宕机,那么整个集群就瘫痪了

因而则出现了元数据的存储问题,接下来请看如下几个问题

如果元数据仅以文件的形式存储在namenode本地硬盘行不行呢?
因为大批量的客户端同时在进行上传、下载等各种操作时,都要对元数据进行读写及修改操作
仅仅以文件的形式来存储元数据显然不行,因为无法做到对各种操作的快速响应
把元数据放在内存中呢,确实能够提高系统响应速度,但是一旦断电就完全丢失了,这肯定也不行

那么如果把内存的数据定期flush到磁盘文件的方法行不行呢?
一旦断电,没来得及的刷到磁盘的内存数据肯定也是要丢失的,显然也不行

那么在实际环境中,hadoop是怎么管理元数据的呢?
首先,磁盘确实有块空间,对元数据进行持久化存储的,名为fsimage
如果直接读取磁盘文件,速度肯定跟不上,内存中也要放一些元数据信息
虽然很容易丢失,但可以提供查询服务,实际上就是读写分离,由读写分离就有了数据一致性的问题

因为写入数据,没有写入内存中,最新的元数据记录在哪呢?
实际上是记录在edits.log中,这个文件不提供修改,只提供追加,以日志的形式记录
比如在上传一个文件时,先对namenode进行询问,往哪里写,namenode一边分配一边记录
将空间分配信息记录edits.log,当完成一个副本的写入工作后,通知namenode,被认为是写入成功
这时,将edits.log的数据更新至内存,此时,内存中的数据是最新的
即使现在断电,最新的元数据在edits.log也有保存。

当客户端执行写操作时,NameNode会先在编辑日志中写下记录,并在内存中保持一个文件系统元数据
元数据会在编辑日志有所改动后进行更新。内存中的元数据用来提供读数据请求服务

过程分析:
1.客户端写入文件时,NameNode首先在edits.log文件中记录元数据操作
2.操作完成后将成功信息发送给NameNode。NameNode在内存中写入这次操作新产生的元数据信息
更新的顺序edits.log-----内存-----fsimage

fsimage合并操作:

为防止影响响应速度,由SecondaryNamenode来合并
当edits*.log写满或时间达到1h时,通知SecondaryNamenode进行checkpoint操作

【checkpoint】操作:
1.辅助Namenode请求主Namenode停止使用edits文件,暂时将新的写操作记录到一个新文件中,如edits.new。
2.辅助Namenode节点从主Namenode节点获取fsimage和edits文件(采用HTTP GET)
3.辅助Namenode将fsimage文件载入到内存,逐一执行edits文件中的操作,创建新的fsimage文件
4.辅助Namenode将新的fsimage文件发送回主Namenode(使用HTTP POST)
5.主Namenode节点将从辅助Namenode节点接收的fsimage文件替换旧的fsimage文件
用步骤1产生的edits.new文件替换旧的edits文件(即改名)。同时更新fstime文件来记录检查点执行的时间

校验点的目的:
通过把hdfs文件系统元数据的快照保存到FsImage中从而保持了hdfs文件系统的一致性。

校验点触发方式:
1.根据时间循环(dfs.namenode.checkpoint.period)单位是秒触发
2.根据文件系统的事务增加量(dfs.namenode.checkpoint.txns)触发
如果两个都进行了设置,那么哪个先达到了,就会触发校验点

namenode安全模式

– namenode启动的时候,首先将映像文件(fsimage)载入内存,并执行编辑日志(edits)中的各项操作。
– 一旦在内存中成功建立文件系统元数据的映射,则创建一个新的fsimage文件和一个空的编辑日志。
– 此刻namenode运行在安全模式。即namenode的文件系统对于客户端来说是只读的。(显示目录,显示文件内容等。写、删除、重命名都会失败)。
– 在此阶段Namenode收集各个datanode的报告,当数据块达到最小副本数以上时,会被认为是“安全”的, 在一定比例(可设置)的数据块被确定为“安全”后,再过若干时间,安全模式结束
– 当检测到副本数不足的数据块时,该块会被复制直到达到最小副本数,系统中数据块的位置并不是由namenode维护的,而是以块列表形式存储在datanode中。

HDFS 2.0 HA

参考链接:https://www.cnblogs.com/hellochennan/p/5373177.html
– 主备NameNode
– 解决单点故障(属性,位置)
• 主NameNode对外提供服务,备NameNode同步主NameNode元数据,以待切换
• 所有DataNode同时向两个NameNode汇报数据块信息(位置)
• JNN:集群(属性)
• standby:备,完成了edits.log文件的合并产生新的image,推送回ANN
– 两种切换选择
• 手动切换:通过命令实现主备之间的切换,可以用HDFS升级等场合
• 自动切换:基于Zookeeper实现
– 基于Zookeeper自动切换方案
• ZooKeeper Failover Controller:监控NameNode健康状态,
• 并向Zookeeper注册NameNode
• NameNode挂掉后,ZKFC为NameNode竞争锁,获得ZKFC 锁的NameNode变为active

Active NameNode 和 Standby NameNode:两台 NameNode 形成互备,一台处于 Active 状态,为主 NameNode,另外一台处于 Standby 状态,为备 NameNode,只有主 NameNode 才能对外提供读写服务。

主备切换控制器 ZKFailoverController:ZKFailoverController 作为独立的进程运行,对 NameNode 的主备切换进行总体控制。ZKFailoverController 能及时检测到 NameNode 的健康状况,在主 NameNode 故障时借助 Zookeeper 实现自动的主备选举和切换,

Zookeeper 集群:为主备切换控制器提供主备选举支持。

共享存储系统:共享存储系统是实现 NameNode 的高可用最为关键的部分,共享存储系统保存了 NameNode 在运行过程中所产生的 HDFS 的元数据。主 NameNode 和NameNode 通过共享存储系统实现元数据同步。在进行主备切换的时候,新的主 NameNode 在确认元数据完全同步之后才能继续对外提供服务。

DataNode 节点:除了通过共享存储系统共享 HDFS 的元数据信息之外,主 NameNode 和备 NameNode 还需要共享 HDFS 的数据块和 DataNode 之间的映射关系。DataNode 会同时向主 NameNode 和备 NameNode 上报数据块的位置信息。

下面开始分别介绍 NameNode 的主备切换实现和共享存储系统的实现,在文章的最后会结合笔者的实践介绍一下在 NameNode 的高可用运维中的一些注意事项。
NameNode 的主备切换实现
NameNode 主备切换主要由 ZKFailoverController、HealthMonitor 和 ActiveStandbyElector 这 3 个组件来协同实现:
ZKFailoverController 作为 NameNode 机器上一个独立的进程启动 (在 hdfs 启动脚本之中的进程名为 zkfc),启动的时候会创建 HealthMonitor 和 ActiveStandbyElector 这两个主要的内部组件,ZKFailoverController 在创建 HealthMonitor 和 ActiveStandbyElector 的同时,也会向 HealthMonitor 和 ActiveStandbyElector 注册相应的回调方法。
HealthMonitor 主要负责检测 NameNode 的健康状态,如果检测到 NameNode 的状态发生变化,会回调 ZKFailoverController 的相应方法进行自动的主备选举。
ActiveStandbyElector 主要负责完成自动的主备选举,内部封装了 Zookeeper 的处理逻辑,一旦 Zookeeper 主备选举完成,会回调 ZKFailoverController 的相应方法来进行 NameNode 的主备状态切换。

NameNode 实现主备切换有以下几步:

  1. HealthMonitor 初始化完成之后会启动内部的线程来定时调用对应 NameNode 的 HAServiceProtocol RPC 接口的方法,对 NameNode 的健康状态进行检测。
  2. HealthMonitor 如果检测到 NameNode 的健康状态发生变化,会回调 ZKFailoverController 注册的相应方法进行处理。
  3. 如果 ZKFailoverController 判断需要进行主备切换,会首先使用 ActiveStandbyElector 来进行自动的主备选举。
  4. ActiveStandbyElector 与 Zookeeper 进行交互完成自动的主备选举。
  5. ActiveStandbyElector 在主备选举完成后,会回调 ZKFailoverController 的相应方法来通知当前的 NameNode 成为主 NameNode 或备 NameNode。
  6. ZKFailoverController 调用对应 NameNode 的 HAServiceProtocol RPC 接口的方法将 NameNode 转换为 Active 状态或 Standby 状态。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值