HDFS高阶原理

1 NameNode的block块管理方案

NameNode是通过什么手段管理block的呢?

文件存储到hdfs中需要将其拆分为多个block块存储到不同的DataNode中,每个块的大小小于等于128M
文件信息及block的相关信息存储在NameNode的元数据中
NameNode中的元数据: 文件大小, 文件名称, 文件创建修改时间,block块的副本数量,block块的副本位置…
读取、写入文件,先访问NameNode,根据元数据信息,告诉客户端去哪读取、写入文件

元数据是存放在内存中还是磁盘中呢?

元数据存储在内存中,可以满足告诉读写并发等需求,多用户同时访问效率高速度快,但是服务器宕机或重启后,数据全部丢失,元数据不能仅存储在内存中;
元数据存储在磁盘中,可以满足持久化存储的需求,并且安全性大大提高,服务器宕机或重启后数据依然不在,不会丢失,但是数据查询或写入效率极低,多用户同时访问效率低;
综上,在开发中元数据会存储两份,一份存储在内存中用户客户端访问、DataNode管理等;另一份存储在磁盘中,用户宕机或重启后的数据丢失

内存中读写效率极高,磁盘中读写效率低,如何备份才能够让内存和磁盘中的数据相同呢?

edits : 仅记录我们对于元数据的增删改的操作内容:
仅记录操作记录,速度极快 举例: sql语句如果不运行,仅记录sql
存储数据为二进制信息,存储的体积更小,运行效率更高
fsimage: 镜像文件,文件内存存储了全部的文件目录结构和block的副本数量等信息(存储的是元数据信息):
不仅记录文件结构,运行edits文件后还可以对于内部数据进行增删改操作
举例: edits 就相当于sql脚本文件, fsimage 相当于数据库, 运行edits 可以对数据库中的内容进行增删改操作

fsimage 运行完所有的edits文件,得到的数据内容就是内存中的完整元数据内容
内存中的元数据管理工作消耗了大量的内存
合并元数据也要消耗大量的内存, 对于主机的内存要求极高,为了缓解主机的内存压力,引入了SNN辅助NN进行元数据合并工作
NN在node1 上 SNN 在node2上, 内存压力就分散了

SecondaryNameNode 怎么知道该进行数据合并了呢?

SecondaryNameNode合并数据:
1.将fsimage 和 edits NameNode所在的服务器复制到SecondaryNameNode所在的服务器中
2. 将fsimage读取到内存中构建元数据架构
3. 运行edits中的操作记录,更新fsimage
4. 新的fsimage 写入磁盘中形成新的文件
5. 将fsimage 回传到 NameNode所在的服务器 替换旧的fsimage
什么时候进行元数据合并(两个条件达成其一即可)
合并时机我们称之为 checkpoint
1、时间间隔达到1小时
2、操作记录达到100万条
每隔60s检查一次是否符合上述

网络拓扑结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P4wwaFa3-1683805525865)(images/image-20230509170633645.png)]

  • 在同一个节点上的进程 : 两个服务在同一个服务器上
  • 在同一个机架上 : 两台服务器同属于同一个三级交换机
  • 在同一个数据中心不同机架上 : 同属于一个二级交换机,但是不属于同一个三级交换机
  • 不同数据中心的节点: 同属于一个一级交换机但是不属于同一个二级交换机

如果一级交换机也不一样,则不是一个网络服务中的服务器,无法进行交互

2 HDFS的数据写入与读取!

HDFS的数据写入(重要)

HDFS写入流程

  1. 写入DataNode之前必须访问NameNode,NameNode允许写入后方可写入数据
  2. 数据文件以packet包的形式进行拆分,每64kb一个包,进行数据传输
  3. 向DataNode写入数据时,不是同时写入三个服务器,而是先将第一个副本写入后,由该副本所在的DataNode备份到其他服务中
  4. 每个packet写入完成后会进行ack回调,收到回调后会写入下一个packet,如果一个block写满后会开启下一个block块继续写入,直到数据写入完成
  5. 所有数据写入完成后,需要向NameNode汇报写入完成,NameNode查询确认后保存元数据信息,方可使用该文件.
  6. NameNode查询确认时,只要有一个副本完整保存,则元数据信息即可开放使用

为何不使用一次性写入三个DataNode的方法呢? 为何要写入一个然后备份呢?

举例:
传输文件时 文件大小为100M 每秒传输1M
如果同时向三个DataNode中写入数据, 备份三个副本一共需要多少秒??? 100s
如果我们想DataNode1写入数据, DataNode1向DataNode2写入数据, DataNode2向DataNode3写入数据,备份三个副本一共需要多少秒??? 大于100s 小于300s

