Hadoop
HDFS的读写文件流程
HDFS写文件流程
-
客户端通过Distributed FileSystem模块向NameNode请求上传文件(hadoop fs -put 文件名 文件路径 )
- 判断该客户端是否有写入权限
- NameNode检查目标文件是否已存在,父目录是否存在。
-
NameNode返回是否可以上传(不满足上述直接报错)。
-
客户端请求第一个 Block上传到哪几个DataNode服务器上。
-
根据副本放置策略,负载均衡,机架感知以及网络拓扑图获取.
副本放置策略:
第一副本:放置在上传文件的DataNode上;如果是集群外提交,则随机挑选一台磁盘不太慢,CPU不太忙的节点上;
第二副本:放置在于第一个副本不同的机架节点上;
第三副本:与第二个副本相同机架的不同节点上;
如果还有更多的副本,则随机放在节点中。
-
-
NameNode返回3个DataNode节点,假设分别为dn1、dn2、dn3。
-
数据逻辑切块
物理切块:真实的切分,将200M切分为128M+72M。两个块会分别存储
逻辑切块:可以理解为切分前的准备,每个块128M,计算出需要切分成几个块(切块规划) -
客户端通过FSDataOutputStream模块请求dn1上传数据(与dn1请求链接),dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。
-
dn1、dn2、dn3逐级应答客户端。
-
客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet(默认64k)为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。
此时开始物理切片
-
当一个Block传输完成之后,上传通道关闭,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)
-
所有数据上传成功后,会向客户端返回上传结果,客户端向NameNode返回信息,告知数据上传成功。
-
上传失败的处理
HDFS读文件流程
-
客户端向Namenode请求下载文件(hadoop fs -get 文件 )
-
Namenode接受到客户端的请求
- 判断该客户是否有写入的权限
- 判断该文件是否存在
-
client(客户端)根据Namenode返回Datanode队列,并行的从这些Datanode中读取block块的数据
- 就近原则返回DataNode
-
上述block块内容读取完毕后,会继续访问Namenode剩余部分或者全部的block块的地址,然后并行读取,(以packet为单位来做校验),直至所有的block读取完成
第一个块下载成功之后会生成一个 crc文件,和上传时候的.meta文件进行完整度校验
校验内容:起始偏移量和末尾偏移量之间的内容
校验通过则认为第一个块下载成功 -
按照block的信息(编号等),将这些block块组合成一个完整文件,至此HDFS读数据完成
-
下载出现异常
- 数据块的某一个节点读取不到数据的时候会向namenode进行汇报,namenode就会标记这个节点可能是问题节点(以后下载时,就会将这个 问题节点返回的优先度下降),接着客户端继续读取这个块的其他节点
- 块下载失败会有3次尝试重新下载的机会,如果块过多的,NameNode会分批次返回块信息
补充:HDFS文件块大小
HDFS块的大小是指在HDFS中存储一个文件时,将文件分成多少个块,并且每个块的大小是多少。在HDFS中,块的大小通常是64MB或128MB。这个大小是可以配置的,但需要注意的是,块的大小不应该设置得太小,因为块的数量会增加,而且设置太小,会增加寻址时间,程序一直在找块的开始位置.但是,块的大小也不应该设置得太大,因为这会增加数据丢失的风险,如果一个块出现故障,整个块都需要重新传输,这会导致数据恢复的时间变长,而且从磁盘传输数据的时间会明显大于定位这个块开始位置所需的时间。导致程序在处理这块数据时,会非常慢。
总结:HDFS块的大小设置主要取决于磁盘传输速率。
-
HDFS中的文件在物理上是分块存储(Block),块的大小可以通过配置参数( hdfs-site.xml文件中的dfs.blocksize)来规定,默认大小在Hadoop2.x/3.x版本中是128M,1.x版本中是64M。
-
如果在系统运行过程中修改了dfs.blocksize属性的值,那么这个修改只对新文件起作用,对于已经存在的文件不会产生影响。
-
块大小的计算方式
- 如果寻址时间约为10ms,即查找到目标block的时间为10ms。
- 寻址时间为传输时间的1%时,则为最佳状态,因此,传输时间=10ms/0.01=1000ms=1s
- 而目前磁盘的传输速率普遍为100MB/s。,所以block大小=1s*100MB/s=100MB