HDFS架构设计: 主从
NN 主 名称节点 扮演老大的角色
SNN 第二名称节点 --》NN 扮演二把手的角色
DN 从 数据节点 扮演小弟的角色
hdfs启动的命令脚本:sbin/start-dfs.sh
:即将linux文件上传到hdfs存储里面,相当于windows上传文件到安装在电脑上的百度云盘上
命令位置:bin/hdfs dfs -ls /
block块
dfs.blocksize : 134217728 / 128M 不满128M也算一个块
例如:
-
1个文件 130M,130/128=1…2M
有两个块128M 2M -
1个文件 260M 260/128=2…4M
有三个文件 2个128M 1个4M -
每个瓶子容量128ML 1碗水260ML 需要3个瓶子
A 128ml
B 128ml
C 4ml
副本数
hdfs-site.xml
下的参数dfs.replication 为1
, 在生产上一般是3 , 指的是一个块的复制数
我们来看看这几个进程分别做什么事?
1. NameNode (NN)
NN
: 是文件系统的命名空间
a
.文件名称b
.文件目录结构c
.文件属性(创建时间 权限 副本数)d
.文件对应哪些数据块—》数据块对应分布到哪些datanode节点上
是种映射关系,叫blockmap,指namenode节点不会持久化存储这种映射关系,因为集群在启动和运行时,datanode会定期发送blockreport 给namenode,以此namenode在内存中动态维护这种映射关系!
作用
:
管理文件系统的命名空间,维护文件系统树,以两种文件永久保存在磁盘。
a
. 命名空间镜像文件fsimage
b
. 编辑日志editlog
2. DataNode (DN)
DN
: 存储数据块和块的校验和
与NN通信: 很多大数据框架都是通过netty做的
a
.每隔3秒发送一个心跳包 (告诉老大我还活着,分布式必须要做的)b
.每10次心跳发送一个blockReport (块报告)
主要作用
: 文件数据块的读写
3. SecondaryNameNode (SNN) 第二
存储: fsimage + editlog
作用: 定期合并 fsimage+editlog
文件为新的 fsimage
,推送给NN,称检查点,checkpoint
检查点参数:
dfs.namenode.checkpoint.period: 3600 (name checkpoint的周期为3600秒),即老大挂掉的话我可以备份一个小时之内的文件,就是这样的一个关系(定期备份)
fsimage
: 镜像文件 文件系统树 全量 14:00
editlog
:操作日志 读写的操作记录 增量 14:40-14:30
那么增量怎么变成全量呢,—> SNN做的事
例如:
SNN在15:00时,会将14:00的fsimage + 14:00~15:00的editlog 合并成一个新的image —> 15:00 fsimage
SNN流程图
4 副本放置策略
数据是以块存储在datanode节点
第一个副本:
假设我提交文件的所在机器就是datanode节点,
那么第一个块就存储在本节点上;
如果不是,就随机挑选一台磁盘不太慢的 cpu不太繁忙的节点上;(老大知道,因为小弟会定时心跳的,会发消息给老大)
如果没有机架的话,另外两块分别就放在该机架的两台不同机器上,如果有另外机架时:
第二个副本:
放置在于第一个副本的不同的机架的节点上
第三个副本:
与第二个副本相同的机架的不同的节点上
5.文件的写流程
假如将ruozedata.log
传到linux机器上的/user/hadoop/day01/
目录下,
hdfs dfs -put ruozedata.log /user/hadoop/day01/
在提交时,
- 1.Client调filesystem.create(path),
与nn rpc通信,check path是否已经存在及有没有权限创建;
假如OK,就创建一个新文件,但是不关联任何的block,
返回一个FSDataOutputStream对象;
假如不OK,就返回错误信息 - 2.Cli ent调用FSDataOutputStream对象的write方法,
将第一个块写给DN1,当第一个块写完,DN1复制块到DN2
当第二个块写完,DN2复制块到DN3,
当第三个块写完,DN3返回一个ack packet确认包给DN2
当DN2收到DN3的ack,发送一个ack给DN1,
当DN1收到DN2的ack,发送一个ack
FSDataOutputStream对象,标识第一个块3个副本全部写完;然后余下的块依次这么写! - 3.当文件写完成,Client调用FSDataOutputStream对象的close方法,关闭输出流,flush缓存区的数据包;
- 4.再调用filesystem.complete方法,告诉NN,我们写完了。