上述举例只是理想情况下,真实情况下,网络带宽存在上限, 磁盘读写速度也存在上限

例如: 上传一个文件 上传速度是3M/s 但是上传三个文件则每个文件上传速度是1M/s
一个客户端同时向三个服务写入,则不能保证速度达到1M/s且可能仅为上仙的三分之一,所以最终同时写入耗费的时间可以无限接近于300s
而仅向node1中写入,由node1向node2备份,node2向node3备份的模式 可以最大程度利用每一台服务器的带宽和磁盘加载速度,总体时间应该略高于100s 速度非常快

HDFS的数据读取(重要)

HDFS读取流程

  1. NameNode返回的blcok位置列表中,不仅包含块位置还包含其副本的位置
  2. 如果出现DataNode不可用的情况会在读取结束后向NameNode进行汇报,如果无不可用的情况不需要向NameNode进行任何汇报
  3. 读取文件时先读取到内存缓冲区,当将多个block读取完成后进行拼接合并后写入文件中.

3 HDFS的元数据管理(重要)

服务器启动时元数据恢复流程
服务器启动时元数据恢复流程
元数据合并流程
数据合并流程

HDFS的元数据存储在内存中还是磁盘中?

内存中一份,负责和客户端的交互以及快速进行元数据的增删改查工作
磁盘中一份,主要负责元数据的持久化存储(存储在磁盘中,关机或重启服务后数据不丢失)

  • edits 存储的是操作记录
  • fsimage 存储的是元数据信息
  • 在hdfs 中读取fsimage 到内存中,执行所有的edits就是最新的元数据状态

启动服务时:

从磁盘中的fsimage中读取全部的元数据加载到内存中,再找到最新的edits文件,将内部的日志文件执行

  • edits中的日志信息是解析完成的二进制指令(占用空间更小,执行效率更快)
    从DataNode中获取所有节点的块信息数据,获取完成后在内存中构建完整的元数据服务

触发元数据合并时:(合并间隔1小时或100万条记录)

  1. 将日志文件备份,将原日志文件修改为新的名称,后续的日志信息将记录在新文件中,备份文件将用于数据合并
  2. 将fsimage和备份的edits文件复制到SecondaryNameNode中
  3. 在SNN中将fsimage读取到内存中,将edits运行一遍,获得一个新的镜像文件命名为fsimage.checkpoint
  4. 将fsimage.checkpoint复制到NameNode中,将其改名为fsimage覆盖原来的镜像文件.
    edits中仅记录事务型指令: 增删改的指令,可以修改数据的指令.

fsimage中保存的不是完整的元数据内容, fsimage 中与内存中的元数据相比

  • DataNode的健康状态信息
  • block块的位置信息没有存储

注意: 当NameNode宕机后数据丢失,SecondaryNameNode可以帮助NameNode恢复数据,但是数据还是会有一部分丢失,只不过最大程度减少了损失.
思考:如果NameNode宕机了,SecondaryNameNode上有完整的元数据信息,那么SecondaryNameNode可以作为主服务使用么???

不可以,因为他们的功能和职责完全不同,SecondaryNameNode永远无法编程NameNode

4 HDFS的归档机制

为何HDFS不适合存储小文件???

无论HDFS存储大文件还是小文件,占用元数据空间差不多
同样存储一定体检的文件,存储小文件消耗的内存会比存储大文件多很多倍,所以不建议在HDFS上存储过多的小文件
而且存储的文件较小,在读取文件和使用文件时我们也当做一个块来看,使用mr任务计算时,小文件也会单独使用一个容器,执行一个map任务,对于资源浪费比较严重

如何处理HDFS中出现的小文件

在刻意减少小文件存储的基础上,还要定期进行文件归档,可以极大程度上避免小文件的产生

归档语法:hadoop archive -archiveName 归档名称.har -p 原始文件的目录 归档文件的存储目录
eg:数据准备

# 在linux 中创建三个文件
[root@node1 ~]# echo 1 > 1.txt
[root@node1 ~]# echo 22 > 2.txt
[root@node1 ~]# echo 333 > 3.txt
# 在hdfs中创建一个small_file目录
[root@node1 ~]# hadoop fs -mkdir /small
# 将三个小文件上传到hdfs中
[root@node1 ~]# hadoop fs -put 1.txt 2.txt 3.txt /small
# 检查文件是否上传成功
[root@node1 ~]# hadoop fs -cat /small/*
1
22
333

eg:归档测试

# 创建档案
[root@node1 ~]# hadoop archive -archiveName test.har -p /small /outputdir
# 我们自己归档的文件一定要使用.har结尾,这样其他人看到就知道是归档文件了,方便后期维护

在这里插入图片描述

