作者:channingbreeze

最近我也在入门大数据相关的基础,这篇文章非常通俗易懂讲解了什么是HDFS,推荐阅读!

建议收藏!

 

 

哇!这就是HDFS!_Java

 

今天是小史生日,为了庆祝自己今年喜提A厂offer,小史叫了二十多个人一起庆生,吕老师、小史姐姐、小林都去啦。

 

到了吃午饭的时间,他们一起去了一家精致的茶餐厅,四人一桌,坐了六桌。

 

所谓众口难调,为了照顾大家,每桌都是自己点菜,小史也是忙前忙后,忙着了解大家都点了些啥,毕竟他要付款。

 

服务员一下子面对六桌,菜有点多,有些菜忘了上哪桌,小史也会告诉他们。

 

哇!这就是HDFS!_Java_02

 

吃着吃着,突然自己桌点的一道芋头排骨汤进了一个苍蝇。

 

哇!这就是HDFS!_Java_03

哇!这就是HDFS!_Java_04

吃完饭,大家都很开心,回家的路上,小史又拉着吕老师问。

 

【饭后】

 

哇!这就是HDFS!_Java_05

哇!这就是HDFS!_Java_06

哇!这就是HDFS!_Java_07

哇!这就是HDFS!_Java_08

【分布式文件系统】

 

哇!这就是HDFS!_Java_09

哇!这就是HDFS!_Java_10

小史:这个我当然知道,文件系统就是用来管理文件的一个系统,比如你今天送我的mac pro,我在命令行敲一个ls,就能看到当前目录的文件。

哇!这就是HDFS!_Java_11

哇!这就是HDFS!_Java_12

哇!这就是HDFS!_Java_13

哇!这就是HDFS!_Java_14

哇!这就是HDFS!_Java_15

哇!这就是HDFS!_Java_16

哇!这就是HDFS!_Java_17

哇!这就是HDFS!_Java_18

哇!这就是HDFS!_Java_19

哇!这就是HDFS!_Java_20

哇!这就是HDFS!_Java_21

哇!这就是HDFS!_Java_22

哇!这就是HDFS!_Java_23

哇!这就是HDFS!_Java_24

哇!这就是HDFS!_Java_25

 

【文件切块】

 

哇!这就是HDFS!_Java_26

哇!这就是HDFS!_Java_27

哇!这就是HDFS!_Java_28

哇!这就是HDFS!_Java_29

哇!这就是HDFS!_Java_30

哇!这就是HDFS!_Java_31

小史:我明白了,原来是这么玩的。大文件切块后分别存储在多台机器,然后提供统一的操作接口,看来分布式文件系统hdfs也是挺简单的。

 

【潜在问题】

 

哇!这就是HDFS!_Java_32

哇!这就是HDFS!_Java_33

哇!这就是HDFS!_Java_34

吕老师:哈哈,这样就太慢了,而且效率很低,是一个o(n)的算法。还有啊,我们刚刚说一个文件分别存在几台机器上,假如其中一台机器坏了,那么这个文件就不能访问了?

哇!这就是HDFS!_Java_35

哇!这就是HDFS!_Java_36

吕老师:那可不对,你可以算一下,假如我有一个1000台机器组成的分布式系统,一台机器每天出现故障的概率是0.1%,那么整个系统每天出现故障的概率是多大呢?

哇!这就是HDFS!_Java_37

哇!这就是HDFS!_Java_38

吕老师:当然有,如果要存储PB级或者EB级的数据,成千上万台机器组成的集群是很常见的,所以说分布式系统比单机系统要复杂得多呀。

 

【hdfs架构】

 

哇!这就是HDFS!_Java_39

哇!这就是HDFS!_Java_40

哇!这就是HDFS!_Java_41

哇!这就是HDFS!_Java_42

哇!这就是HDFS!_Java_43

哇!这就是HDFS!_Java_44

哇!这就是HDFS!_Java_45

哇!这就是HDFS!_Java_46

哇!这就是HDFS!_Java_47

吕老师:小史,你可以把每一桌看作是一个DataNode,每道菜看作是一个文件切块,服务员看作client,你就是NameNode。

哇!这就是HDFS!_Java_48

吕老师:DataNode是真正存储数据的地方,NameNode相当于一个管理者master,它知道每一个DataNode的存储情况,client其实就是那个对外操作的统一接口。

哇!这就是HDFS!_Java_49

哇!这就是HDFS!_Java_50

哇!这就是HDFS!_Java_51

小史:嗯,不需要,他问我就行,我会告诉他。哦,我明白了,client要查询文件的时候,也是先去NameNode里面询问需要找的文件在哪个DataNode上是么?

哇!这就是HDFS!_Java_52

哇!这就是HDFS!_Java_53

哇!这就是HDFS!_Java_54

哇!这就是HDFS!_Java_55

小史:因为其他桌也点了相同的菜,所以我们可以去其他桌吃这个菜啊。等等,我好像知道了,你的意思是hdfs会将数据保存多份是么?

哇!这就是HDFS!_Java_56

