目录
HDFS分布式文件存储,通常是将1个文件拆分成多个部分,然后分别发送到不同服务器节点上。


问题:不同的文件大小不一,粗暴的拆分然后放到服务器不同节点,会导致各个部分的大小也不一样,不利于统一管理。
解决办法:设定统一的管理单位,block块。
这样可以将文件分成多个Block块,不同的Block块存入对应服务器。
举例说明
某个文件大小1G,那么理论上可以分为4个Block块。
如果集群有三台服务器,那么某台服务器放2个Block块,然后其他两台服务器各1个Block块。
如果不备份,假如某个块损坏了,那么就会导致整个文件不可用。
所以,副本机制是保障数据安全的非常重要的机制。


默认的HDFS文件的副本数量就是3个。
当然这个值可以修改,具体可以在hdfs-site.xml中配置如下属性
- <property>
- <name>dfs.replicationname>
- <value>3value>
- property>
这个属性默认是3,一般情况下,我们无需主动配置(除非需要设置非3的数值)
如果需要自定义这个属性,请修改每一台服务器的hdfs-site.xml文件,并设置此属性。
如果不加限制,我们创建的文件或者上传的文件,默认副本数就是上面设置的值。
但是单次文件上传,我们也可以指定某个文件拥有多少个副本。
hadoop fs -D dfs.replication=2 -put test.txt /tmp/
对于已经存在HDFS的文件,修改dfs.replication属性不会生效,如果要修改已存在文件可以通过命令
hadoop fs -setrep [-R] 2 path
如上命令,指定path的内容将会被修改为2个副本存储。
-R选项可选,使用-R表示对子目录也生效。
我们要查看详细的文件副本数信息,可以通过如下命令:
hdfs fsck path [-files [-blocks [-locations]]]
fsck可以检查指定路径是否正常
-files可以列出路径内的文件状态
-files -blocks 输出文件块报告(有几个块,多少副本)
-files -blocks -locations 输出每一个block的详情

默认情况下,block块的大小是256MB,当然我们也可以修改。
- <property>
- <name>dfs.blocksizename>
- <value>268435456value>
- <description>设置HDFS块大小,单位是bdescription>
- property>
NameNode作用:管理Block块。
在hdfs中,文件是被划分了一堆堆的block块,那如果文件很大、以及文件很多,Hadoop是如何记录和整理文件和block块的关系呢?
答案就在于NameNode。
NameNode基于一批edits和一个fsimage文件的配合完成整个文件系统的管理和维护。
edits文件,是一个流水账文件,记录了hdfs中的每一次操作,以及本次操作影响的文件其对应的block。




将全部的edits文件,合并为最终结果,即可得到一个FSImage文件

小结
NameNode基于edits和FSImage的配合,完成整个文件系统文件的管理。
1. 每次对HDFS的操作,均被edits文件记录
2. edits达到大小上线后,开启新的edits记录
3. 定期进行edits的合并操作
4. 重复123流程
对于元数据的合并,是一个定时过程,基于:
dfs.namenode.checkpoint.period,默认3600(秒)即1小时
dfs.namenode.checkpoint.txns,默认1000000,即100W次事务
只要有一个达到条件就执行。
检查是否达到条件,默认60秒检查一次,基于:
dfs.namenode.checkpoint.check.period,默认60(秒),来决定。
对于元数据的合并,还记得HDFS集群有一个辅助角色:SecondaryNameNode吗?

没错,合并元数据的事情就是它干的
SecondaryNameNode会通过http从NameNode拉取数据(edits和fsimage)
然后合并完成后提供给NameNode使用。

1. 客户端向NameNode发起请求
2. NameNode审核权限、剩余空间后,满足条件允许写入,并告知客户端写入的DataNode地址
3. 客户端向指定的DataNode发送数据包
4. 被写入数据的DataNode同时完成数据副本的复制工作,将其接收的数据分发给其它DataNode
5. 如上图,DataNode1复制给DataNode2,然后基于DataNode2复制给Datanode3和DataNode4
6. 写入完成客户端通知NameNode,NameNode做元数据记录工作
关键信息点:
NameNode不负责数据写入,只负责元数据记录和权限审批
客户端直接向1台DataNode写数据,这个DataNode一般是离客户端最近(网络距离)的那一个
数据块副本的复制工作,由DataNode之间自行完成(构建一个PipLine,按顺序复制分发,如图1给2, 2给3和4)

1、客户端向NameNode申请读取某文件
2、 NameNode判断客户端权限等细节后,允许读取,并返回此文件的block列表
3、客户端拿到block列表后自行寻找DataNode读取即可
关键点:
数据同样不通过NameNode提供
NameNode提供的block列表,会基于网络距离计算尽量提供离客户端最近的
这是因为1个block有3份,会尽量找离客户端最近的那一份让其读取。
最难不过坚持,继续下一关~✨