HDFS分布式文件系统

一、HDFS概述

1.HDFS不支持对文件的随机写
可以追加,但是不能修改
原因:文件在HDFS上存储时,以block为基本单位存储!
(1)没有提供对文件的在线寻址(打开)功能
(2)文件以块形式存储,修改了一个块中的内容,就会影响当前块之后的所有的块,效率低。
2.HDFS不适合存储小文件
根本原因:HDFS存储了大量的小文件,会降低NN的服务能力!
NN负责文件元数据(属性,块的映射)的管理,NN在运行时,必须将当前集群中存储的所有文件的元数据加载到内存中!
NN需要大量的内存!
举例: 当前运行NN的机器,有64G内存,除去系统开销,分配给NN50G内存!

	举例:文件a (1k), 存储到HDFS上,需要将a文件的元数据保存到NN,加载到内存
		 文件名  创建时间  所属主  所属组 权限 修改时间+ 块的映射(1块)
		150B
		
		最多存储50G/150B个文件a
			50G/150B * 1k
		 
	文件b (128M), 存储到HDFS上,需要将b文件的元数据保存到NN,加载到内存
			文件名  创建时间  所属主  所属组 权限 修改时间+块的映射(1块)
		150B
		最多存储50G/150B个文件b
			50G/150B * 128M

3.同一文件在同一时刻只能由一个客户端写入!
4.块大小
块大小取决于dfs.blocksize, hadoop2.x默认为128M,1.x默认为64M
默认为128M的原因,基于最佳传输损耗理论!
不论对磁盘文件进行读还是写,都需要先进行寻址!
最佳传输损耗理论:在一次传输中,寻址时间占用总传输时间的1%时,本次传输的损耗最小,为最佳性价比传输!
目前硬件的发展条件,普通磁盘写的速率大概是
100M/S,寻址时间一般为10ms!
10ms/1%=1s
1s*100M/S=100M
块在传输时,每64K还需要检验一次,因此块的大小必须为2的N次方,最接近100M的就是128M!
如果公司使用的是固态硬盘,写的速度是300M/S,将块的大小调整到256M
如果公司使用的是固态硬盘,写的速度是500M/S,将块的大小调整到512M

5.块大小的调节
不能太大:
(1)在一些分块读取的场景,不够灵活,会带来额外的网络消耗。
(2)在上传文件时,一旦发生故障,会造成资源的浪费。
不能太小:
(1)块太小,同样大小的文件,会占用过多的NN的元数据空间
(2)块太小,在进行读写操作时,会消耗额外的寻址时间。

6.副本数的概念指的是最大副本数!
具体存放几个副本需要参考DN节点的数量,每个DN节点最多只能存储一个副本!

7.默认块的大小为128M,128M指的是块的最大大小!每个块最多存储128M数据,如果当前块存储的数据不满128M,存了多少数据,就占用多少磁盘空间!
一个块只属于一个文件!

二、HDFS的客户端操作

1.shell操作
hadoop fs: 既可以对本地文件系统进行操作,也可以对分布式文件式系统进行操作!
hdfs dfs:只能操作分布式文件系统

2.客户端操作
使用HDFS
服务端:启动NN,DN
客户端:使用shell客户端 hadoop fs
使用Java客户端
使用python客户端
使用javaapi
Filesystem:客户端的基类
LocalSystem:本地文件系统
DistributedFileSystem:分布式文件系统
具体实现取决于配置文件的fs.defaultFS参数
Configuration:
负责读取配置文件中的参数,保存到一个map中!
默认Configuration会读取类路径下的八个配置文件!
Configuration.set(name,value):手动添加属性
Path:一个文件的路径
Path.toString():输出文件的完整的URI(协议+路径)
Path.getName():输出文件名
FileStatus:文件的状态(文件的属性信息)
LocatedFileStatus:除了包含文件的属性信息,还包含文件所有的块的位置信息(length,offset,hosts)
FileSystem.listStatus(Path p) | FileSystem.getFileStatus(Path p)
自定义上传和下载
上传:获取本地文件系统对文件的一个输入流,读取文件将读到的数据通过HDFS对目标路径的输入流,进行写出!
下载:获取HDFS文件系统对文件的一个输入流,将读到的数据通过本地文件系统对目标路径的输出流,进行写出。
(1)获取文件系统上对某个路径的输入流:DFSinputStream is=FileSystem.open(Path p);
(2)获取文件系统上对某个路径的输出流:FileSystem.create(Path p);
(3) 数据的拷贝:IOUtils.copyBytse(in,out,4096,true);
(4)定位读取:DFSFileInput Stream.seek(int offset);