吕老师:没错,hdfs在写入一个数据块的时候,不会仅仅写入一个DataNode,而是会写入到多个DataNode中,这样,如果其中一个DataNode坏了,还可以从其余的DataNode中拿到数据,保证了数据不丢失。

哇!这就是HDFS!_Java_57

哇!这就是HDFS!_Java_58

哇!这就是HDFS!_Java_59

哇!这就是HDFS!_Java_60

 

【hdfs读写流程】

 

哇!这就是HDFS!_Java_61

哇!这就是HDFS!_Java_62

哇!这就是HDFS!_Java_63

哇!这就是HDFS!_Java_64

哇!这就是HDFS!_Java_65

哇!这就是HDFS!_Java_66

哇!这就是HDFS!_Java_67

小史:没问题啊,读取文件大概分为这几个步骤:

1、client询问NameNode,我要读取某个路径下的文件,麻烦告诉我这个文件都在哪些DataNode上?

2、NameNode回复client,这个路径下的文件被切成了3块,分别在DataNode1、DataNode3和DataNode4上

3、client去找DataNode1、DataNode3和DataNode4,拿到3个文件块,通过stream读取进来

哇!这就是HDFS!_Java_68

哇!这就是HDFS!_Java_69

哇!这就是HDFS!_Java_70

哇!这就是HDFS!_Java_71

哇!这就是HDFS!_Java_72

小史:文件写入也是类似的吧?分为这几个步骤:

1、client先将文件分块,然后询问NameNode,我要写入一个文件到某个路径下,文件有3块,应该怎么写?

2、NameNode回复client,可以分别写到

DataNode1、DataNode2、DataNode3、DataNode4上,记住,每个块重复写3份,总共是9份

3、client找到

DataNode1、DataNode2、DataNode3、DataNode4,把数据写到他们上面

哇!这就是HDFS!_Java_73

哇!这就是HDFS!_Java_74

哇!这就是HDFS!_Java_75

哇!这就是HDFS!_Java_76

哇!这就是HDFS!_Java_77

哇!这就是HDFS!_Java_78

由于之前吕老师专门给小史讲过mysql的专题,所以小史对mysql的理解还是比较深的。

哇!这就是HDFS!_Java_79

哇!这就是HDFS!_Java_80

哇!这就是HDFS!_Java_81

哇!这就是HDFS!_Java_82

哇!这就是HDFS!_Java_83

哇!这就是HDFS!_Java_84

 

【SecondNameNode】

 

哇!这就是HDFS!_Java_85

(注:元数据metadata是指描述数据的数据,这里指描述文件的数据,比如文件路径,文件被分为几块?每个块在哪些DataNode上等)

哇!这就是HDFS!_Java_86

哇!这就是HDFS!_Java_87

哇!这就是HDFS!_Java_88

小史:哦,原来是这个问题啊,简单啊,既然文件的元数据这么重要,那可以持久化到硬盘上啊,重启之后再从硬盘把数据恢复到内存不就行了。

哇!这就是HDFS!_Java_89

哇!这就是HDFS!_Java_90

小史:对哦,这么说是要写,这块我确实欠考虑,写入流程应该还要考虑这个,但是如果写硬盘,还得找到那个文件的元信息的位置,再进行插入或修改,这样会不会很慢啊?或者我直接把整个文件系统的元数据写到硬盘,省去查找时间,会不会好点?

哇!这就是HDFS!_Java_91

吕老师:小史,这次你考虑得很全面,如果每次写文件都要再去寻找元数据位置,或者把所有元数据在硬盘中同步一份,写入的效率将大大受到影响,所以hdfs并不是这样做的。

哇!这就是HDFS!_Java_92

哇!这就是HDFS!_Java_93

吕老师:hdfs会把操作日志记录下来,存在editlog中,下次重启的时候,先加载editlog,把所有的日志都回放一遍,达到重启前的状态。

哇!这就是HDFS!_Java_94

哇!这就是HDFS!_Java_95

哇!这就是HDFS!_Java_96

哇!这就是HDFS!_Java_97

小史:如果NameNode运行了很久,文件操作很多的话,editlog就会很大吧?那么下次NameNode重启的时候,需要进行大量操作的恢复,启动时间就会非常长。

哇!这就是HDFS!_Java_98

吕老师:哈,小史,你的思维越来越活跃了,没错,这确实是一个大问题,不过hdfs的设计者也想到了这个问题。你看看之前hdfs的架构图,里面有一个SecondNameNode,就是用来解决这个问题。

哇!这就是HDFS!_Java_99

哇!这就是HDFS!_Java_100

吕老师:刚刚其实只说了一半,NameNode确实会回放editlog,但是不是每次都从头回放,它会先加载一个fsimage,这个文件是之前某一个时刻整个NameNode的文件元数据的内存快照,然后再在这个基础上回放editlog,完成后,会清空editlog,再把当前文件元数据的内存状态写入fsimage,方便下一次加载。

哇!这就是HDFS!_Java_101

