HDFS采用了主从(Master/Slave)结构模型,一个HDFS集群是由一个NameNode和若干个DataNode组成的。
其中,NameNode作为主服务器,管理文件系统的命名空间和客户端对文件的访问操作;集群中的DataNode管理存储的数据。
HDFS分布式文件系统
HDFS设计思想
HDFS核心设计思想:分散存储、冗余备份
1、如果一个文件中有10个数值(一行一个,并且都是可以用int来度量), 现在求10个数值的和。
思路:
(1)一行一行读取文件的内容
(2)帮读取到的文本内容转化为Int类型
(3)帮转化之后的值进行累加
(4)输出
2、假如,这样的文件有很大一堆, 并且每个文件都很大,而且每个文件里面的内容都很多。
例如:现在有10000个文件,每个文件2T,文件里面的内容依然是每行一个数值,要求这一堆文件的所有数值的和。
如果说用1的思路来说,最终可能也可以计算出来结果,但是效率比较低,大概率算不来。
一行一行读取文件的内容 串行!!!
改进方案: 串行 --》 并行
分布式计算:
1、第一个阶段:先将大的任务切分成多个小的任务,然后让集群中的每个节点来对这些小的任务来执行计算
2、第二个阶段:需要将第一个阶段的中间临时结果进行最终的汇总
3、又有个问题:该10000个2T的文件应该怎么分布, 才能让这10000个任务的执行效率达到最高?
如果集群有10000个节点,这样每个节点上面存放一个文件,然后在对应的节点上面启动对应的计算任务,这样效率最高。
计算在a节点, 数据存在b节点
数据传输 效率问题
4、数据的处理:存储和计算是怎么设计的?
谷歌在设计大数据解决方案的时候,存储和计算两个方案是相互依赖的
存储:HDFS
计算:MapReduce
在设计存储的时候,必须要考虑计算的问题
在设计计算的时候,必须要考虑存储的问题
HDFS的设计思路:
要帮存储到HDFS集群中的数据均匀的分散的存储到整个集群中
举个例子:
100g数据,集群有100个节点,按照1g的大小进行切分存储,每个节点要存储1g的数据量
100g数据,集群有90个节点,按照1g的大小进行切分存储,其中90台服务器中有10台需要存储2g的数据,其余80台服务器需要存储1g的数据
假设1g的数据需要1秒钟的计算时间,那么整个任务需要 2 秒钟的计算时间
100g数据,集群有90个节点,按照512M的大小进行切分存储,其中90台服务器中有20台需要存储1.5g的数据,其余70台服务器需要存储1g的数据
假设1g的数据需要1秒钟的计算时间,那么整个任务需要 1.5 秒钟的计算时间
从上面的结果来看,切分的块是不是越小越好
但是: 小文件如果多,会有问题
access.log 100g
block0 50g
block1 50g
access.log 100g
block0 20g
block1 20g
block2 20g
block3 20g
block4 20g
对于用户来说,一个文件存储进来的时候被HDFS切分了,当用户下载这个大文件的时候,还需要给完整的合并回来。也就是需要给拼装回来,并且拼装的顺序不能错。
从上面的结果来看,切分的块是不是越大越好
中庸思想
不大不小 : HDFS在设计的时候就考虑到了不同的应用场景中的情况,在不同的场景中,有可能需要的块的大小不一样,可以配置。
这个块的大小的配置,可以自行配置
有默认的大小:
Hadoop2.x版本以前,默认的是64M
Hadoop2.x(含)版本以后,默认的是128M
到目前为止:
让大数据能够存入到HDFS,并且需要考虑到计算的效率问题,让这个文件进行切分存储,并且需要让这些切分存储的文件块能够比较均匀的分散的存储到集群中。
解决存问题:
数据量大,一台集群放不下,使用多态集群存储
一个节点存不下,加节点。
HDFS集群,理论上,可以通过无限制的加集群来完成存储。
但是,加到一定的时候是有上限的
1、HDFS集群是主从架构
主从架构也就意味着主节点能够管理的从节点的个数是有上限的。
2、无限制的加集群,能加的机器的可靠性不是特别高。成本和效率
给数据存储到集群中中,有可能会出现数据丢失的情况。
5、HDFS是怎么保障数据的安全的?
HDFS使用了一种最有效也是最笨重的方式:存储多份
数据节点hadoop1、hadoop2、hadoop3,只要有一个节点存活,数据就安全。
多份数据的存储有原则的:
- 数据的备份的个数由客户端指定的
- 如果一份数据存储多份,这些多份的数据完全没有必要在一个节点上
也就是:
如果集群有3个数据存储节点,数据指定存储4份,结果HDFS只会存储3份。
HDFS的集群中的任意一个数据节点,肯定没有两份完全一模一样的数据。
6、HDFS核心思想
总结:分散存储、冗余备份
- 大文件被切割成小文件,使用分而治之的思想对同一个文件进行管理
- 每个切分之后的块都进行冗余存储,高可用不丢失
真实文件存储的参考位置: /software/hadoop/data/datanode/current/BP-1075021137-192.168.22.136-1630242976706/current/finalized/subdir0/subdir30
一个节点能否存一个文件的多个数据块?可以
如果只有3个节点,结果存储的那个文件被切分成了4个块。所以一定有一个数据节点存储了其中的2个数据块。
一个文件存储了多份,只需要关注某个数据块的多个 副本 的分布就可以啦
blk_01: hadoop02 hadoop03
blk_02: hadoop03 hadoop04
blk_03: hadoop02 hadoop03
blk_04: hadoop03 hadoop04
给上面的数据反过来看:
hadoop02: blk_01 blk_03
hadoop03: blk_01 blk_02 blk_03 blk_04
hadoop04: blk_02 blk_04
如果是上面的情况,怎么样保证安全?
只要宕机的节点的数量少于副本冗余的数量,就一定能保证安全。
HDFS架构
1、namenode:掌管文件系统的目录树,处理客户端的请求,保存元数据信息
2、datanode:存储实际的数据的,处理真正的读写
3、secondnamenode:分担namenode压力的,协助合并元数据信息
详细补充解释:
1 | 1、NameNode(nn):是Master,管理者节点。 |
HDFS使用注意事项
HDFS不适于以下操作:
- 要求高的数据访问:比如毫秒级
- 小文件存取:寻道时间超过读取时间
- 并发写入、文件随机修改:一个文件只能有一个写,仅仅支持append追加
- 不适合存储小文件:存储一个1亿个小文件,大小仅仅1t,但是消耗掉20g左右的内存
HDFS三大机制
心跳机制
HDFS的心跳:
集群分布式、跨网络。 跨网络有数据延迟和丢失问题。
datanode每间隔一段时间就会跟namenode去联系一次,证明自己还活着,让namenode能够识别到当前的集群还有多少个datanode存活。
每次间隔一个固定的时长,datanode都会发送一个心跳数据给namenode,如果过了很长一段时间namenode没有接受到datanode的心跳数据包,那么namenode就要有一个标准来判断datanode是否真的宕机掉。
作用:
- 让namenode能够识别到datanode的存活状态
- 心跳数据包
(1)从节点的自身状态:磁盘使用量、块的数量、块的状态
(2)这个从节点所保存的所有的块的信息:file1.txt blk_001 blk_002
每一个从节点上线之后,会帮自身所持有的的数据块通过心跳汇报给namenode,当namenode接收到所有的datanode的汇报信息之后,就能统计出来,哪些文件的哪些数据块的多个副本的分布情况。
blk_001: hadoop01 hadoop02
blk_002: hadoop02 hadoop03
HDFS启动流程:
- 先启动namenode进程
- 加载namenode文件夹当中存储的磁盘元数据信息(fsimage edits )
- namenode在启动完毕之后,会在namenode节点启动一个服务,等待所有的datanode上线 并汇报他们的数据块的内容
- datanode一旦上线,就会通过心跳机制帮自身所持有的block块信息全部汇报给namenode
- 只有当namenode等到了所有的datanode的上线,并且帮所有的块信息都汇报完毕之后,最后namenode才能够得知,整个集群的所有的文件的数据块的副本都存储。
元数据:
- 目录树结构
- 每个文件的数据块的存储的节点位置
假如hdfs集群非常大,会出现下面情况:
- 元数据信息fsimage文件特别大,加载到内存所需要的时间会变长
- datanode节点多,并且每个datanode节点保存的数据块的个数也变多
因此,随着hdfs集群的增大,集群启动的时候所消耗的资源也越来越多。
总结:
1 | 心跳: |
安全模式
在集群没有完全启动的这个时间段内,客户端可不可以进行上传下载呢? 不可以。
在正常的启动范围内,HDFS集群会进入安全模式,在安全模式中,hdfs集群不能正常对外提供服务。
Namenode进入安全模式:
- 当hdfs集群中的datanode宕机之后,hdfs后台会启动一些服务,做自我恢复
- 当丢失的数据块的比例超过 0.1% 的时候会自动的进入安全模式
Namenode退出安全模式:
- 找出问题所在 ,进行修复 (比如修复宕机的 datanode)
- 手动通过命令强行退出(但是并没有真正解决数据丢失问题)
1 | 安全模式相关命令: |
副本存放策略
副本存放策略:就是决定一个数据块的多个副本(默认是3个) 到底应该选取哪些服务器的节点进行存储。
存储原则:
- 任意的一个节点上面不要存储两个一样的副本块
- 如果一个数据块要保存完整的3个副本,至少需要3个数据节点
副本存放策略:
- 第一个副本块选取和客户端相同的节点上
- 第二个副本块选取跟第一个副本的存储节点相邻机架的任意一个节点
- 第三个副本存储在和第二个副本块所在机架不同的节点上
HDFS的读写流程
NameNode和SecondaryNameNode联合工作流程
HDFS的shell操作
启动Hadoop集群
1 | sbin/start-dfs.sh |
查看 dfs 集群工作状态
1 | hdfs dfsadmin -report |
-mkdir:创建/zz文件夹
1 | hadoop fs -mkdir /zz |
-appendToFile:追加文件操作
1 | hadoop fs -put wordcount.txt /bb/cc |
-moveFromLocal:从本地剪切到HDFS
1 | vim aa.txt |
-moveToLocal:从 hdfs 剪切到本地
1 | 功能:从 hdfs 剪切到本地 |
-copyFromLocal:从本地拷贝到HDFS
1 | 功能:从本地文件系统中拷贝文件到HDFS路径去 |
-copyToLocal:从 hdfs 拷贝到本地
1 | 功能:从 hdfs 拷贝到本地 |
-put:等同于copyFromLocal
1 | vim cc.txt |
-get:从hdfs下载文件到本地
1 | 功能:等同于copyToLocal,就是从 hdfs 下载文件到本地 |
-appendToFile: 追加文件
1 | vim dd.txt |
-ls: 显示目录信息
1 | hadoop fs -ls /zz |
-cat:显示文件内容
1 | hadoop fs -cat /zz/aa.txt |
-chgrp、-chmod、-chown:修改文件权限
1 | hadoop fs -chmod 666 /zz/aa.txt |
-mkdir:创建路径
1 | hadoop fs -mkdir /yy |
-cp:从HDFS拷贝到HDFS
1 | 功能:从HDFS的一个路径拷贝到HDFS的另一个路径 |
-mv:在HDFS目录中移动文件
1 | hadoop fs -mv /zz/aa.txt /yy |
-tail:显示一个文件的末尾1kb的数据
1 | hadoop fs -tail /yy/dd.txt |
-rm:删除文件或文件夹
1 | hadoop fs -rm /zz/dd.txt |
-rm -r:递归删除目录及目录里面内容
1 | hadoop fs -rm -r /zz |
-du:统计文件夹的大小信息
1 | hadoop fs -du -s -h /yy |
-setrep:设置HDFS中文件的副本数量
1 | hadoop fs -setrep 5 /yy/aa.txt |
-help:输出这个命令参数手册
1 | 功能:输出这个命令参数手册 |
-rmdir:删除空目录
1 | 功能:删除空目录 |
-text:以字符形式打印一个文件的内容
1 | 功能:以字符形式打印一个文件的内容 |
-df:统计文件系统的可用空间信息
1 | 功能:统计文件系统的可用空间信息 |
-count:统计指定目录下的文件节点数量
1 | 功能:统计一个指定目录下的文件节点数量 |
-setrep:设置 hdfs 中文件的副本数量
1 | 功能:设置 hdfs 中文件的副本数量 |