目录
1. 文件块
HDFS上的文件是分块存储的,默认每一块是128M,若一个文件是150M,那么它会被分成两个块存储,一个128M,一个22M。
1.1. 为什么会有这样的规则呢?
试想,当一个文件的大小为1T,计算机查找到它的时间是1s,但是读取它的世界可能就远远大于1s,这让文件的读取效率变得特别的低。为此,我们有一个规则:
找到文件的时间 = 读取文件的时间*1%
换言之,找到文件需要1s,读取文件需要100s,这个时间比例是比较合适的
而目前磁盘的传输速率普遍是100M/s,经过计算,128M的块大小是比较合适的。
总结:HDFS块的大小是取决于磁盘的传输速率。
2. HDFS读写数据流程
在HDFS中,namenode是管理datanode的,所以客户端任何操作都要向namenode发送请求
2.1. HDFS写数据流程
0 1 all原则:客户端先把文件发送到DataNode1,后面就没有客户端的事情了,是DataNode1自己把数据再发送到DataNode2
在HDFS写数据的过程中,NameNode会选择距离待上传数据最近距离的DataNode接收数据。那么这个最近距离怎么计算呢?
答:机架感知
节点距离:两个节点到达最近的共同祖先的距离总和。
副本节点的选择
为什么要这样选择呢?
答:因为要保证在不同机架上也有一份数据,而且这样的传输顺序,可以减少另一个机架上节点的等待时间。
2.2. HDFS读数据流程
3. SecondaryNameNode工作机制
我们提到了SecondaryNameNode是辅助NameNode工作的,那么它是如何辅助的呢?
- NameNode的作用是用来存储数据的元数据,为了保证效率,这些元数据是存储在内存中的,但是这样会引发一个问题,当机器断电的时候,内存中的数据就丢失了,所以我们必须将内存中的数据存储一份到磁盘上,那个文件就是fsimage,但是又会有问题,机器在修改内存的时候还要修改磁盘上的数据,这样效率很低,所以又产生了一个edits(日志文件),只用来记录每一步的操作,写入的速度非常快,当日志文件很大的时候,再将日志文件的东西合并到fsimage中,这一步交给SecondaryNameNode执行。
- 首先我们了解两个东西:
- 日志文件(edits):记录每一步的操作
- 镜像文件(fsimage):存储元数据
所以我们得到一个结论:元数据 = 日志文件(edits) + 镜像文件(fsimage)
当HDFS启动时,namenode会加载edits和fsimage到内存中。
这里一定要记住,元数据是存在于内存中的,只不过在磁盘上备份了一份
4. DataNode工作机制
5. Hadoop高可用
Hadoop的HA应该分为HDFS 的 HA 和 YARN 的 HA,主要是解决NameNode和ResourceManager的单点故障问题,所以HA就是通过配置 Active/Standby 两个 实例来解决单点故障
5.1. HDFS-HA 工作机制
5.1.1. HDFS-HA 工作要点
(1)元数据管理方式改变
两个NameNode内存中各自保存一份元数据,Edits 日志只有 Active 状态的 NameNode 节点可以做写操作, 两个 NameNode 都可以读取 Edits,共享的 Edits 放在一个共享存储中JounalNode
(2) 增加一个状态管理功能模块
Zkfailover(hadoop的模块),常驻在每一个 namenode 所在的节点,每一个 zkfailover 负责监控自己所在 NameNode 节点,和ZooKeeper通信利用 zk 进行状态标识,当需要进行状态切换时,由 zkfailover 来负责切换,切换时需要防止 brain split 现象的发生。
(3) 必须保证两个 NameNode 之间能够 ssh 无密码登录(为了防止脑裂,远程登录进行kill)
(4)隔离(Fence),即同一时刻仅仅有一个 NameNode 对外提供服务
5.2. HDFS-HA 自动故障转移工作机制
-
故障检测:集群中的每个NameNode在ZooKeeper 中维护了一个持久会话,如果机器崩溃,ZooKeeper 中的会话将终止,ZooKeeper 通知另一个 NameNode 需要触发故障转移。
-
现役 NameNode 选择:ZooKeeper 提供了一个简单的机制用于唯一的选择一个节点为 active 状态。如果目前现役 NameNode 崩溃,另一个节点可能从 ZooKeeper 获得特殊的排外锁以表明它应该成为现役 NameNode。
-
ZKFC工作原理:
(1)健康监测:ZKFC 使用一个健康检查命令定期地 ping 与之在相同主机的 NameNode,只要该 NameNode 及时地回复健康状态,ZKFC 认为该节点是健康的。如果该节点崩溃,冻结或进入不健康状态,健康监测器标识该节点为非健康的。
(2)ZooKeeper 会话管理:当本地 NameNode 是健康的,ZKFC 保持一个在 ZooKeeper中打开的会话。如果本地 NameNode 处于 active 状态,ZKFC 也保持一个特殊的 znode 锁,该锁使用了 ZooKeeper 对短暂节点的支持,如果会话终止,锁节点将自动删除。
(3)基于 ZooKeeper 的选择:如果本地 NameNode 是健康的,且 ZKFC 发现没有其它的节点当前持有 znode 锁,它将为自己获取该锁。如果成功,则它已经赢得了选择,并负责运行故障转移进程以使它的本地 NameNode 为 Active。