3.HDFS的写数据流程
(1)服务端启动HDFS中的NN和DN进程。
(2)客户端创建一个分布式系统客户端,由客户端向NN发送请求,请求上传文件
(3)NN处理请求,检查客户端是否有权限上传文件,路径是否合法等
(4)检查通过,NN响应客户端的请求,可以上传
(5)客户端根据自己设置的块大小,开始上传第一个块,默认为0~128M,NN根据客户端上传的副本数(默认为3),根据机架感知策略选取指定数量的DN节点返回
(6)客户端根据返回的DN节点,请求建立传输通道
客户端向最近(网络距离最近)的DN节点发起建立通道的请求,由这个DN节点依次向通道中的(距离当前DN距离最近)下一个DN节点发送建立通道请求,各个节点发送响应,通道建立成功。
(7)客户端每读取64k的数据,封装为一个packet(数据包,传输的基本单位),将packet发送到通道的下一个节点,通道中的节点收到packet后,落盘(检验)存储,将packet发送到通道的下一个节点。每个节点在收到packet后,向客户端发送ack确认消息!
(8)一个块的数据传输完成后,通道关闭,DN向NN上报消息,已经收到某个块。
(9)第一个块传输完成,第二块开始传输,依次重复(5)到(8),直到最后一个块传输完成,NN向客户端响应传输完成!客户端关闭输出流。

4.异常写流程
(1)到(6)见上
(7)客户端每读取64k的数据,封装为一个packet,封装成功的packet,放入到一个队列中,这个队列称为dataQuene(待发送数据包)
在发送时,先将dataQuene中的packet按顺序发送,发送后再放入到ackQuene(正在发送的队列)。
每个节点在收到packet后,向客户端发送ack确认消息!
如果一个packet在发送后,已经收到了所有DN返回的ack确认消息,这个packet会在ackquene中删除!
假如一个packet在发送后,在收到返回的ack确认消息超时,传输终止,ackquene中的packet会回滚到dataQuene。

重新建立通道,剔除坏的DN节点,建立完成之后,继续传输!
只要有一个DN节点收到了数据,DN上报NN已经收完此块,NN认为当前快已经传输成功!
NN会自动维护副本数!
5.机架感知
2.7.2默认的机架感知策略
第一个副本放在本地机架的一个DN节点
第二个副本放在本地机架的另一个DN节点
本地机架的网络拓扑距离最多为2,速度快!
第三个副本放在其他机架的一个DN节点
为了安全性

NameNode的工作原理

1.
(1)NN的作用
NN保存HDFS上的所有文件的元数据!
NN负责接手客户端的请求!
NN负责接受DN上报的信息,给DN分配任务(维护副本数)!
(2)元数据的存储
元数据存储在fsimage文件+edits文件中!
fsimage(元数据快照文件)
edits(记录所有写操作的文件)
NN负责集群中所有客户端的请求和所有DN的请求!在一个集群中,通常NN需要一个高配置,保证NN可以及时处理客户端或DN的请求,一旦NN无法及时处理请求,HDFS就已经瘫痪!
(3)fsimage的产生:
第一次格式化NN时,此时会创建NN工作目录,其次在目录中生成一个fsimage_000000000000文件
当NN在启动时,NN会将所有的edits文件和fsimage文件加载到内存中合并得到最新的元数据,将元数据持久化到磁盘新生成的fsimage文件
如果启用了2NN,2NN也会辅助合并元数据,会将合并后的元数据发送到NN.
(4)edits:
NN在启动后,每次接受的写请求操作,都会将写命令记录到edits文件中,edits文件每间隔一定的时间和大小滚动!
(5) 每次写操作命令,分为若干步,每一步都有一个id,这个id称为txid!

