这一篇之所以命名分离之后,是因为当我们前面负载均衡的介绍,假设每台实际服务器都是相同的,就是拥有相同的文件和程序。实际上如何要实现的每台实际服务器都有相同的资源呢?这篇我们将分享网络共享、内容分发同步和分布式文件系统。
网络共享
这个方式就是把资源放到一个网络上的服务器,多个实际请求处理服务器都可以以相同的方式访问到这些资源,像我们常见的数据库服务器,我们的程序都可以网络的方式访问数据库,获得数据后,生成HTML,返回给用户,还有我们前面关于缓存中提到的缓存服务器,这里我们再介绍下文件共享系统。
文件共享系统让你不必考虑网络访问和传输的细节,你可以像访问本地文件系统一样访问网络上其它服务器文件系统上的文件。文件共享系统并不是通常意义上的磁盘文件系统,它不能用于存储和管理磁盘数据,而只是定义了文件在网络传输过程中的组织格式和传输协议,当我们实际服务器应用共享文件系统规定的方式访问一个文件时,内部实际要进行两次格式的转换,分别发生在从实际文件服务器进入网络时和从网络离开到达实际处理服务器时。
常用的文件共享系统有NFS和Samba,其中NFS主要用于UNIX/Lniux平台,而Samba设计初衷是将UNIX/Linux的文件映射到Windows的网上邻居中,来实现UNIX/Linux到Windows的文件共享,同时也支持UNIX/Linux平台之间的文件共享。当然还有其它的系统,我们可以根据实际需求和各系统的特性来决定采用哪个。
虽然它解决了我们文件的访问问题,但是我们必须明白:不同于磁盘IO,通过文件共享系统,文件服务器本身磁盘的吞吐率上限、并发处理能力和网络带宽都成了制约我们系统的重大因素。除此之外,目前为止它还是一个依赖单点的解决方案,如果大量共享文件存在,我们必须考虑其它方案,如将文件复制到更多的服务器,建立多级冗余。
内容分发和同步
由于上段提到的原因,我们要把文件复制到各个服务器,让服务器访问本地磁盘的文件来处理HTTP请求,我们一般通过两种方式来实现复制,主动分发和被动同步。
所谓主动分发,就是更新的时机在有文件改动时,如用户上传了新的图片,这时应用程序就会把此图片同步到其它相同功能的服务器。如果相同服务器太多,或者部署在不同区域,我们可以通过多级分发来解决这些问题,将任务分离到不同的机器上,发起服务器在同步几个结点之后,几个结点服务器再负责把该集群内其它服务器的文件同步。在php中我们有SSH、SFTP、WebDAV来实现。如果文件操作过于频繁,实时的文件同步的请求就可能是一个灾难,服务器每时每刻都要去处理文件的分发。
被动同步就是文件的一端主动向文件服务器发起请求,如果两者存在差异,进行有选择的更新,从而保证各服务器文件一致。linux下rsync工具可以出色的完成此项工作,我们可以设置更新的时间间隙,每一隔一段时间去同步下,似乎一定程度减少了服务器压力,但是如果更新的文件过多,磁盘扫描文件来和本地磁盘文件进行对比的开销将是非常的大。不过书中提到一种方法来减少扫描的开销,启用linux内核的inotify模块,通过它监视文件的动静,如果任何文件修改时间变化后,发出事件通知,这样我们就可以编写程序来更新该文件的上级目录的修改时间,直到根目录。这样扫描时,从最早时候就能得知是否有文件改动,没有改动时及时退出扫描。
分布式文件系统
通过以上方法,我们似乎能解决文件的同步问题,但是共享的单点瓶颈,而分发和同步,又需要我们实现太多的脚本和逻辑并且缺乏整体的管理和监控。幸好我们有另一个考虑:分布式文件系统。分布式文件系统不是传统意义的操作系统,它工作在用户空间,由应用程序来实现,如MogileFs或Hadoop等,它们更像底层操作系统的抽象,避免了文件系统的限制,拥有自己的内容组织结构,如MogileFS支持域和类,便于对大规模存储和复制进行合理规划。
当我们通过特定的接口操作分布式操作系统时,我们看到的是一个整体,但是在简单的接口背后,分布式文件系统内部,可以跨越多台服务器,根据自己的规则进行自动的文件复制。当然现如今已有不少的分布式文件系统供大家选择使用,至于如何使用或内部的实现逻辑、优缺点还需要深入的了解。
文件系统这篇说的比较简单,都是大概性的东西,但是实用时却不是那么容易的,这里仅仅是提供一个思路,实际问题再实际解决吧,“车到山前必有路”嘛。文件之后,下篇分享数据库的优化和扩展。