举例1:一桶水 1000ml,瓶子的规格 100ml =>需要10个瓶子装完
一桶水 1010ml,瓶子的规格 100ml =>需要11个瓶子装完
一桶水 1010ml,瓶子的规格 200ml =>需要6个瓶子装完
块的大小<==>规格,只要是需要存储,哪怕一点点,也是要占用一个块的
块大小的参数:dfs.blocksize 官方默认的大小为128M
官网:https://hadoop.apache.org/docs/r3.2.2/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
搜索blocksize关键字
举例2:假设一个小电影的大小是256M
1 128M
2 128M
3 4M
需要三个块来存储
在伪分布式模式:有一个DN节点,副本数为1,3个块,它的实际存储空间是260M
在集群模式:有3个DN节点,副本数为3,3*3=9个块,它的实际存储就是260*3=780M,而不是128*3*3=1152M,这是错误的,每个副本的第三块是没有装满的,它不会自动生成数据。
举例3:假设有一亿个小文件,每个小文件的大小是10kb,集群模式下,3个DN节点,副本数为3,一共有1亿*3=3亿个块===>3亿条数据
假设还有一亿个小文件,每个小文件的大小是10kb,合并成100万个100M的文件(块的大小128M),集群模式下,3个DN节点,副本数为3,一共有100万*3=300万个块===>300万条数据
NN维护:元数据,元数据指的就是,文件名称、路径、权限、被切割哪些块、这些块分布在哪些机器,假设每个元数据大小是15kb。
namenode维护==>3亿*15kb数据 VS 300万*15kb 哪个轻松?肯定是300万的轻松
但是:基本上,很少有数据文件超过128M的,都是小文件比较多
业务关系型数据源,同步很难解决小文件。
日志型数据源(flume)、计算结果(spark--语法--coalesce),可以控制小文件;
所以生产上:尽规避小文件在HDFS存储,又或者
a.数据在传输到hdfs之前,提前合并
b.数据已经到了hdfs,就定时在业务低谷时期,去合并(冷)文件----比如 12月1号,合并10月1号; 12月2号,合并10月2号。 做到一天卡一天;
在之后的学习中有:hive--有一套合并小文件的方法,并且是手动的 ;hbase--自带小合并和大合并,是自动的
所以说,小文件过多会对危害我们的元数据!!!!!
2. hdfs架构2.1 hdfs是一个主从架构,并且大数据的组件大部分都是主从架构的---老大带着一群小弟干活
官网:Apache Hadoop 3.2.2 – HDFS Architecture
2.2 下面就是hdfs的架构图:
老大管理着文件系统的命名空间(打开、关闭、或者重命名文件或目录),并允许将用户数据存储在文件中,小弟存放着数据块
这里面涉及到机架的知识点,可以简单理解为柜子,想要深刻理解,可以观看下面的视频【若泽大数据】大数据平台建设三部曲,真正从0开始(全网讲该主题第一人,因为在职)_哔哩哔哩_bilibili
采购 IDC 机架 刀片服务器 规格 256G GPU 56core 10块 1T磁盘 配置 价格 10W 数量 ==》 数据仓库
如图,Rack就表示一个机架
当客户端在写时,先去向老大 *** 作一下,然后再去向小弟写
当客户端在读时,先去向老大读一下,老大才能知道这个文件被切分了哪些块,这些块分布在哪些数据节点上,拿到这些信息后,对应的去机器去读数据块,读出来之后,然后再在客户端上显示
对于用户而言,无论是通过Linux还是API Java代码,在写和读时,用户都是无感知的。它去写时,会把文件切割成好多块,按照规则放在不同的机器上面;在读时,对用户而言,读出来的数据是个完整性的,但是它其实是不完整的,内在是通过块与块的形式来组织起来的数据结构。
3. namenode---NNnamenode---名称节点----老大
3.1 nn的作用:
a.文件的名称
b.文件的目录结构、权限、大小、所属用户用户组 时间
c.文件被切割哪些块----》块(块本身+2副本=3个块)分布在哪些DN节点上 blockmap 块映射
nn不会持久化存储这种映射关系,是通过集群启动和运行时候,DN定期给NN汇报blockreport,
然后NN在内存中动态维护这种映射关系;
[hadoop@hadoop001 hadoop]$ hdfs dfs -ls /output1
Found 2 items
-rw-r--r-- 1 hadoop supergroup 0 2021-12-01 23:31 /output1/_SUCCESS
-rw-r--r-- 1(->表示副本数) hadoop supergroup 60 2021-12-01 23:31 /output1/part-r-00000
3.2 数据的checkpoint
查看数据表现形式
NN:
[hadoop@hadoop001 current]$ pwd
/home/hadoop/tmp/dfs/name/current [hadoop@hadoop001 current]$ ll
-rw-rw-r--. 1 hadoop hadoop 1048576 Dec 1 23:31 edits_0000000000000000062-0000000000000000152
-rw-rw-r--. 1 hadoop hadoop 42 Dec 2 15:47 edits_0000000000000000153-0000000000000000154
-rw-rw-r--. 1 hadoop hadoop 1048576 Dec 2 15:47 edits_inprogress_0000000000000000155
-rw-rw-r--. 1 hadoop hadoop 1685 Dec 2 15:46 fsimage_0000000000000000152
-rw-rw-r--. 1 hadoop hadoop 62 Dec 2 15:46 fsimage_0000000000000000152.md5 -rw-rw-r--. 1 hadoop hadoop 1685 Dec 2 15:46 fsimage_0000000000000000154
-rw-rw-r--. 1 hadoop hadoop 62 Dec 2 15:46 fsimage_0000000000000000154.md5
SNN:
[hadoop@hadoop001 current]$ pwd
/home/hadoop/tmp/dfs/namesecondary/current
[hadoop@hadoop001 current]$ ll
-rw-rw-r--. 1 hadoop hadoop 1048576 Dec 1 23:31 edits_0000000000000000062-0000000000000000152
-rw-rw-r--. 1 hadoop hadoop 42 Dec 2 15:47 edits_0000000000000000153-0000000000000000154 -rw-rw-r--. 1 hadoop hadoop 1685 Dec 2 15:46 fsimage_0000000000000000152
-rw-rw-r--. 1 hadoop hadoop 62 Dec 2 15:46 fsimage_0000000000000000152.md5
-rw-rw-r--. 1 hadoop hadoop 1651 Dec 2 15:47 fsimage_0000000000000000154
-rw-rw-r--. 1 hadoop hadoop 62 Dec 2 15:47 fsimage_0000000000000000154.md5
edits 编辑日志文件
fsimage 镜像文件 .md5 验证文件----验证文件大小,看文件是否有损坏
其中的fsimage_152<==>edits_62-152,相当于前者对后者的一个重命名
而fsimage_154<==>fsimage_152 + edits_153-154-----这是nn的作用,就是将老大的fsimage_152 文件和 edits_153-154 文件拿到【NN】进行合并,生成 fsimage_154 文件,然后将此文件【推送】给老大,同时老大在新的编辑日志文件edits_inprogress_000000000000000155。
以上的整个动作-----检查点,又叫checkpoint
官网:https://hadoop.apache.org/docs/r3.2.2/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
搜索checkpoint关键字:
dfs.namenode.checkpoint.period 3600(1h)
dfs.namenode.checkpoint.txns 1000000(数据文件达到1000000个)
--》以上两个参数条件,任意满足其一,就会做一次checkpoint
3.4 历程
大数据早期的时候:只有NN一个人,假如挂了 ,真的挂了。
大数据中期的时候:SNN,定期来合并、 备份 、推送,如果NN磁盘坏了,是可以用SNN的edit和fsimage的文件的,但是这样的也就是1小时备份1次。比如11点合并备份,但是11点半挂了,从SNN恢复到NN,只能恢复11点的时刻的元数据,丢了11-11点半的元数据。 大数据后期的时候:就取消SNN,新建一个实时NN,作为高可靠 HA。
NN Active 老大对外提供读和写时,Active是活跃的
NN Standby 实时的等待active NN挂了,瞬间启动Standby--》active,对外提供读写服务。
datanode dn 数据节点
4.1 dn的作用
a.存储数据块 和 块的校验和(块的校验和对比,看数据块有没有问题,有没有损坏)
b.定期给NN发送块报告(块报告 blockreport)
官网:https://hadoop.apache.org/docs/r3.2.2/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml
搜索关键字:block report 以及directoryscan
参数:dfs.blockreport.intervalMsec 21600000(ms)=6h(块报告时间)
参数:dfs.datanode.directoryscan.interval 21600(s)=6h(目录扫描时间)
块扫描(DN扫描数据目录,然后把块的磁盘和内存差别扫描出来),目的是为了向NN汇报块差别多少,块变化多少,块处于什么状态。
通过上面两个参数的单位不一致,我们知道hadoop作为开源软件,它的设置不是一个人写的,所以它的单位不统一,但是但是但是!!未来我们在设置参数时一定要先去确认参数的单位是什么,再去设置!!!
4.2 块损坏
生产HDFS Block损坏恢复最佳实践(含思考题) | 若泽大数据 www.ruozedata.com
在我们出现块损坏或丢失的时候,不要慌张,如果你的块是偶发性的或者少量丢失,可以等待,数据块是会自动修复的,而自动修复的时间就是dfs.datanode.directoryscan.interval 21600(s)=6h这个参数。因为在块损坏之后,DN节点执行directoryscan之前,是不会发现块损坏的,所以要么就是静静等待6h让它自动修复,要么就修改directoryscan参数扫描时间,让它更快一点修复。但是如果是大面积丢失,就得手动 *** 作了。--------想要更详细了解的可以看上面粘贴的网址
5.hdfs写流程------output对用户是无感知
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.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条)