(6)NN元数据分为两部分:
inodes:记录在fsimage文件中或edits文件中
blocklist:块的位置信息(每次DN在启动后,自动上报的)
(7)checkpoint
每次Namenode会定期进行checkpoint,主要是为了防止在运行期间产生大量的edits文件,导致下次重启时恢复时间过长!
定期将edits文件中的新内容,持久化到fsimage文件中,进行快照存储!
默认的机制:每间隔1h,执行一次;距离上次,又新生了100w次txns操作

2. HDFS集群的注册
(1)每次格式化NN,会产生一个VERSION文件
VERSION记录的是NN的集群的信息
每次格式化NN时,重新生成clusterID和blockpoolID(会被DN领取,生成一个同名的目录,每次DN启动时,会将这个同名目录中的块上报NN)
DN在第一次启动时,如果没有VERSION信息,会向配置文件中配置的NN发起请求,生成VERSION,加入到集群!

3.安全模式
(1)NN的安全模式主要是为了接受DN上报块信息!
NN在启动时,当NN将所有的元数据加载完成之后,等待DN来上报块的信息!
当NN中所保存的所有块的最小副本数(默认为1)/块的总数>99.99%时,NN会自动离开安全模式!
在安全模式,客户端只能进行有限的读操作!不能写!
手动操作:hdfs dfsadmin -safemode get/enter/leave/wait
4.NN总结
NN主要负责元数据的存储
两种存储的文件格式
edits:在NN启动后,保存新写入的命令
fsimage:在合并了edits和fsimage文件后,将新的元数据持久化到新的fsimage文件中
合并的时机:需要满足checkpoint:(1)默认1h,(2)两次checkpoint已经额外产生了100w txid的数据!

NN启动的过程
先加载fsimage——000000xx文件
将fsimage文件xx之后的edits文件加载
合并生成最新的元数据,记录checkpoint,如果满足要求,执行savaNamespace操作,不满足等满足后执行!
saveNamespace操作必须在安全模式下执行!
5.Datanode
(1)作用:
接受客户端的读写块请求!
DN负责维护块的完整性,通过定期检查块的校验和来判断块是否损坏
损坏的块,DN会自动删除,在下次启动时,不会上报给NN
DN负责定期向NN汇报块的信息,接收NN的其他任务(负责块等)
(2)Datanode的掉线时长
DN和NN每间隔dfs.heartbeat.interval(3s)进行一次心跳!
如果DN和NN上一次心跳距离当前时间,已经过了2dfs.namenode.heartbeat.recheck-interval(5min)+10dfs.heartbeat.interval,NN会将DN的状态标记为DEAD!
6.其他配置
(1)NN的多目录配置
NN的多目录指对元数据进行多个目录的同事备份,通过hdfs.site.xml中dfs.namenode.dir进行设置!
(2)DN的多目录配置
如果机器添加了新的磁盘,希望DN在写入块时,向新磁盘的目录进行写入!
配置DN多目录!通过hdfs.site.xml中的datanode.data.dir进行配置!
(3)服役新节点
准备机器,安装软件,配置NN,RM的相关配置
启动datanode和弄得manager进程即可
服役了新的DN节点以后,可以执行再平衡命令,这个命令可以将集群中的块进行重新平衡分配! ./start-balancer.sh
(4)白名单
白名单是为了阻止某个进程加入集群!
白名单之外的机器,无法进入集群!
白名单通过hdfs.site.xml中dfs.hosts配置!
可以通过hdfs dfsadmin -refreshNodes刷新配置,读取此配置信息!
(5)黑名单
退役datanode!
黑名单通过hdfs-site.xml中的dfs.hosts.exclude配置!
黑名单中的机器在最后一次启动时,会将当前机器的块移动到其他节点!
注意:如果当前集群中在线的DN节点不满足某些文件的副本数要求,当前退役节点无法退役完成!
(6)集群间的拷贝
hadoop distcp hdfs:///xxxx:xxx/xxx hdfs://xxxx:xxx/xxx

7.解决HDFS小文件的存储
(1)从源头上解决
在上传时,将多个小文档归档
tar -zcvf xxx.tar.gz 小文件列表
(2)如果小文件已经上传到HDFS了,可以使用在线归档
在线归档的功能实际是一个MR程序,这个程序将HDFS已经存在的多个小文件归档为一个归档文件!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值