1. HDFS--写(上传)
NameNode:Master主管管理者,管理HDFS的名称空间、配置副本策略、管理数据块Block的映射信息、处理客户端读写请求;
DataNode:Slave,执行NN下达的命令,存储实际的数据块、执行数据块的读写操作;
Client:①文件切分,将文件切分成一个个Block再上传;②与NameNode交互,获取文件的位置信息;③与DataNode交互读取或写入数据;④Client提供一些命令来管理HDFS,如格式化NameNode;⑤通过一些命令来访问HDFS,如对HDFS的增删改查操作;
SecondaryNameNode:辅助NameNode,如定期合并FSimage和Edits并推送给NameNode;②紧急情况下辅助恢复NameNode;
块:HDFS中的文件在物理上分块存储Block,块的大小可通过配置参数 dfs.blocksize来规定,在Hadoop2.x中默认128M,如果寻址时间约为10ms(查找目标Block的时间10ms),寻址时间为传输时间的1%最佳,因此传输时间=10ms/0.01=1s;目前磁盘的传输普遍在100MB/S;则Block的大小为1s*100M/S=100M,凑个整数就是128M了。
①客户端通过Distributed FileSystem向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在。
②NameNode返回是否可以上传;
③Client请求第一个Block上传到哪几个DataNode服务器上;
④NameNode返回3个DataNode节点DN1、DN2、DN3;
⑤Client通过FSDataOutputStream模块请求向DN1发起上传请求建立通信通道,DN1-->DN2-->DN3依次串行,DN3-->DN2-->DN1依次应答成功告知Client
⑥Client客户端开始往DN1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,DN1收到一个Packet就会传给DN2,DN2传给DN3;DN1每传一个packet会放入一个应答队列等待应答。
⑦当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。重复步骤⑤--⑦;
在HDFS写数据的过程中,NameNode会选择距离待上传数据最近距离的DataNode接收数据。那么这个最近距离怎么计算呢?
节点距离:两个节点到达最近的共同祖先的距离总和。
DN1是最近的,DN2和DN3是根据第一个节点DN1选出来的;
第二次的DN4、DN5、DN6可能跟第一次传输的DN一样,也可能不一样取决于内部集群的状况;两次返回的DN都是独立的。
网络拓扑图(只描述关系,不描述实体)
N1与N2之间的距离为2;(找线条数)
假设N1、N2、N3三台机器,从N1上传数据,则最短的节点就是它本身0;
后两个的选择是根据机架感知来选:
For the common case, when the replication factor is three, HDFS’s placement policy is to put one replica on one node in the local rack,
another on a different node in the local rack, and the last on a different node in a different rack.
第二个副本和第一个副本位于相同机架,随机节点;
第三个副本位于不同机架的随机节点;前提都是在相同数据中心的。
串行而不是并行;在于集群的性能限制,第一是NameNode的内存;第二个限制是IO(网络IO| 磁盘IO ),串行每个都是一进一出,而并行全部集中在client上导致传输的性能下降;
2. HDFS读数据流程(下载)
1)客户端通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。给Client响应;
2)Client发起请求下载第一块Block数据;NameNode返回DN1、DN2、DN3表示用这3个节点存储的数据;
3)Client挑选一台DataNode(就近原则,然后随机)服务器,发起建立通信通道请求,DN1回应应答成功;
4 )Client打开一个流FSDataInoutStream 请求读取数据,DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。
4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。
5 )依次重复 2)--4)直到全部下载完成;NameNode响应数据传输完毕,流FSDataInputStream关闭;
3. NN和2NN的工作机制
NameNode的元数据需要存放在内存中,因为经常需要进行随机访问还有响应客户请求,为了提高效率;
同时在磁盘中备份元数据的FsImage,为了数据的安全性防止断电等导致元数据的丢失;
引入Edits文件(只进行追加操作,效率很高),(是为了解决内存中元数据更新时,若同时更新FsImage导致效率降低;若不更新产生一致性问题一旦NameNode节点断电导致数据丢失)每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。
引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。(如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。)
这种保存机制类似在Redis的RDB和AOF:
RDB保存的快,读取的慢;AOF保存的快安全性高,读取慢;
类似AOF的保存是edits.log(每一个对元数据的变动,增删改查,都会立即持久化到edits.log)
类似RDB的是FSimage,随着NN的操作,每隔一段时间存一个档; 启动的时候先加载这个存档,然后再加载很短的一段edits.log;
NN是只写edits.log这个文件并且负责edits.log和FSimage的合并;
先加载fsimage(存档),再加载edits.log(过程);
先写edits,再读写到内存(为了数据的安全性);
edits-inprogress_002这种的都不会删除,而fsimage是只保留最新的2份;
Fsimage:NameNode内存中元数据序列化后形成的文件。包含HDFS文件系统的所有目录和文件inode的序列化信息;是HDFS文件系统元数据的永久性检查点;
Edits:记录客户端更新--增删改元数据信息的每一步操作。
NameNode启动时,先滚动Edits并生成一个空的edits.inprogress,然后加载Edits和Fsimage到内存中,此时NameNode内存就持有最新的元数据信息。
第一阶段:NameNode启动
1 )第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志eidts_inprogress_001和镜像文件Fsimage到内存(先加载Fsimage--存档,再加载edits_inprogress_001;)。
2 )客户端对元数据进行增删改的请求。(先记录在edits_inprogress_001再加载到内存为了数据的安全性;)
3 )记录操作日志edits_inprogress_001和更新滚动日志;这些请求的操作首先会被记录到edits.inprogress中(查询元数据的操作不会被记录在Edits中,因为查询操作不会更改元数据信息); 如果此时NameNode挂掉,重启后会从Edits中读取元数据的信息。
4 )然后,NameNode会在内存中执行元数据的增删改的操作。
第二阶段:Secondary NameNode工作
1 )Secondary NameNode询问NameNode是否需要CheckPoint。直接带回NameNode是否检查结果。
2 )Secondary NameNode请求执行CheckPoint。
3 )NameNode滚动正在写的Edits日志,并生成一个空的edits_inprogress_002,滚动Edits的目的是给Edits打个标记,以后所有新的操作都写入edits_inprogress_002
4)将滚动前的编辑日志Edits_001和镜像文件fsimage 拷贝到Secondary NameNode。
5)加载到内存,并合并。(所谓合并,就是将Edits和Fsimage加载到内存中,照着Edits中的操作一步步执行,最终形成新的Fsimage。)
6)生成新的镜像文件fsimage.chkpoint。
7)拷贝fsimage.chkpoint到NameNode。
8)NameNode将fsimage.chkpoint重新命名成fsimage,替换掉原来的Fsimage。
hdfs oiv查看Fsimage文件
[kris@hadoop101 current]$ ll 总用量 7256 -rw-rw-r--. 1 kris kris 1048576 1月 17 17:10 edits_0000000000000000001-0000000000000000001 -rw-rw-r--. 1 kris kris 42 1月 18 11:08 edits_0000000000000000002-0000000000000000003 -rw-rw-r--. 1 kris kris 1048576 1月 18 17:12 edits_0000000000000000004-0000000000000000020 -rw-rw-r--. 1 kris kris 1048576 1月 18 18:27 edits_0000000000000000021-0000000000000000021 -rw-rw-r--. 1 kris kris 42 1月 18 18:29 edits_0000000000000000022-0000000000000000023 -rw-rw-r--. 1 kris kris 3869 1月 18 19:29 edits_0000000000000000024-0000000000000000074 -rw-rw-r--. 1 kris kris 922 1月 18 20:29 edits_0000000000000000075-0000000000000000090 -rw-rw-r--. 1 kris kris 1048576 1月 18 20:37 edits_0000000000000000091-0000000000000000107 -rw-rw-r--. 1 kris kris 42 1月 19 11:28 edits_0000000000000000108-0000000000000000109 -rw-rw-r--. 1 kris kris 42 1月 19 12:28 edits_0000000000000000110-0000000000000000111 -rw-rw-r--. 1 kris kris 42 1月 19 13:28 edits_0000000000000000112-0000000000000000113 -rw-rw-r--. 1 kris kris 1276 1月 19 14:28 edits_0000000000000000114-0000000000000000127 -rw-rw-r--. 1 kris kris 42 1月 19 15:28 edits_0000000000000000128-0000000000000000129 -rw-rw-r--. 1 kris kris 42 1月 19 16:28 edits_0000000000000000130-0000000000000000131 -rw-rw-r--. 1 kris kris 1048576 1月 19 16:28 edits_0000000000000000132-0000000000000000132 -rw-rw-r--. 1 kris kris 1048576 1月 19 20:45 edits_0000000000000000133-0000000000000000133 -rw-rw-r--. 1 kris kris 14290 1月 20 12:24 edits_0000000000000000134-0000000000000000254 -rw-rw-r--. 1 kris kris 42 1月 20 13:24 edits_0000000000000000255-0000000000000000256 -rw-rw-r--. 1 kris kris 42 1月 20 14:24 edits_0000000000000000257-0000000000000000258 -rw-rw-r--. 1 kris kris 1048576 1月 20 14:24 edits_inprogress_0000000000000000259 -rw-rw-r--. 1 kris kris 2465 1月 20 13:24 fsimage_0000000000000000256 -rw-rw-r--. 1 kris kris 62 1月 20 13:24 fsimage_0000000000000000256.md5 -rw-rw-r--. 1 kris kris 2465 1月 20 14:24 fsimage_0000000000000000258 -rw-rw-r--. 1 kris kris 62 1月 20 14:24 fsimage_0000000000000000258.md5 -rw-rw-r--. 1 kris kris 4 1月 20 14:24 seen_txid -rw-rw-r--. 1 kris kris 206 1月 20 11:36 VERSION [kris@hadoop101 current]$ [kris@hadoop101 current]$ cat seen_txid //文件保存的是一个数字,就是最后一个edit_数字 259 [kris@hadoop101 current]$ hdfs oiv -p XML -i fsimage_0000000000000000258 -o /opt/module/hadoop-2.7.2/fsimage.xml [kris@hadoop101 current]$ sz /opt/module/hadoop-2.7.2/fsimage.xml