该文章的图都是根据自己理解画的 如有不对的地方 请大家指正 谢谢
HDFS 是一个分布式的集群 能够满足大量文件的上传与访问,但是namenode 为了实现快速的相应客户端的请求 存储在namenode上的源数据 存在什么地方呢?
目前能想到的是存在内存中。
但是存在内存中如果namenode关机了 或者 宕机了 那源数据不就没有了么?也没办法恢复了,那集群就不能用了 datenode上的数据也没办法访问了。
那就在磁盘同步一份数据。
那怎么保证磁盘跟内存中的数据一致性呢?
HDFS 多个副本 是怎么 存储的 是客户端在上传的时候上传多个么?
当时启动Hdfs的时候 会有一个secondaryNameNode启动 但是我们在安装过程中 没有配置这个SecondaryNameNode 那么它是做什么的呢?
当客户端上传文件完成以后 NameNode是如何知道哪个datenode存储的块文件 成功了呢?
...... 等等一些问题 我们带着问题来看一下 工作原理图 或许你就会明白了。
前提:客户端(C)先向NameNode 请求往某个地址写文件。然后NN(NameNode 下面都已NN表示) 检查C是否有权限,目录是否存在,集群是否可用等。
如果检测通过,NN会给C反馈成功信息,然后进入图中的第一步
1. C给NN发送写入的请求
2. NN 经过一系列处理以后返回给C分配的DN信息 (分配DN的因素 ①数据的可靠性②数据的写入效率 ③DN的负载均衡策略)
3. 然后C 就通过NN 给的 DN节点队列 进行分块写入 。写入过程中 C和DN 会进行信息确认。
4. NN会通过心跳 判断DN 是否存活 并进行通信,当某一个Block 小于配置的副本数量的时候 ,会有DN 根据副本生成策略进行Block的拷贝工作。当C成功上传好第一个Block的时候,C 会向NN进行汇报,告知Block上传完成。与副本拷贝同时进行。
5. 副本拷贝完成后DN会通过Map映射表通知NN 副本Block的存储位置
6. 然后C会重复 3、4、5步骤,继续对下一个block上传 ,直到整个文件上传完毕。
在上传文件的时候 各个block的副本 存放的DN有 一定的策略,会把C上传的第一个block 存放于 离C最近的 机架上 ,然后把 第二个副本存放在 于 第一个副本不同的机架上,第三个副本存放在第一个副本的机架上的其他DN中。
实现快速相应和数据的安全性可靠性
NN 的源文件都存放在内存中,但是在硬盘中有一份备份 fsimage 同时以日志的形式也记录在磁盘的edits文件中(edits 文件大小为64M)
1. C 发送上传文件请求
2. NN 首先往edits 日志中记录信息
3. 返回记录的block对应的块 给C
4. C开始往DN中写数据
5 C成功写入block后向NN 报告
6. NN收到C成功写入报告后 向内存中添加一条记录
这时候就保证了数据的安全性 在内存中的数据 在磁盘也存在一份
每次集群启动的时候 都会把fsimage的文件加载到内存中
因为NN主要负责存储源数据的信息。把edits 日志 同步到fsimage中需要 消耗一部分性能 来处理日志信息并转换为源数据存储形式。HDFS设计了SecondaryNameNode(后面以SN表示)SN的主要功能就是用来合并edits日志和fsimage源数据信息。
1. 合并edits 和 fsimage 有两个条件
1)当edits达到64M。 (fs.checkpoint.period 指定两次checkpoint的最大时间间隔 默认3600秒)
2)当与上次同步时间相差了3600秒(一个小时)。(fs.checkpoint.size 规定edits文件的最大值 默认为64M)
可以修改hdfs-site.xml 进行配置
这时候NN通知SN进行checkpoint操作 合并edits和fsimage
2. SN收到合并请求后会通知NN停止往edits文件中写数据,不然会导致数据不一致的问题 SN拿到的edits不是最新的数据
3. 然后NN会创建一个新的edits文件 命名为edits.new ,并把后来的日志数据写入edits.new 文件中
4. 然后SN把老的edits文件和 fsimage文件下载到SN 节点主机
5. 下载以后会对两个文件进行checkpoint操作,合并成一个文件fsimage.checkpoint
6. 然后把合并好的fsimage.checkpoint文件上传到NN节点主机上,并重命名为fsimage,并把edits.new 文件重命名为 edits。
SN中也存放的有最近一次合并的记录
到此位置 HDFS 在1.X版本 基本上就能保证数据安全性问题 但是 不能保证集群的高可用性
一旦NN宕机了,那集群就无法工作 虽然源数据保存在硬盘中 可以恢复,但是也需要时间。
可以看到 历史的edits 文件 同时你可以注意到edits 文件每隔一小时创建一个新的
edits_inprogress_... 为正在写入的edits 文件
fsimage文件也可以看到 同时hdfs 也同时存储多个历史fsimage文件
如果当前使用的文件损坏,还可以找到历史版本数据
所有文件存放的都是二进制的数据。
我使用的是2.X的版本 目录可能跟1.X版本不一样