本文是在学习GFS(The Google File System,谷歌文件系统)后对存在中心节点的分布式文件系统的一些宏观的总结与思考。本文并无太多关注GFS的细节实现,而是侧重在GFS的基础上进行概括和进一步探究。redis
关于这个问题,百度百科是这么说的缓存
计算机经过文件系统管理、存储数据,而信息爆炸时代中人们能够获取的数据成指数倍的增加,单纯经过增长硬盘个数来扩展计算机文件系统的存储容量的方式,在容量大小、容量增加速度、数据备份、数据安全等方面的表现都差强人意。分布式文件系统能够有效解决数据的存储和管理难题.....安全
更深层次而言,纵观人类软件系统的发展史,业务的爆炸不断驱动着技术飞速发展。随着接入网络的人数愈来愈多,软件系统也须要不断升级以可以知足海量用户的并发请求。而软件系统的升级过程,就是不断挑战性能瓶颈的过程。从这个角度出发,用户的增多必然会致使单机没法容纳须要持久化的数据,即便采用增长硬盘个数的方式将单机不断扩大,在达到必定规模后,查找有关数据的操做会变得很是缓慢,掣肘总体软件性能的提高。为了解决这些问题,分布式文件系统几乎是必经之路,也是惟一选择。服务器
最终目标只有一句话:用户使用分布式文件系统,感受就像在使用单机文件系统同样。网络
而限制这一最终目标达成的最主要因素,就在于网络和机器都不是百分百的可靠。系统运行期间网络的一点点波动、时延,或者机器的一点点故障,都有可能形成用户没法看到或看到不符合预期的结果。并发
本文的系统模式是存在中心节点的分布式文件系统模型。app
谷歌文件系统(The Google File System)的系统模型就是很是经典的下图:负载均衡
我将该系统提取成为了一个较为通用的抽象模型:分布式
在该模型中,分布式文件系统主要有master部分和server部分组成。master部分须要承载用户的访问请求并对所需资源进行定位,出于负载均衡方面的考虑通常不存储文件;server部分是真正用来存放文件数据的部分。不一样的分布式文件系统对master部分和server部分的可能会有不一样的具体实现,但功能大致类似。性能
以该抽象模型为例,用户想在系统中查询文件的工做流程大体以下:
client向系统的master发送查询请求,请求中包含须要查询的文件的信息。
master获取client须要所需内容在server中的位置坐标,并返回client。
client根据查询内容的位置坐标找到相应的server节点,并发送查询请求。
server将查询的内容返回给client,查询过程完毕。
上述流程以查询为例,增长、修改、删除的操做也相似。
须要注意的是,分布式文件系统也能够采用以下模型:
但该模型中,master还须要承担向server发送文件请求并接受文件内容的任务,在并发场景下I/O负担会加剧到不可思议,master极易成为系统的性能瓶颈,所以并不可取。
这部分将参照上文的第三部分,以GFS系统为参考,但不只限于GFS系统,逐条进行解决方案说明与分析:
大容量。系统中的server部分存在多个存储节点知足系统大容量的需求,对应GFS中存在多个chunkserver。存储节点越多,系统的容量越大,但也会相应的提升系统的运营成本,给系统性能带来更大的挑战。
支持并发访问。系统对并发的支持主要体如今两个方面:第一.master部分能够支持多个client并发查询文件所在的server坐标。第二.server能够支持多个client并发的操做数据。固然,并非全部的分布式文件系统都须要同时知足这两种并发,例如,master彻底能够采用相似生产者-消费者的方式,client的查询请求加入master队列,而后master逐条取出并处理。
持久化。master和server都会将自身的数据保存到磁盘,server天然没必要多说,会持久化存储的文件数据,master部分须要持久化的东西较为复杂,不一样的分布式文件系统持久化的内容也存在差别,我理解对于大多数系统而言,master至少应该持久化两部份内容:1)文件与server的信息,如二者的命名空间、映射关系等 2)server中各个节点的最新版本id,节点版本id存在的必要是为了知足一致性。
值得注意的是,因为GFS采用了给节点头分配租约(lease)的方式,所以并不须要持久化server当前的主节点(primary)。另外,GFS的持久化方式是日志(log)+checkpoint,checkpoint是为了防止日志随着时间的增加膨胀得太大。这种log+checkpoint的方式很是不错,也是redis等经常使用软件中采用的方式。
高可用。最多见的方式就是冗余备份了,在GFS系统中高可用主要体如今两个方面:
1)master的高可用。master的操做日志、存档等数据会被复制到多台机器,master故障时,监控设备会在冗余机器上启动新的master进程,并采用更新DNS的方式引导client访问新的master,保证系统持续可用。另外,GFS还提供了阴影master,阴影master能在master故障时提供只读服务,可是阴影master的数据一般会落后1秒左右。
2)server的高可用。每份数据默认有3个chunkserver进行备份,固然,3个只是默认值,会根据不一样文件的访问热度进行灵活调整,避免3个chunkserver没法应对热点数据的请求而成为系统瓶颈。在冗余备份时,须要考虑不一样的server节点放置在不一样的位置,如GFS会将同一文件不一样的备份机放到不一样的机架上,避免整个机架故障形成系统瘫痪,现在,大型系统须要考虑备份不只放在不一样的机架,甚至要越远越好,即“异地容灾备份”。
一致性。多备份解决了高可用问题,但同时会引入一致性问题,不一样的备份所处地理距离越远,安全性越高,但一致性越困难。一致性产生的最根本缘由就是网络的不可靠性,若是存在绝对可靠的网络,那也不会存在一致性的难题,虽然随着现在网络的发展,网络出现不可靠的几率愈来愈低,但在设计分布式系统时,仍然须要考虑网络每时每刻都存在不可靠的可能性,注意,必定要假设每时每刻均可能发生网络故障,这对系统的一致性是很是巨大的挑战。
在GFS系统中,大部分文件发生变化都是由于执行了追加(append)操做,而一般不会发生内容的覆盖。GFS保证append操做一致性采用的松弛一致性模型:append操做会发送给多个备份中实时的primary节点,由primary节点指定执行顺序,并通知其余节点。在其余节点所有执行成功后,primary节点会告诉client执行成功了,不然只要有一个节点执行失败,primary就会告诉client失败了,须要client从新发起操做请求。这个过程当中,若是执行失败了,该过程并不会删除已经append成功的节点中的文件信息,这显然会形成没必要要的空间浪费,这也是我认为GFS能够改进的点之一,好比采用两阶段提交或三阶段提交的方法。另外,若是GFS同时存在读和写,那么读的线程有可能会读到没有写完整的数据,这也是GFS作的不够严谨的地方之一,这一问题能够采用写时复制、读的过程当中检查是否读到了正在写入的位置等方式进行改进。
低时延。缓存是减小时延很是有效的手段,可是在缓存的同时须要考虑缓存与磁盘数据的一致性问题。GFS的客户端会缓存一些chunk句柄或对应的chunkserver的位置(这部分信息一般不会变化,所以不会存在复杂的一致性问题),但并不会缓存文件数据,由于该系统的业务场景下文件重用率不高,缓存文件内容的收益较小。在chunkserver中,chunk被存储为本地文件,此时Linux会提供操做系统层面的缓存,GFS没有进行额外的缓存处理。
另外,GFS还采用了特殊的方式缩短查询请求的时延:在查询的时候,不是必须通过primary节点,而是根据距离、负载等因素选择可以最快响应的server节点查询。
可拓展(具备伸缩性)。系统的可拓展性主要考虑两个方面:
1)master的可拓展性。master的可拓展方式主要有将单机master拓展为多机master,具体实现可采用主从机制。可是在GFS系统中,并无对master进行拓展。这主要是由于,GFS以较大的数据块存储文件数据(每一个chunkserver保存64M),这就可以尽可能减小master保存的server信息,并减小client与master交互的次数,同时,client在查询有关文件信息的时候,颇有可能会在同一次查询中额外询问一些后续的chunk信息,master有时也会主动告知client一些后续额外chunk信息,client一样会缓存这些信息,这在业务主要是顺序读的场景中,几乎不须要增长额外的成本就很是有效的减小了client与master交互的频次,减小了master的负担,若是采用这些方法就可以知足GFS的业务需求,那天然没必要多此一举去增长多机master。
可是若是考虑更为长远和大规模的场景,随着server的增长,单机master必然会成为系统的瓶颈,系统的升级就是不断与瓶颈作斗争,所以,在必定业务规模下,master的拓展也必须在软件设计之初就加以考虑。
2)server的可拓展性。server的可拓展性指的是随着系统存储文件数量的不断增大,server节点不够用时,须要补充新的server节点,此时须要新节点向master进行注册,master即可以给新节点分配数据。master在给新节点分配数据时,能够借助新节点进一步实现系统的负载均衡,但也应该注意,不要为了缓解负荷较重节点的压力一会儿将过多的热点数据分配给新节点,这会形成新节点短时间内负载忽然增大。
本文是在对GFS学习后,阅读了一些相关文章,对存在中心节点的分布式文件系统进行的概括,从分布式文件系统存在的意义、终极目标提及,依据本身抽象出来的分布式文件系统通用模型分析了如何知足分布式文件系统应该知足的要求。
本文不少内容都是以GFS的实现方式为例,对GFS的优缺点进行了简单的探讨。文中提到的GFS能够改进的点,只是针对我认为较为通用的场景,并无过多的考虑GFS的业务场景,所以可能在特定业务场景下并不成立。
因为本人水平有限,不免会存在错误纰漏,欢迎你们与我交流,欢迎批评指正!谢谢!