hdfs读写流程

本文详细探讨了HDFS在处理小文件时面临的问题,解释了块大小、副本数如何影响存储,并提出了避免小文件的策略。此外,还介绍了HDFS的主从架构,NameNode和DataNode的角色,以及数据的写入和读取流程。文章最后讨论了副本放置策略,强调了生产环境中考虑的因素。
摘要由CSDN通过智能技术生成

1.块
dfs.blocksize  默认128m


一桶水 1000 ml, 瓶子规格 100ml ==》 10瓶子
一桶水 1010 ml, 瓶子规格 100ml ==》 10+1=11瓶子  
                          200ml ==》 5+1 =6瓶子

一个小电影 260m
1 128m  1  1
2 128m  2  2
3 4m
-------=3块

伪分布式 1 DN节点, 副本数(dfs.replication) 1 :  3个块,实际存储空间是260m*1=260m
集群     3 DN节点,副本数(dfs.replication) 3 :  3*3=9个块,实际存储空间是260m*3=780m
                                                        128m*3*3 错误的 


假设 1亿个小文件,每个小文件10kb,集群3 DN节点,副本数 3 , 1亿*3=3亿块
Namenode维护: 元数据,文件名称、路径、权限、被切割哪些块,这些块分布在哪些机器上; 3亿条数据
假设 1亿个小文件,每个小文件10kb,合并为100百个100m 大文件,集群3 DN节点,副本数 3 , 100百万*3=3百万块 ==》3百万条数据

Namenode维护 3亿 还是3百万元数据的压力,谁轻松?
8G

但是: 业务关系型数据源,同步很难解决小文件。
      日志型数据源(flume)、计算结果(spark coalesce),我们可以控制小文件;

所以生产上: 尽量规避小文件在HDFS的存储
a.数据在传输到hdfs之前,提前合并
b.数据已经到了hdfs,就定时在业务低谷时期,去合并(冷)文件,
比如 12月1号,合并10月1号; 12月2号,合并10月2号。 一天卡一天;

hive 有一套合并小文件的方法  手动
hbase 小合并 大合并 自带的


2.hdfs架构
主从架构

机架 ?  https://www.bilibili.com/video/BV1eE411p7un?spm_id_from=333.999.0.0  必须要看
采购 IDC 机架  刀片服务器  规格 256G GPU 56core 10块 1T磁盘  配置  价格 10W  数量  ==》 数据仓库     

3.namenode  nn 名称节点  老大
a.文件的名称
b.文件的目录结构、权限、大小、所属用户用户组  时间
c.文件被切割哪些块----》块(块本身+2副本=3个块)分布在哪些DN节点上  blockmap 块映射
不会持久化存储这种映射关系,是通过集群启动和运行时候,DN定期给NN汇报blockreport,
然后NN在内存中动态维护这种映射关系;


[ruoze@ruozedata001 ~]$ hdfs dfs -ls /output1
Found 2 items
-rw-r--r--   1 ruoze supergroup          0 2021-11-26 22:43 /output1/_SUCCESS
-rw-r--r--   1(副本数?) ruoze supergroup         60 2021-11-26 22:43 /output1/part-r-00000
[ruoze@ruozedata001 ~]$ 

NN:
-rw-rw-r-- 1 ruoze ruoze      42 Nov 28 08:07 edits_0000000000000000256-0000000000000000257
-rw-rw-r-- 1 ruoze ruoze      42 Nov 28 09:07 edits_0000000000000000258-0000000000000000259
-rw-rw-r-- 1 ruoze ruoze 1048576 Nov 28 09:07 edits_inprogress_0000000000000000260
-rw-rw-r-- 1 ruoze ruoze    2874 Nov 28 08:07 fsimage_0000000000000000257
-rw-rw-r-- 1 ruoze ruoze      62 Nov 28 08:07 fsimage_0000000000000000257.md5
-rw-rw-r-- 1 ruoze ruoze    2874 Nov 28 09:07 fsimage_0000000000000000259
-rw-rw-r-- 1 ruoze ruoze      62 Nov 28 09:07 fsimage_0000000000000000259.md5
-rw-rw-r-- 1 ruoze ruoze       4 Nov 28 09:07 seen_txid
-rw-rw-r-- 1 ruoze ruoze     219 Nov 26 22:01 VERSION
[ruoze@ruozedata001 current]$ pwd
/home/ruoze/tmp/hadoop-ruoze/dfs/name/current
[ruoze@ruozedata001 current]$ 

edits 编辑日志文件
fsimage 镜像文件

