HDFS——分布式文件系统
分布式:如何解决问题的?
问题1:为什么不用MySQL存储和分析计算?
1、数据量大,MySQL存储不了
2、即使能存储,处理的性能也很差。
3、数据种类的多样化。mysql适用于存储结构化的数据,对于非结构化或半结构化的数据,mysql并不适用
问题2:如何解决数据大无法存储或者计算的问题?
分布式:分而治之。一分、二计算处理、三合并。就是将多台机器的资源【集群】在逻辑上合并成一个整体,通过分布式的软件,提供分布式的服务。
问题3:分布式解决了什么问题?
- 解决了大数据量的存储和计算的问题
- 单台机器资源不足问题
- 单台机器资源性能差问题
问题4:分布式的通用架构是什么样的?
主从架构:主从节点进程。
主节点主要功能有:
1、管理所有从节点的存亡
2、管理任务的分配
3、接收客户端的请求
从节点的功能主要是:
1、负责管理每一台机器自己的资源。有几台机器就有几个从节点
2、接收主节点分配的任务,调用自己的机器来执行任务。
问题5:分布式架构中存在问题?
1、单点故障问题:主节点只有一个,如果主节点进程或者所在机器故障,会导致整个分布式服务不可用的
2、分布式数据一致性问题:多台机器要共享同一份数据,如何保证读取的数据一致性问题
解决:zookeeper。
问题6:zookeeper如何解决分布式的两个问题?
1、数据一致性问题
- 利用ZK实现一致性存储,将数据存储在ZK中
- 所有节点都从ZK中读取数据。
2、主节点单点故障问题 - 解决:分布式框架可以构建多个主节点,保证同一时刻只有一个是工作状态
- 状态
- Active:工作状态
- Standby:备份状态
- 问题:如何决定谁是工作谁是备份?
- 解决:利用zookeeper的临时节点进行辅助选举
- 实现:让两个主节点A和B都到ZK中创建一个同名临时节点file,谁创建成功,谁就是Active,另外一个由于节点已存在,就会创建失败
- 假设A创建成功,A就是Active的
- B作为Standby,并为file节点设置监听,如果A故障,与ZK的会话会断开,file这个临时节点,就会被删除,B会受到这个监听的信息,发现A故障,就会切换为Active状态
问题7:zookeeper自己也是分布式的,它的问题需要自己解决?
- 问题:如果有一台ZK故障了,是否影响?
- 不影响
- zk是公平节点,zk每一台节点存储的内容是一致的,而且任何一台ZK都可以接受读写请求
- 问题:zk如何保证每台机器的内容是一致的?
- 限定只能由leader执行写操作,leader同步给其他节点。
- 问题:如果leader故障怎么办?
- 公平节点:每台机器都可以被选举为Leader
HDFS功能与架构
功能
HDFS(Hadoop Distributed File System):hadoop分布式文件系统。
- HDFS就是一个逻辑上的文件系统
- 本质:将多台机器的文件系统从逻辑上合并了,构建一个虚拟的文件系统
- 主:NameNode:管理节点
- 负责管理
- 接受客户端请求
- 从:DataNode:存储节点
- 负责将NameNode分配的存储任务对自己所在机器的文件系统进行操作。
应用场景
- 离线场景:基于大文件的IO流的读写
- 读写速度比较慢
- 适合于一次写入,多次读取场景
- 不适合于实时、频繁的修改或者删除的场景
特点
分块机制
HDFS解决分布式存储的机制。默认机制如果一个文件大于128MB,就会被拆分,每128MB一个块,不足128M,按实际大小存储。
300M => HDFS
block1:128M
block2:128M
block3:44M
最终HDFS的数据还是存储在Linux的文件系统中的,存储在哪?
- hdfs-site.xml属性
<property> <name>dfs.datanode.data.dir</name> <value>file:///export/server/hadoop-2.7.5/hadoopDatas/datanodeDatas</value> </property>
副本机制
通过冗余副本存储,来保证数据安全性。默认为3,所有的数据块,在存储时,实际存储了3份。
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
HDFS的工作机制
HDFS架构角色
客户端
负责实现与用户交互,提交请求给服务端,将服务端返回的结果再展示给用户
NameNode
1、管理集群:所有DataNode在启动时会向NameNode进行注册
(1)管理从节点的状态【存活状态】:心跳机制
- 每隔一段时间,DN会向NN发送一个心跳,表示自己是一个正常存活的DN节点
- 如果长时间NN没有接收到某一个DN的心跳,就会认为这个DN故障状态,不再分配任务
(2)管理数据的安全:汇报块机制 - 每隔一段时间,DN要向NN发送当前自己这台DN上所存储的所有块的信息
- NameNode会根据汇报的信息与自己管理元数据进行比对,发现是否有数据丢失
2、管理元数据:元数据在NameNode启动时,会被加载到内存中
- 元数据中记录了每一个块所对应的文件以及存储的位置
{block1:file1:root:timestamp:id:List< node1,node2,.noder3>} - 元数据的产生以及管理
- 产生:元数据在格式化的时候会产生一个元数据文件fsimage
- 管理:NameNode启动时,会读取这个文件的数据加载到内存
问题:为什么要将fsimage的内存读取到内存中?
为了加快NameNode对元数据读写的速度
NameNode会根据客户端的请求读写内存的元数据
问题:由于NameNode只更改内存的元数据,并没有修改文件元数据,如果一旦NameNode故障,内存中数据丢失,重启重新加载文件元数据,文件元数据没有发生变化,导致元数据丢失的?
解决:将内存中元数据的变化【操作】记录在edits文件中,每次NameNode会将edits与fsiamge文件进行合并加载到内存
问题:fsiamge文件一直没变,edits越来越大,会有很多无用的元数据,导致NameNode启动非常慢?
解决:SecondaryNameNode:辅助节点。负责定期或者定量的将edits与fsiamge文件进行合并,生成最新的元数据文件:fsiamge 。
3、负责接收管理客户端请求。
DataNode
负责接收任务,实现基于文件系统的数据块的读写。
HDFS写数据流程
- 客户端提交写请求给NameNode。
- NameNode检验请求合法性,检查目标路径是否存在等,如果合法,namenode会在editlog中创建新文件记录的一条记录。如果不合法,文件创建失败并向客户端抛出异常。HDFS创建文件之后,分布式文件系统向客户端返回一个输出流对象。该对象负责处理datanode和namenode之间的通信。
- 客户端会将文件进行切分,分块,输出流对象提交第一个块block1的写入请求给Namenode,向namenode申请一块空的数据块,NameNode会根据请求以及当前的数据块分配的规则,返回Block1要存储的DataNode地址列表。
- 客户端获取列表以后,会根据机架感知,从列表中选群离自己最近一台DataNode,构建pipeline通道,将一个块拆分一个个packet,每写满一个packet后会将packet放入dataQueue队列中。
- dataNode1会将数据从dataQueue取出,再从datanode1传到datanode2,再从datanode2传到datanode3中,每个DataNode写入完成,返回一个ack的确认,如果返回成功,则从ackQueue队列中删除packet,否则,将packet从新放回dataQueue。
- 当当前块已经写完,如果还有其他块要写,重复提交下一个块的请求给NameNode,直到整个文件写入完成,NameNode记录完整的元数据。
写过程容错机制
在写的过程中,pipeline中的datanode出现故障(如网络不通),输出流如何恢复?
1、输出流中ackQueue缓存的所有packet会被重新加入dataQueue
2、将故障的datanode从pipeline中删除
3、通知namenode分配新的datanode到数据流pipeline中,并建立新的pipeline
4、将新的datanode与其他datanode的数据同步
5、更新namenode中的元数据
6、完成后续写入操作。
HDFS读数据流程
读过程容错机制
情况一:读取block过程中,client与datanode通信中断
1、client与存储此block的第二个datandoe建立连接,读取数据
2、记录此有问题的datanode,不会再从它上读取数据
情况二:client读取block,发现block数据有问题
1、client读取block数据时,同时会读取到block的校验和,若client针对读取过来的block数据,计算检验和,其值与读取过来的校验和不一样,说明block数据损坏
2、client从存储此block副本的其它datanode上读取block数据(也会计算校验和)。
3、client会告知namenode此情况。
HDFS的数据安全
数据安全
为了保证datanode中保存的数据安全,hadoop有如下两种机制
1、副本机制
对于每个块构建副本,一般来说是3份,不同的副本存储在不同的机器上,保证数据安全
2、安全模式
在安全模式下,HDFS会尝试恢复故障数据块,同步保存的数据。
元数据安全
namenode格式化时,会产生元数据文件:fsimage,fsimage文件是用来保存元数据的文件,每当namenode启动都会将fsimage中的元数据加载到内存中。
问题1:每次修改元数据,只会修改内存中的元数据,而文件中元数据没有变化,如果namenode发送故障,会导致元数据丢失。
解决:将内存中元数据的变化写到edits文件,每次namenode启动先加载edits和fsimage。
问题2:edits不断变大会导致namenode启动变慢。
解决:SecondaryNameNode进程会定时或edits文件达到一定大小时,通过http协议到NameNode所在的节点上下载edists文件和fsiamge文件,合并生成最新的fsimage文件,namenode会将内存中元数据的变化写入新的edits文件中。namenode下次启动会加载新的fsimage和新的edits文件。
Hadoop的高可用
这里拿hdfs为例来讲解高可用架构,mapreduce的高可用与hdfs唯一的区别是,在MapReduce中resourcemanager的主从节点之间的监听与数据一致性,都是由zookeeper来完成的,而在hdfs中,zookeeper的作用是主备监听,hdfs的namenode的数据一致性是由journalnode来完成的,但是其原理与zookeeper的一致性原理类似。不使用zookeeper的原因主要是zookeeper上节点容量太小。
hdfs中namenode是如何实现高可用的呢?
问题1:怎么解决主节点的单点故障问题?
解决:启动多个主节点,Hadoop2中可以启动两个NameNode。
问题2:两个NameNode只能有一个是active状态,两个namenode是怎么工作的?使用Zookeeper实现辅助选举,每个namenode都会有一个zkfc进程,这个进程负责监控自己对应的namenode,监听当前namenode的状态,帮助namenode在zk中创建临时结点。 这两个namenode都要通过zfkc进程向zk注册,在zk上创建临时节点。谁创建成功,该namenode结点状态为active,另外一个standby。Standby对临时节点设置监听,如果Active故障,这个临时节点会被删除,Standby会重新创建这个临时节点,Standby会成为新的Active。 只有active节点可以接受用户请求,只有Active的NameNode的元数据在发生变化。
问题3:两个NameNode都维护自己的内存元数据,如何保证两个NameNode内存元数据的一致性?元数据安全性前面已经提及,实现将edits文件实现高可靠的分布式共享存储,activenamenode将元数据操作写入edits文件中,standbynamenode 从edits文件中读取,并与本地的fsimage文件合并。功能设计角度,可以选择zookeeper来实现。 但是zookeeper中只能存储小数据,edits是比较大的数据,不能使用zookeeper Hadoop自己设计了一种服务,类似于Zk的机制,但是以文件形式来管理的,没有大小限制,也是分布式的,每台节点存储的内容都是一样:Journalnode
问题4:为什么HA架构中没有SecondaryNameNode?
它的工作由Standby的NameNode来实现了,Standby的NameNode会将读取的edits与fsiamge合并,定期生成最新的元数据,并且会主动将新的fsiamge同步给Active的NameNode一份。
问题5:脑裂问题
① 正常情况下的切换:假设Active的NameNode故障:Namenode1。
- NameNode1故障,ZKFC1发现这个问题,ZKFC1 会主动断开与ZK连接
- 临时节点自动删除
- ZKFC2收到这个临时节点被删除的通知,于是ZKFC2会创建这个临时节点
- ZKFC2会通知NameNode2转换为Active状态
② 特殊情况下的问题:假设Active的NameNode对应的ZKFC1出现问题,网络通信问题或者进程资源问题。
- 临时节点自动删除
- ZKFC2收到这个临时节点被删除的通知,于是ZKFC2会创建这个临时节点
- ZKFC2会通知NameNode2转换
- 问题:现在两个NameNode都是Active状态
- 现象:脑裂
③ 解决:在ZKFC创建临时节点的时候,同时创建一个永久性节点:ActiveBreadCrumb
- ZKFC1会创建两个节点:临时节点和永久性节点
- 如果ZKFC1故障,临时节点自动删除,永久性性节点依旧存在
- ZKFC2发现临时节点消失,于是创建这个临时节点,并且通知NameNode2转换为Active
- ZKFC2会发现这个临时节点依旧存在,就知道NameNode1没有故障,ZKFC1故障了
- ZKFC2会通过隔离机制将NameNode1强制转换为Standby状态
联盟机制:Federation
- HA:主要解决单点故障问题,一个NameNode如果故障了,导致HDFS不可用的问题
- 两个NameNode,一个是Active工作状态,一个是Standby的备份状态
- Federation:单个NameNode工作性能的瓶颈的问题,这两个
- 两个NameNode,两个NameNode都是工作状态,负责的数据是不一样的,元数据不一样。