说明:/
表示两个词是同一语义,方便你理解的
前置知识:Windows与Linux文件系统的差异
Windows & LInux 虽然都有硬盘/分区、目录,但感受很不同的是:
- Windows:有很强的分区概念,要先通过不同的“盘符”去找文件
- 在命令行模式下,切换盘符不方便
- 在Windows下,你每天都要跟盘符打交道
- Linux:感受不到分区,只感受得到目录,只需要知道在那个目录下即可
- Linux分区/磁盘空间 是挂载在目录树下的
- 即:目录树是一个逻辑结构,把底层的磁盘空间给封装好了;只要空间够,你都不会想到磁盘,就很方便
举个例子:
现在,开发一个便携软件,但开发时写死了一个文件的存放位置,比如:必须在 /E
存放
解压安装的便携软件,是可以从别人那里拷贝过来直接用的
现在,我想从朋友哪里将他的软件拷贝过来
在Windows中,语义就是E盘,此时如果没有E盘,那完蛋了,是创建不了E盘/分区的,这个软件也就安装不、用不了
在Linux中,E就是根目录下的E目录,此时也让这个目录可能没有,但没关系,我创建个目录是很简单的
没有分区的概念,对开发人员的好处:软件具备了 移动性 ,对硬件做了解耦
HDFS中的角色及功能
NameNode 记账人:负责存储和管理文件元数据,并维护了一个层次型的文件目录树
DataNode 存数据的:负责存储文件数据-block块,并提供block的读写
简单过程:
客户端排队存东西 → 问NameNode(说:去哪里存?) → 到DataNode给它存
此时HDFS就有了负载能力:排队的人没有扎堆挤在一起长时间进行存东西,而是分散开来
在NameNode短暂停留,大部分时间都分散在不同的DataNode
DataNode与NameNode维持心跳(通信),DataNode并汇报自己持有的block信息
NameNode要知道手底下有哪些工人;NN记账时信自己人,不信客户端
与客户端的交互
客户端和NameNode交互文件的元数据
客户端和DataNode交互文件的block数据
这些角色本质上就是运行服务器上的一个JVM进程
HDFS的架构
进入分布式集群有两个概念:主从,主备
主备的场景:高可用:1主1备,备是不对外“处理业务/提供服务”的,主挂了,无缝切换到备马上提供服务
主从的场景:如下
HDFS 是主从架构 Master/Slaves
主从两人都是活动/工作的,之间有通信/协作/互相调用的
由一个(主)NameNode 和 一些(从)DataNode组成
HDFS是面向文件的,包含:文件数据-data 和 文件元数据-name/metadata(在上一篇文章中“HDFS启蒙”中提过)
NameNode
不管你DataNode有多少台,我NameNode只有一台,所有客户端都要往我这走
所以NameNode要低延迟/非常快,快速对外提供服务
- 完全基于内存,存储文件元数据、目录结构、文件block的映射等
- 像人的大脑一样,读和写就很快了
- 内存寻址 是 IO寻址的 10万倍
产生问题:
- 不可靠:内存不是持久化的,断电易失
- 内存大小有限
只要是基于内存的东西(如:Redis、HBase),都需要 持久化方案 保证数据可靠性
HDFS还有一个很重要的:副本放置策略
DataNode
- 基于 本地磁盘 存储block(文件的形式)
- block块(逻辑概念)→ 小文件(物理),打散分配到不同的机子上,每台机都有一个 DataNode进程,存到本地磁盘中
所以:HDFS并没帮存数据,而就是一个“管理映射/记账”的东西
- block块(逻辑概念)→ 小文件(物理),打散分配到不同的机子上,每台机都有一个 DataNode进程,存到本地磁盘中
- 并保存block的”校验和“数据,保证block的可靠性
- 校验和:通过映射算法,将一批数据映射成一串很小的乱字符
- 检验和出现的场景:下载大资源,链接旁会有一个叫md5值,下载后校验用的,保证数据没坏
- 因为在存的时候,磁盘可能有坏道;网络下载发生数据错乱了,都会导致数据被破坏了
- 校验和:通过映射算法,将一批数据映射成一串很小的乱字符
存到服务器前算一个值,到服务器又算一个来比较,下载后再算又比较,只要有不一样的就是数据被破坏了
值都符合,块就没被破坏,按顺序拼起来自然也就没问题
- 与NameNode保持心跳,汇报block列表状态
NameNode元数据的持久化
数据持久化的两种方式:
- 日志文件:追加记录 实时发生的“增删改”的操作,所以可以从头执行恢复
优点:完整性(只要有操作,就记录)
缺点:有大量的相同操作,文件占用空间很大,加载恢复数据慢 - 镜像:间隔一段时间,将内存的全量数据,向磁盘溢写
即:将这个系统的全部状态写到磁盘中,隔一段时间一次,隔一段时间一次,……
这个时间间隔多久合适?一小时级的是最合适的。因为IO慢,间隔不能更低了。一天的间隔又太长了。
优点:二进制文件,恢复速度较快
缺点:间隔的,中间容易丢失部分数据
HDFS中:
EditLog事务日志记录:记录NN元数据产生修改的操作
FsImage文件系统镜像:存储内存所有的元数据状态
使用本地磁盘保存EditLog和FsImage
HDFS将他们两的结合:
滚动的将增量的EditLog更新到FsImage,以保证更近时点的FsImage和更小的EditLog体积
即:最近时点的FsImage + 增量的EditsLog
如:9点的FsImage + 9~10的EditLog,在10点时合并为一个新的10点的FsImage
就算你9:30到10:00这个NN出故障了,在10点时,我仍可以用FsImage和EditLog快速恢复,保证数据不丢
拿了两者的优点:FsImage保证快速恢复,EditLog保证FsImage的数据完整正确,EditLog的体积也不大
看看这个合并过程的问题:
体会一下这个过程:在10点时,9点的FsImage上内存,执行完EditLog后变成10点FsImage,是不是还得下内存去磁盘啊
是不是在“脱落裤子放屁”,多此一举。(话虽然不好,但意思就是这么个意思)
FsImage在NameNode的机子上,上内存又下内存,大量的IO在消耗性能,但我们又知道NameNode是需要独享尽可能多的资源性能的
所以,就要在另一台机子Secondary NameNode,专门 合并FsImage和EditLog
多了一个角色SNN
后面会说在HA模式下,这个角色被代替了,加了更多功能并改了个名