# 基于自己的需求 删除小文件 减少对内存的消耗
[root@node1 ~]# hadoop fs -rm /small/*

# 查看档案文件 --归档之后的样子 文件_SUCCESS为成功标志
[root@node1 ~]# hadoop fs -ls hdfs://node1:8020/outputdir/test.har
Found 4 items
hdfs://node1:8020/outputdir/test.har/_SUCCESS
hdfs://node1:8020/outputdir/test.har/_index
hdfs://node1:8020/outputdir/test.har/_masterindex
hdfs://node1:8020/outputdir/test.har/part-0

# 查看小文件的元数据信息
[root@node1 /]# hadoop fs -cat /outputdir/test.har/_index
%2F dir 1683783049564+493+root+supergroup 0 0 1.txt 2.txt 3.txt 
%2F1.txt file part-0 0 2 1683783048842+420+root+supergroup 
%2F2.txt file part-0 2 3 1683783049090+420+root+supergroup 
%2F3.txt file part-0 5 4 1683783049558+420+root+supergroup 

# 查看小文件的数据信息
[root@node1 /]# hadoop fs -cat /outputdir/test.har/part-0
1
22
333

# 查看档案文件 --归档之前的样子  使用har协议查看即可
[root@node1 ~]# hadoop fs -ls har://hdfs-node1:8020/outputdir/test.har
Found 3 items
 har://hdfs-node1:8020/outputdir/test.har/1.txt
 har://hdfs-node1:8020/outputdir/test.har/2.txt
 har://hdfs-node1:8020/outputdir/test.har/3.txt

# 从档案文件中提取文件
[root@node1 ~]# hadoop fs -cp har://hdfs-node1:8020/outputdir/test.har/* /small/
[root@node1 ~]# hadoop fs -ls /small
Found 3 items
-rw-r--r--   3 root supergroup          2 2021-05-24 17:58 /small/1.txt
-rw-r--r--   3 root supergroup          2 2021-05-24 17:58 /small/2.txt
-rw-r--r--   3 root supergroup          2 2021-05-24 17:58 /small/3.txt

归档文件在使用时,除了必须使用har协议外和普通文件没有任何区别
文件归档会走mr程序,此时效率较低

一般情况下,企业中每个星期或者每个月都要进行一次归档,但是归档一般都是脚本完成,很少手动操作

归档的本质是什么?

就是将元数据信息存储到归档文件中(磁盘中),牺牲磁盘空间换内存空间
归档文件,由于元数据存储在磁盘中,所以读取小文件时需要先读取其元数据信息
归档文件使用时效率略低于普通文件

hdfs的路径 : hdfs://node1:8020/
linux文件系统路径: file:///
har归档文件路径 : har://hdfs-node1/

5 垃圾桶机制

垃圾桶就类似于windows中的回收站,被删除的文件会暂时存放在垃圾桶内,如果一段时间不恢复则会自动删除
默认情况下,是没有开启垃圾桶机制的

在虚拟机中命令删除默认是永久删除
[root@node1 hadoop]# hdfs dfs -rm /binzi/hello.txt
Deleted /binzi/hello.txt

在虚拟机中需要手动设置才能使用垃圾桶回收: 把删除的内容放到: /user/root/.Trash/Current/
先关闭服务: 在 node1 中执行 stop-all.sh
再修改文件 core-site.xml : 进入/export/server/hadoop-3.3.0/etc/hadoop目录下进行修改

<property>
	<name>fs.trash.interval</name>
	<value>1440</value>
</property>

其中,1440 表示 1440分钟,也就是 24小时,一天的时间。
企业中一般会设定时间为7天或15天,除非公司的存储空间非常紧俏.

# 设置了垃圾桶机制好处: 文件不会立刻消失,可以去垃圾桶里把文件恢复,继续使用
[root@node1 ~]# hadoop fs -rm /small/1.txt
2022-05-05 19:35:45,899 INFO fs.TrashPolicyDefault: Moved: 'hdfs://node1.itcast.cn:8020/small/1.txt' to trash at: hdfs://node1.itcast.cn:8020/user/root/.Trash/Current/small/1.txt
# 查看回收站中的文件
[root@node1 ~]# hadoop fs -ls hdfs://node1.itcast.cn:8020/user/root/.Trash/Current/small/ 
Found 1 items
-rw-r--r--   3 root supergroup          2 2022-05-05 19:42 hdfs://node1.itcast.cn:8020/user/root/.Trash/Current/small/1.txt
# 恢复删除的文件
[root@node1 ~]# hadoop fs -mv hdfs://node1.itcast.cn:8020/user/root/.Trash/Current/small/1.txt /small/

删除数据时,没有将数据直接销毁,而是放入了一个临时存储位置

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值