哇!这就是HDFS!_Java_102

哇!这就是HDFS!_Java_103

哇!这就是HDFS!_Java_104

哇!这就是HDFS!_Java_105

 

【hdfs的HA】

 

哇!这就是HDFS!_Java_106

小史:我也想到一个问题,NameNode对于hdfs来说是非常重要的,假如NameNode挂了,谁来接替它的工作呢?是SecondNameNode吗?

哇!这就是HDFS!_Java_107

吕老师:哈,你这样想可就大错特错啦,这是初学hdfs很容易被误导的一个地方,NameNode挂了, SecondNameNode并不能替代NameNode,所以如果集群中只有一个NameNode,它挂了,整个系统就挂了。

哇!这就是HDFS!_Java_108

哇!这就是HDFS!_Java_109

吕老师:没错,hadoop2.x之前,整个集群只能有一个NameNode,是有可能发生单点故障的,所以hadoop1.x有本身的不稳定性。但是hadoop2.x之后,我们可以在集群中配置多个NameNode,就不会有这个问题了,但是配置多个NameNode,需要注意的地方就更多了,系统就更加复杂了。

哇!这就是HDFS!_Java_110

哇!这就是HDFS!_Java_111

吕老师:这和系统的设计理念是有关系的,虽然hadoop1.x存在一个NameNode单点,但是它大大简化了系统的复杂度,并且数据量在一定范围内时,NameNode并没有这么容易挂,所以那个时代是被接受的。但是随着数据量越来越大,这个单点始终是个隐患,所以设计者不得不升级为更加复杂的hadoop2.x,来保证NameNode的高可靠。

哇!这就是HDFS!_Java_112

哇!这就是HDFS!_Java_113

吕老师:俗话说一山不容二虎,两个NameNode只能有一个是活跃状态active,另一个是备份状态standby,我们看一下两个NameNode的架构图。

哇!这就是HDFS!_Java_114

哇!这就是HDFS!_Java_115

哇!这就是HDFS!_Java_116

吕老师:因为active的NameNode挂了之后,standby的NameNode要马上接替它,所以它们的数据要时刻保持一致,在写入数据的时候,两个NameNode内存中都要记录数据的元信息,并保持一致。这个JournalNode就是用来在两个NameNode中同步数据的,并且standby NameNode实现了SecondNameNode的功能。

哇!这就是HDFS!_Java_117

哇!这就是HDFS!_Java_118

吕老师:active NameNode有操作之后,它的editlog会被记录到JournalNode中,standby NameNode会从JournalNode中读取到变化并进行同步,同时standby NameNode会监听记录的变化。

哇!这就是HDFS!_Java_119

哇!这就是HDFS!_Java_120

哇!这就是HDFS!_Java_121

(注意,hadoop2.x如果只部署一个NameNode,还是会用SecondNameNode)

 

【hdfs优缺点

 

哇!这就是HDFS!_Java_122

哇!这就是HDFS!_Java_123

小史:可以,hdfs可以存储海量数据,并且是高可用的,任何一台机器挂了都有备份,不会影响整个系统的使用,也不会造成数据丢失。

哇!这就是HDFS!_Java_124

哇!这就是HDFS!_Java_125

哇!这就是HDFS!_Java_126

吕老师:哈哈,这到不是主要的。小史,你想想吃饭场景,如果每一桌都点份量小的菜,但是点很多份,那你还能清楚记住哪桌点哪些吗?

哇!这就是HDFS!_Java_127

小史:我想我可能记不住了,你的意思是每一个小文件都有元信息,它们都存在NameNode里面,可能造成NameNode的内存不足?

哇!这就是HDFS!_Java_128

哇!这就是HDFS!_Java_129

哇!这就是HDFS!_Java_130

哇!这就是HDFS!_Java_131

哇!这就是HDFS!_Java_132

哇!这就是HDFS!_Java_133

小史:如果要随机写,由于文件被切块,需要先找到内容在哪个块,然后读入内存,修改完成之后再更新所有备份,由于一个块并不小,这个效率会很低吧?

哇!这就是HDFS!_Java_134

哇!这就是HDFS!_Java_135

哇!这就是HDFS!_Java_136

哇!这就是HDFS!_Java_137

 

【笔记

 

哇!这就是HDFS!_Java_138

哇!这就是HDFS!_Java_139

小史在吕老师的课堂上,赶紧把这次的笔记记录下来。

 

1、hdfs是一个分布式文件系统,简单理解就是多台机器组成的一个文件系统。

 

2、hdfs中有3个重要的模块,client对外提供统一操作接口,DataNode真正存储数据,NameNode协调和管理数据,是一个典型的master-slave架构。

 

3、hdfs会对大文件进行切块,并且每个切块会存储备份,保证数据的高可用,适合存储大数据。

 

4、NameNode通过fsimage和editlog来实现数据恢复和高可用。

 

5、hdfs不适用于大量小文件存储,不支持并发写入,不支持文件随机修改,查询效率大概在秒级。

 

最后

哇!这就是HDFS!_Java_140