SNN:
-rw-rw-r-- 1 ruoze ruoze      42 Nov 28 08:07 edits_0000000000000000256-0000000000000000257
-rw-rw-r-- 1 ruoze ruoze      42 Nov 28 09:07 edits_0000000000000000258-0000000000000000259
-rw-rw-r-- 1 ruoze ruoze    2874 Nov 28 08:07 fsimage_0000000000000000257
-rw-rw-r-- 1 ruoze ruoze      62 Nov 28 08:07 fsimage_0000000000000000257.md5
-rw-rw-r-- 1 ruoze ruoze    2874 Nov 28 09:07 fsimage_0000000000000000259
-rw-rw-r-- 1 ruoze ruoze      62 Nov 28 09:07 fsimage_0000000000000000259.md5


将老大的 
fsimage_0000000000000000257
edits_0000000000000000258-0000000000000000259
拿到SNN,进行【合并】,生成fsimage_0000000000000000259文件,然后将此文件【推送】给老大;
同时,老大在新的编辑日志文件edits_inprogress_0000000000000000260

动作: 检查点  checkpoint

dfs.namenode.checkpoint.period 3600
dfs.namenode.checkpoint.txns   1000000

在大数据早期的时候,只有NN一个人,假如挂了 ,真的挂了。
中期的时候,SNN,定期来合并、 备份 、推送,但是这样的也就是1小时备份1次。
比如11点合并备份,但是11点半挂了,从SNN恢复到NN,只能恢复11点的时刻的元数据,丢了11-11点半的元数据。

后期就取消SNN,新建一个实时NN,作为高可靠 HA。
NN Active
NN Standby 实时的等待active NN挂了,瞬间启动Standby--》active,对外提供读写服务。


4.datanode dn 数据节点
a.存储数据块 和 块的校验和
b.定期给NN发送块报告
dfs.blockreport.intervalMsec  21600000=6h
dfs.datanode.directoryscan.interval  21600s=6h


https://ruozedata.github.io/2019/06/06/%E7%94%9F%E4%BA%A7HDFS%20Block%E6%8D%9F%E5%9D%8F%E6%81%A2%E5%A4%8D%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5(%E5%90%AB%E6%80%9D%E8%80%83%E9%A2%98)/

5.hdfs 写流程 面试
对用户是无感知
5.1 hdfs client调用FileSystem.create(filePath)方法,去和NN进行【RPC】通信。
NN会去检查这个文件是否已经存在、是否有权限创建这个文件等一系列校验操作;
如果校验通过,就创建一个新的文件,但是这个没有数据,不关联任何的block的。
NN会根据文件的大小,再根据当前集群的块大小 128、副本数3,和当前的DN节点情况,
计算出这个文件要上传多少个块(包含副本)和块上传到哪些DN节点。
最终把这个信息返回给客户端【FsDataOutputStream】对象。

5.2 Client 调用【FsDataOutputStream】对象的write方法,
根据【副本放置策略】,将第一个块的本身写到DN1,写完复制到DN2,再写完复制到DN3.
当三个副本写完的时候,就返回一个ack package确认包给DN2,DN2接收到确认包加上自己也写完了,
给DN1发送ack package确认包加上DN1自己写完了,就给【FsDataOutputStream】,告诉它第一个块 三个副本都写完了。

以此类推。

5.3 当所有的块全部写完,Client调用【FsDataOutputStream】对象的close方法,关闭输出流。
再次调用FileSystem.complete方法,告诉NN文件写成功。


6.hdfs 读流程
6.1 Client调用FileSystem的open(filePath),与NN进行【RPC】通信。
返回这个文件的部分或者全部的block列表,
也就是返回【FSDataInputStram】对象。
6.2 Client调用【FSDataInputStram】对象的read方法,
去与第一个块的最近的DN的进行读取,读取完成后会校验,假如ok就关闭与DN通信。
假如不ok,就记录块和DN的信息,下次就不从这个节点读取,那么从第二个节点读取。

然后与第二个块的最近的DN进行读取,以此类推。

假如当block的列表全部读取完成,文件还没结束,再去NN请求下一个批次的block列表。


block1-1 dn1
block1-2 dn2
block1-3 dn3

block2-1 dn3
block2-2 dn1
block2-3 dn2

6.3 Client调用【FSDataInputStram】对象的close方法,关闭输入流。

【***** 提醒:hbase ,主从架构,读写操作不经过老大】


7.副本放置策略

生产上读写操作,尽量选择DN节点操作。
第一个副本就放置在自己本身节点,就近原则,节省网络IO。

第二个副本:
放置在第一个副本的不同机架的某个节点;

第三个副本:
放置与第二个副本相同机架的不同机器上。


但是:
生产上真的是这样的吗?  这样会带来 权限问题,比如一不小心把Linux文件删除了怎么办

所以生产上真正的是,有个单点的客户端节点,不是NN也不是DN进程在。
其实网络IO,还好。一般生产上集群内部都是万兆带宽  光纤的。忽略不计。
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值