目录
一.HDFS的读写流程
1.1 读流程
1.客户端获取DistributedFileSystem对象,调用open方法,准备读取一个文件
2.namenode收到读请求后,会校验是否有权限,读取文件路径是否存在等操作,如果通过校验,会返回一个输入流对象以及文件的所有块的所有副本的位置信息
3.客户端准备调用输入流的read方法读取数据,先将第一个块的三个位置由近及远的排序,选择最近的副本开始循环调用read方法读取数据
4.当块读完后,会断开与该datanode的连接,继续寻找下一个块的最佳读取位置读取数据,直到整个文件读取完毕
5.调用输入流的close方法关闭流,以及向namenode汇报读取流程结束
注意:如果读取过程中,出现机器宕机,会选择该块的另外两个副本的最佳位置,开始重新读取该块的数据,并标记宕机的那个机器节点,防止其他的读取操作在此来到该节点(做无用功).读取过程中,也会进行校验和确认数据是否完整,如果不完整,也会选择其他的副本重新读取
1.2 写流程
1.客户端获取DistributedFileSystem对象
2.调用分布式文件系统对象的create方法,表示创建文件路径
3.namenode会对客户端是否有权限,目录是否已经存在等进行校验,如果校验通过,则返回一个输出流对象,并返回第一个块的三个datanode的信息
4.客户端先将三个datanode节点组成一个socket通信的pipleine,由近及远的顺序
5.客户端将本地数据读入内存,封装成多个chunk(512byte)和checksum(4byte),然后再将多个chunk和checksum封装成一个packet(64kb)
6.客户端调用输出流的write方法,将每一个packet写入管道的第一个节点的内存中,第一个节点再传入第二个节点内存,第二个节点再传入第三个节点内存.三个节点都要进行向客户端进行ack应答,表示存储成功
7.客户端会源源不断的向管道书写packet,当累计到一个块大小128M时,会断开该管道,重新向namenode申请下一个块的三个datanode信息.重复上述操作,知道文件的最后一个块完成写出,调用
close方法关闭输出流.再与namenode进行通信,表示上传成功,namenode重新维护元数据
细节:
写流程设计两个队列和两个线程
dataqueue--->dataStreamer
dataqueue:用来存储客户端封装好的packet
dataStreamer:将dataqueue中的每一个头元素packet拷贝pipeline中,并移除到ackqueue队列
ackqueue--->responseStreamer
ackqueue:用来记录正在管道中的所有packet
responseStreamer:用来接受ack信息,如果三个节点都ack成功,就会将ackqueue中的packet删除
注意:
如果中间出现宕机,则会记录宕机的机器防止下次再给予操作于该机器,然后将另外两个节点组成一个新管道,并为了确保数据一致性,会对数据进行回滚重新写入
二.HDFS的块的特点
2.1 hdfs块的特点
hdfs的块大小统一,固定的
hdfs的块大小可以自定义
默认情况:
hadoop1.x --->64M
hadoop2.x --->128M
hadoop3.x --->256M
块是hdfs的最小存储单元
块使用了副本的概念(提高数据的安全性,可靠性)
块的多个副本一定是布局到不同的机器上的(一个机器不可能有一个块的两个副本)
文件的最后一个块,通常是小于128M,实际大小是多少,就占磁盘多少空间
注意:块的数量(一个文件能分成的块数) 和 块的个数(算上副本的块的总数)要区别开
2.2 hdfs块大小的选择
1.块不能太大,原因是网络宽带稀缺,下载时间长,带宽被稀释的越多
2.块不能太小
①.最小化寻址开销时间
寻址与传输用时比:10ms:1000ms
②namenode内存的利用率
内存有限的情况下,namenode存储的元数据数量有限,即分布式文件系统的总块数有限
此时块越大,分布式文件系统的存储能力越强
③扩展:怎么提高集群的存储能力
(1).在namenode内存是固定的情况下,提高块的大小
(2).在namenode内存充足的情况下,横向扩展集群的datanode个数
2.3 块的参数
1.dfs.blocksize
块的大小对应的参数
2.dfs.namenode.fs-limits,min-block-size
块大小的最小值,默认是1M
3.dfs.namenode.fs-limits,max-blocks-per-file
每个文件的块的最大数量,默认是1048576个
4.块的存储位置:
由dfs.datanode.data.dir参数决定:
默认值${hadoop.tmp.dir}/dfs/data
2.4 HDFS的优缺点
2.4.1 优点
1.高容错性(硬件故障是常态,高可靠性):数据自动保存多个副本,副本丢失后,会自动恢复
2.适合大数据集:GB,TB,甚至PB级数据,千万规模以上的文件数量,1000以上节点规模
3.数据访问:一次写入,多次读取,保证数据一致性,安全性
4.构建成本低
5.多种软硬件平台中的可移植性
6.高效性:Hadoop能在节点之间动态移动数据,并保证各个节点的动态平衡,因此处理速度非常快
2.4.2 缺点
1.不适合做低延迟数据访问
2.不适合小文件存取
3.不适合并发写入,文件随意修改
三.HDFS的体系结构
3.1 namenode
管理命名空间,操作fsimage和edit日志,维护目录树结构,以及块和datanode的存储位置
3.2 datanode
与客户端进行交互完成读写请求,定期向namenode反馈状态信息
3.3 secondnarynamenode
合并fsimage和edit文件,并交给namenode存储
3.4 client
提供API
四.HDFS的工作机制
4.1开机启动流程
## 第一步:
加载name目录下最新的那个fsimage_xxx019文件,将里面存储的元数据(目录树结构)维护到内存中,但是还不是关机前的状态
## 第二步:
将关机前的最后使用的edits_inprogress_xxxx0160进行重命名
edits_0000000000000000160-0000000000000000169操作,然后生成一个最新的edits_inprogress_xxx170文件,并修改seen_txid里的值为170.
将从xxx020~xxx169的这个范围内的所有的edit日志文件加载到内存中,重演里面的操作,从而维护成关机前的最新的目录树结构
## 第三步
如果触发了检查点条件,namenode就会自己做一个检查点。将内存中的最新状态持久化成一个新的fsimage文件,删除之前保留的两份中的最旧那个。 也就是说namenode会保留最近两次的fsimage.
## 安全模式:
从启动到结束,整个过程处于安全模式下。当namenode收到datanode的心跳反馈时,并且达到块数量的99.9%时,会退出安全模式。
注意:当集群第一次开机时,edit文件才生成,而且datanode上还没有块,因此不会出现安全模式。
扩展:为什么客户端的访问操作不直接存储到fsimage里
因为fsimage会随着时间会越来越大(相对而已,不是绝对的,因为有的时候会有删除操作)
直接将访问操作存入fsimage中,性能会非常差。
反而我们提供了edit文件,用于存储客户端的访问,edit文件最大是64M,当达到此值,会新生成一个edit文件来存储新的访问数据。
4.2 安全模式
1.安全模式下不能在hdfs上上传,删除,重命名,追加等操作。只能读取文件。(对于普通用户来说,是只读模式)
2.相关命令
hdfs dfsadmin [-safemode <enter | leave | get | wait>]
hdfs dfsadmin -safemode enter: 进入安全模式
hdfs dfsadmin -safemode leave: 离开安全模式
hdfs dfsadmin -safemode get: 查看安全模式的状态
hdfs dfsadmin -safemode wait: 使安全模式处于等待状态
4.3 心跳机制
1. 概念: 集群在启动后,slave节点会向master节点进行周期性的汇报,汇报自己的健康状态以及其他信息,比如3秒一次,这种机制,我们称之为心跳机制(心跳反馈)
2. dfs的心跳机制:
--(1)namenode在启动的时候会先开IPC通信服务,等待datanode主动连接
--(2)datanode启动后,会主动连接IPC通信服务,并且每隔3秒连接一次,并携带自己的状态信息,如块的ID列表,主机名,磁盘剩余空间等。
-- (3) namenode收到datanode的汇报信息后,在内存中维护信息,并下达其他的相关指令给datanode。
3. namenode什么时候认为datanode宕机了?
两个参数和一个公式决定的:
属性:dfs.namenode.heartbeat.recheck-interval 的默认值为5分钟 #Recheck的时间单位为毫秒
属性:dfs.heartbeat.interval 的默认值时3秒 #heartbeat的时间单位为秒
计算公式:2*recheck+10*heartbeat
通过上述公式可知: 默认情况下10分钟30秒后,如果没有接收到某一个datanode的心跳反馈,则认为该datanode宕机。之后就不会再给该datanode分配任务。
4. 扩展:
大数据框架的master/slaves的这种主从架构,多数都是采用的心跳反馈机制。
比如yarn
zookeeper
hbase
4.4 检查点机制
##概念:
namenode会产生fsimage和一堆edit文件,secondarynamenode会定期的帮助namenode吧fsiamge和edit文件合并,生成最新的fsimage,这种机制称之为检查点机制。
##定期:
--属性1:
dfs.namenode.checkpoint.period :默认是3600s,也就是1小时
--属性2:
dfs.namenode.checkpoint.txns: 默认是100w次,指的是txid的值的变更
--属性3:
dfs.namenode.checkpoint.check.period: 默认是60s,表示60s一检查txid的值是什么
##检查点机制的流程:
1. SecondaryNamenode请求Namenode停止使用正在编辑的edit日志文件,Namenode会创建新的editlog文件(小了吧),同时更新seed_txid文件。
2. SecondaryNamenode通过HTTP协议获取Namenode上的fsimage和最近的没有合并过的所有editlog文件。
3. SecondaryNamenode将fsimage读进内存当中,并逐步分析editlog文件里的数据,进行合并操作,然后写入新文件fsimage_x.ckpt文件中。
4. SecondaryNamenode将新文件fsimage_x.ckpt通过HTTP协议发送回Namenode,secondarynamenode也会保留最近的两份
5. Namenode再进行更名操作,并删除最旧的那一个,
4.5 网络拓扑以及机架感知
##1.网络拓扑就是用于计算服务器远近的
hdfs采用了两个服务器距离最近祖先的距离之和来表示带宽
距离有这四种情况:
Distance(/d1/r1/n1, /d1/r1/n1)=0(同一节点上的进程)
Distance(/d1/r1/n1, /d1/r1/n2)=2(同一机架上的不同节点)
Distance(/d1/r1/n1, /d1/r2/n3)=4(同一数据中心不同机架上的节点)
Distance(/d1/r1/n1, /d2/r3/n4)=6(不同数据中心的节点)
带宽依次递减。
##2. 机架感知(重点)
使用机架感知,必须配置相关属性,以及多台机器,否则所有机器都会被注册到同一个机器上,名字为/default-rack.如果使用了机架感知策略,那么文件块的副本是如何存储的?
--1.hadoop2.8.2版本之前的版本机架感知策略(副本冗余策略)如下:
(1)第一个副本,如果client在某一个datanode上,就存储在本地上,如果client不是datanode,就随机一个机架中的一个datanode进行存储
(2)第二个副本, 存储位置是与第一个副本同一个机架不同datanode上
(3)第三个副本,存储位置是不同机架上的任意一个datanode上
--2.hadoop2.8.2版本之后的版本机架感知策略(副本冗余策略)如下:
(1)第一个副本,如果client在某一个datanode上,就存储在本地上,如果client不是datanode,就随机一个机架中的一个datanode进行存储
(2)第二个副本, 存储位置是不同机架上的任意一个datanode上
(3)第三个副本,存储位置是与第二个副本同一机架上的不同datanode上
(=-=全是理论知识,理清楚顺序和原理就好)