这是《漫谈分布式系统》系列的第 3 篇,预计会写 30 篇左右。每篇文末有为懒人准备的 TL;DR,还有给勤奋者的关联阅读。关注公众号「漫谈大数据」(ID: sobigdata),听我娓娓道来。也欢迎转发朋友圈分享给更多人。
1
系列开篇我们说到,分布式系统的初衷,是想要解决两大问题:
存不下
算的慢
今天这篇,我们就一起看下第一点,分布式文件系统是怎样解决存不下的问题的。
首先,思考一个问题:为什么会存不下?
是某一个文件太大了吗?通常不是。现在我们用的服务器,少则几十 GB,多则上百 TB 的硬盘,很少会有一个文件这么大。毕竟一部 720P 的电影才几 GB。
通常是很多个文件累积的总量太大了。
所以很自然的思路就是,以文件为单位,分散放到很多台服务器上去。
但是这个办法还不够好,很容易碰到问题,比如:
数据分布不均衡
文件大小差距会很大,这就导致有些服务器上会存很多数据,还有些则相对较少。
当然,我们可以不要这么笨,分配的时候把当前文件大小和所有服务器上剩余空间做下比较,然后选择最合适的服务器放上去。
但是这样就会导致另一个问题:
空间分配不够灵活
再试想这样一种情况。现在有 2 台机器 A 和 B,分别剩下 200GB 和 100GB 空间,然后来了个 80GB 的文件,很显然应该放到 A 机器上。但是如果这个文件之后又来了个 150GB 的文件呢,就放不下了。
而如果一开始我们能知道后面有个 150GB 的文件要来,那就可以把第一个文件放到 B,第二个文件放到 A。但这是预测未来,做不到的。
这两个问题,本质上都是因为不均衡导致的,这个不均衡体现在服务器剩余空间和待存储的文件大小两方面。
那怎么解决这个不均衡的问题呢?
仍然是系列第一篇里我们提到的分治的思想。
先打散,各自处理完,然后再合并结果。
服务器存储空间不均衡的问题,操作系统早就解决了。大家肯定都听说过 block 或者 page,我们去读写文件的时候,操作系统都是以这样的固定大小去处理的。
而待存储的文件大小不均衡,就需要应用层自己去处理了。
既然不均衡是由于文件大小不一致导致的,那就强制让它一致起来。把文件拆成若干个同样大小的单元,然后把这些单元分散存储到不同的服务器上去,需要访问文件的时候,再去各个服务器上拿过来合在一起。
这样,以固定大小的单元,而不是文件为单位去存储文件,理论上,只要硬件资源足够,存不下的问题就很好的解决了(当然只解决了最基本的问题,还会很多其他难题,后续的文章会一一说到)。
2
HDFS 就是按照这个思路去做的。
固定大小的单元叫做 block
存储这些 blcok 并提供读写功能的服务叫做 DataNode
一个文件由哪些 block 组成,又存储哪些服务器上,这个信息叫做元数据
存储这些元数据并提供读写操作的服务叫做 NameNode
简化后的结构如下图所示:
3
下面看下写数据的过程是怎样的。
当然,这里我们看的也只是简化后的流程:
Client 找 NameNode 申请,我现在要写一个文件。NameNode 做完诸如权限检查之类的前置工作后,告诉 Client,可以的我准备好了。
Client 收到 NameNode 的确认请求后,进入一个循环,直至数据写完:
向 NameNode 申请一个 block,NameNode 根据一定规则选出合适的 DataNode 后,告诉 Client
Client 向 NameNode 指定的 DataNode 发送数据,DataNode 接受数据并写到本地
4
再来看看读数据的过程。
同样,是简化后的过程:
Client 像 NameNode 询问,我要读一个文件,告诉我它在哪里。NameNode 做完诸如权限检验之类的检查后,返回对应文件的元信息,一共有哪些 block,分别保存在哪些 DataNode 上。
Client 接收到文件元信息后,去对应的 DataNode 请求对应的 block 数据,最后拼在一起就是完整的文件内容。
5
试想一个图书馆的场景。
馆里新进了一批书,就需要先到管理员(一个人或者一个系统)那里登记,管理员会分配应该放到哪一个书柜上。
用户要借书,也需要到管理员那里询问,管理员告诉他这本书在哪个书柜,用户就能很快找到。
如果新买的书没地方放了,只需要买几个书柜,然后在管理员那里登记下就行。只要有足够的钱买书柜,就不用担心书没地方放。
很容易理解,NameNode 就充当了类似图书馆管理员的角色,而 DataNode 就是书架。
很容易看到,无论是写,还是读,这样的设计都足够简单而有效。
当然,这篇文章只解决了最基础的问题。在一切顺利的理想情况下,我们不用再担心新书没地方放了。
但现实情况总是不理想的。
比如,如果管理员生病(管理系统宕机)了呢?
如果有个书柜年久失修垮掉了呢?
这些问题,在后续的文章里面,都会一一讲到。请大家扫码关注公众号,不要错过。
TL;DR
数据存不下通常都是文件总空间太大,而不是个别文件太大。
以文件为单位分散存储可以一定程度解决存不下,但由于文件大小的不均衡,很快会遇到瓶颈。
经典的分治法可以很好的解决不均衡的问题,大小不一样的文件都拆分成一样大的单元,再以单元为单位分散出去。
HDFS 以 block 为单位拆分文件,DataNode 负责提供 block 的读写,NameNode 负责保存文件和 block 的对应关系,block 和机器的对应关系等元信息。
所有对文件的读和写操作,都先经过 NameNode 处理元数据,再和对应的 DataNode 发生具体的数据交换。
存的下还不够,还要存的好。毕竟,海量数据带来的就是海量的成本。下一篇,我们就一起看下海量数据的存储治理。
虽然很忙,但这个系列我一定会坚持写完。请大家关注公众号,点右下角的在看,分享到朋友圈,这些都是对我莫大的鼓励。
关联阅读
原创不易
关注/分享/赞赏
给我坚持的动力
![640?wx_fmt=jpeg](https://i-blog.csdnimg.cn/blog_migrate/5ed1a58152e7c963a5a6b713cb90607f.jpeg)
点在看,给大家好看
![640?wx_fmt=gif](https://i-blog.csdnimg.cn/blog_migrate/c0b593e35e3ceca396a074a8ef093d59.gif)