谷歌分布式文件系统Google file system (GFS)

谷歌在2003到2006年间发表了三篇论文,《The Google File System》《Bigtable: A Distributed Storage System for Structured Data》《MapReduce: Simplified Data Processing on Large Clusters》介绍了Google如何对大规模数据进行存储和计算的。

简单地讲,GFS解决了海量超大文件的分布式存储问题BigTable解决了实时在线应用的海量数据该如何存储的问题MapReduce解决了海量数据并发计算的问题

这三篇论文开启了工业界的大数据时代,被称为Google技术的三驾马车。本文介绍GFS的相关内容,不仅是论文的阅读笔记,也讲一讲论文解决的问题和设计思路。

我们在计算机硬盘上是如何保存一个文件的呢?

硬盘被分为多个Block, 1个Block = 1024字节。

然后有一个元数据Metadata,其中FileInfo记录文件的名称 创建时间 大小 等信息,Index记录文件存储在哪个Block里,如果文件占用多个Block,就记下存储在哪几个Block里面。DiskOffset记录了文件在硬盘上的偏移量,方便更好的定位文件的具体位置。

Google用64MB的Chunk来代替Block,以更好的存储大文件,减少元数据的存储空间。

然后以Master + ChunkServer的分布式架构,来将文件存储在多个机器上。

但是,如果Master的Index信息里记载所有ChunkServer对所存数据的增删查改行为,ChunkServer每一次数据存储在本地硬盘的变化都要和Master通讯汇报的话,Master的通信消耗就太大了。

Google就让Master只记录文件存储在哪些Chunk 上,每个Chunk在哪个ChunkServer上,而具体在硬盘上的位置留给ChunkServer本地的Index来记录。这样既减少了Master 的元数据信息的大小,还减少了Master 和ChunkServer的通信消耗。

那么存储的数据损坏或者丢失了怎么办呢?

提前复制数据,制造多个副本,存储在不同的地方。

Google把数据的每个Chunk都存储3份,分别在3个不同的ChunkServer上。至于为什么这个数字是3呢,这是google存储性能上做了考量而抉择的方案。存储太多份的话,数据存储会变的冗杂,存储需要的机器代价比较大。而只存储2份的话又不足以预防偶然情况的发生。

那么Google如何选择Chunk副本存储在哪个ChunkServer上的呢?

 其中一个原则是跨中心跨机架2+1。整个GFS分布式存储架构基于数据存储服务器的位置组成了一个树形结构,Google把数据存储在不同城市,每个城市是一个树的不同分支节点,而城市里有多个存储中心,每个存储中心有多个存储机器。对于Chunk的3个副本,Google会基于跨中心跨机架的原则,把数据存储在2不同分支的中心上,而同一个分支的2份副本被存储在不同的机架上,以此来预防一个大规模的数据崩溃发生时会丢失所有副本。

另一个原则是热点平衡。Master会统计ChunkServer的可用空间和网络传输带宽,以及每个数据Chunk 的访问频率。基于热点平衡原则,会优先选择空闲的ChunkServer来存储新的Chunk副本。当某个Chunk的副本访问频率特别高时,Master会把这个Chunk的副本复制到不相邻的空闲ChunkServer,以方便另一区域(距离更近)更快地访问这个热点数据,而不会拥挤。

那么如何发现ChunkServer挂掉了呢?

 就类似于活人的心跳检测一样,每个ChunkServer会定期向Master发送“存活”的时间戳。当Master发现某个ChunkServer很久没有消息了,就会让临近的服务器发消息询问,如果没有回复,就启动这个ChunkServer上存储的所有数据的恢复流程。

那么Chunk的数据损坏是如何被发现的呢?

 Google将每个大Chunk分为固定个数的小Block,每个组成的Block都有一个检验和(检验和具体算法在计算机课程比如计算机网络传输中有学过,用以检测数据和原来是否一致),而每个Chuck都有一个元数据记载着组成的每个Block检验和是多少,每次读取数据时执行对当前Block检验和的验证操作。

那么如何恢复损坏的Chunk呢?

当ChunkServer验证Chunk的检验和时,发现不一致,ChunkServer会向Master求助,发送Chunk损坏的信息给Master。Master记载着Chunk的副本在哪3个服务器上,会把另两个ChunkServer发送给请求恢复损坏Chunk的服务器。而这个服务器会直接通信2个副本服务器,请求他们把自己损坏Chunk的副本传输过来。当2份副本一致时,恢复损坏的Chunk。当2份Chunk不一致时,同时保留2份,等待Master之后的处理。

那么如何读GFS呢?

GFS客户端,也就是应用程序端,会向GFS Master询问想要的文件名称。GFS Master有一个namespace的数据结构,用树形结构记载了目标文件的路径和存储地址。GFS Master会确认数据权限请求许可并返回数据的地址。GFS客户端在拿着权限许可和地址向ChunkServer请求目标数据文件,ChunkServer会把对应的数据文件发送给GFS客户端

那么如何写GFS呢?

GFS客户端会向GFS Master询问数据所在的服务器,GFS Master会返回一个主服务器和2个副本服务器。然后GFS客户端会把数据发送给临近的服务器,由服务器之间来传输数据副本,而不是直接发送3份数据副本,这涉及数据一致性和通信问题。而收到的数据也不是立刻写入硬盘,而是先缓存起来,以防数据传输出了问题导致写入硬盘变为无用功。等3个服务器的确认收到数据后,由主服务器发号施令统一写入硬盘,3个服务器都完成写入操作后,由主服务器向GFS客户端发送完成信息

 

posted @ 2023-06-17 19:34  ImreW  阅读(225)  评论(0编辑  收藏  举报