HDFS一致性和高可用原理
HDFS的特点
-
分布式文件系统。
-
保存多个副本,提供容错机制,副本丢失或宕机的自动恢复能力。
-
适合大数据处理,文件分块存储,默认是128M;文件与Black的对应关系存储在NameNode所在节点的内存中,方便文件的寻址和访问。如果小文件过多则会增加HDFS的NameNode节点的负担。
-
流式数据访问,一次写入,多次读取。仅支持Append,不支持修改文件内容;
-
水平扩展,增加DataNode节点,无需停止服务,自动完成;
HDFS的关键元素与概念
-
Black:文件块,默认为128M;
-
NameNode:Master节点,管理数据块映射,处理客户端的读写请求,配置副本策略。管理HDFS的名称空间。保存整个文件系统的目录信息(文件信息,分块信息)。
-
SecondarNameNode:是NameNode的小弟,负责分担NameNode的工作。是NameNode的冷备份;合并fsimage和fsedits然后再发给NameNode。(热备份:b是a的热备份,如果a坏掉了,那么b马上运行,替代a的工作。如果b是a的冷备份,那么当a坏掉时,b无法替代a的工作;但是b上面会存储a的信息,减少a坏掉时候的损失。)
-
DataNode:Slave节点,负责存储Client发来的Black,执行数据的读写操作;
-
fsimage:元数据镜像文件(文件系统的目录树)
-
fsedits:元数据的操作日志(针对文件系统所做的修改操作)
HDFS的架构原理
-
-
一个HDFS集群,包含一个单独的NameNode和多个DataNode组成;
-
NameNode作为Master服务,它负责管理文件系统的命名空间和处理客户端对文件的访问请求。NameNode保存了文件的元数据信息(文件名,Black数量,Black所在位置等)。NameNode同时会接受DataNode的心跳信息。
-
DataNode作为Salve服务,在集群中存在多个;通常每个DataNode对应于一个物理节点。DataNode负责管理其节点上存储的Black块信息。同时需要周期性的给NameNode发送其上所有的Black信息。
-
HDFS的设计重点
-
HDFS被设计成一个可以在大集群中,跨机器做分布式的文件存储。它将所有文件存储成Black块组成的序列。除了最后一个Black以外,其余的Balck大小都一样。
-
HDFS中文件默认是一次写入,多次读取。HDFS严格要求,在任何之后都只有一个Write。
-
NameNode全权管理数据库的复制。它周期性的从DataNode接收心跳和每个Black上所存储的所有Black信息(也就是块状态报告)。
-
NameNode的内存中存储的是fsimage + fsedits;SecondaryNameNode负责定时的从NameNode中拉取fsImage + fsedits(默认是1小时),合并完成之后再发送给NameNode。以此来减轻NameNode的负担。
HDFS容错机制与故障恢复
-
多副本机制,使副本分布在不同的服务器上。
-
数据校验功能,后台连续自检数据一致性。
-
心跳信息和数据块报告
-
三类故障
-
节点故障(DataNode)
-
网络故障(无法接受和发送数据)
-
数据损坏(传输出错,或者存储不完整)
-
-
故障检测机制
-
节点失败监测机制
-
注意如果NameNode故障,整个集群都会挂掉。NameNode是集群中唯一单点;
-
DataNode节点会定时向NameNode节点发送心跳(默认是3秒),如果NameNode节点超过10秒没有收到DataNode的心跳信息,此时NameNode认为该DataNode节点处于宕机状态;
-
-
通信故障检测机制
-
只要发送数据,接收方会收到一个确认码,如果结果几次重试之后,发送方仍未收到确认码,此时发送方会认为主机故障,或者网络异常;
-
-
数据错误检测机制
-
在传输数据时,同时会发送“总和校验码”。当数据存储到磁盘是,同时也会存储“总和检验码”。
-
所有DataNode都会定期向NameNode发送Black的状态,在发送Black状态信息之前,DataNode会首先检验“总和检验码”是否正确。如果检验失败,DataNode就不再发送该Block信息了。NameNode收到DataNode的Black状态信息后会发现,少了一个Black的信息。这时NameNode就知道这个Black被损坏了。
-
-
-
HDFS的读写容错
-
写容错
-
HDFS采用流式的数据写入方式,每个数据包的大小被分割成64KB进行发送。当第一个数据包副本复制完成,改DataNode会将这个数据包发送给存储其他副本的另一个Data节点。每个DataNode节点接收数据完成,都会向NameNode发送确认。
-
-
读容错
-
Client向NameNode发送读数据请求,NameNOde会返回该文件所有的Black存储信息。
-
Client拿到Black存储信息后,首先要询问DataNode是否可以进行数据读取。
-
-
HDFS副本恢复
-
-
NameNode上会存储两个表,一个是数据块列表(存储每一个Black的存储位置),另一个是DataNode列表(存储每个DataNode的Black信息)。
-
NameNode通过DataNode发送给它的数据块信息报告中可以得知哪些Black损坏或者哪些DataNode故障。
-
当发现某个Black损坏时:NameNode会指定一个新的DateNode从现在的副本中重新复制一份。同时NameNode也会刷新“数据块存储列表”;
-
当发现某个DataNode损坏时:NameNode会同时刷新“DataNode列表”和“数据块列表”。
-
NameNode会定期检查“数据块列表”,找到哪些数据块活跃副本数是低于预期的(默认3个)。然后指定新的DataNode去复制这些副本。
-
HDFS副本复制和DataNode的选择策略
-
机架感知
-
第一个副本优先存放在,写入方所在的机器。如果写入方所在机器不具备写入条件,则从该机器所在机架中选取一台合适的机器。
-
第二和第三个副本,存储在不同机架的不同机器上。
-
-
HDFS的高可用配置
-
NameNode单点故障
-
当NameNode所在的机器发生异常(宕机),在NameNode恢复正常之前,整个HDFS集群都不可用。
-
当NameNode所在的机器执行某些日常维护任务(入软件升级)后重启服务器时,同样会导致HDFS集群在一段时间内不可用。
-
-
HDFS高可用简介
-
在Hadoop2.X版本后,HDFS引入了双NameNode的架构。通过将两个NameNode分别配置为Active/Passive来解决;
-
两个NameNode分别被叫做:Active NameNode 和 Standby NameNode,Standby NameNode是Active NameNode的热备份。能够在Active NameNode发生故障时或者软件升级等情况下,立刻替代Active NameNode的工作。保证整个HDFS集群的正常工作;
-
两个NameNode如何确保数据一致?
-
Active NameNode 接收所有的读写请求,Standby NameNode作为Active NameNode的备份,负责尽可能的做到与Active NameNode的数据一致。
- 为了使数据保持一致,两个NameNode都需要与一组Journal Node节点保持通信。当Active NameNode节点执行的读写操作对NameSpace(目录树)有所修改时,会确保将修改日志持久化到大部分的Journal Node节点。Standby NameNode发现NameSpace有改动时,会从Journal Node 节点同步更改内容,进而保持与Active NameNode节点的数据一致。
-
无论何时都只应该有一个NameNode处于Active状态。如果同一时刻两个NameNode都认为自己处于Active状态(裂脑现象),那么就会导致同时进行数据读写,不再进行数据一致性同步,最终可能导致数据损坏或者数据丢失。为了避免“裂脑现象”的发生,管理员必须为共享存储配置至少一个fencing方法。在宕机期间,如果确定了上一个ActiveName已经不再活跃,那么fencing进程会马上切断对上一个Active NameNode的内存共享,避免其对命名空间再做任何修改。
-
为了保证故障转移的快速进行,StandBy NameNode需要存储所有Black信息,因此在DataNode节点,同样需要配置两个NameNode,在向NameNode发送数据块报告时,同时发送给两台NameNode;
-
当Standby NameNode需要接替Active NameNode时,Standby NameNode会首先保证自己从Journal Node节点中同步了所有修改日志;
-
-
借助Zookeeper实现自动故障转移
-
需要hdfs-site.xml和core-site.xml中增加配置,开启“自动故障转移”,并配置故障转移所用到的Zookeeper服务列表。
-
接着需要在Zookeeper中创建一个用来存储自动故障转移的Znode。配置了自动故障转移后,会在NameNode所在的机器上,运行一个ZKFC守护进程。在ZKFC启动的过程中会自动选择一个NameNode作为Active NameNode。