【大话存储II】学习笔记(15章),块级集群存储系统里面分析的主要是块集群系统,同样文件级存储也可以集群化。
因为NAS系统的前端网络是以太网,速度比较低,导致NAS主要用于一些非关键业务中,比如文件共享。但是一些特殊应用也需要多主机同时访问某个大文件,比如3D渲染集群等。如果我们使用块集群存储系统,则会存在一个问题,需要在应用程序上引入文件锁,而NAS的文件系统一般都自带有文件锁机制,所以还不如把NAS存储系统进行集群化。
在谈怎么样把NAS系统进行集群化之前,我们说说集群文件系统的架构。集群文件系统是个很宽泛的概念,分布式文件系统、并行文件系统、共享文件系统统都可以称为集群文件系统
。
集群文件系统
集群文件系统,顾名思义,就是把提供文件存储的设备进行集群化。一般来说,我们可以使用一堆服务器来提供文件服务。
本章中,我们首先对集群文件系统架构进行分类,主要有如下几种
共享与非共享存储型集群
对称与非对称集群
自助型与服务型集群
SPI与SFI型集群
串行与并行集群
是否共享LUN
我们可以按照集群是否有共享LUN将架构分为共享存储集群和非共享存储集群
共享存储集群
集群的所有节点都是共享使用后端存储的,注意这里的共享不是说共享磁盘阵列,而是说可以共享访问同一个LUN。
这就引出另一个问题了,多主机同时读写同一个LUN里面的文件,如何保证数据一致性?无法保证数据一致性的原因在于存在多个独立的文件系统逻辑,每个客户端都要维护自己的文件系统缓存,而且它们之间不互相通信。
我们可以直接把多余的文件系统实例去除掉,只保留一份文件系统逻辑,这就形成了共享式SAN文件系统了。
下图为传统的架构。多个主机共同访问一个LUN的文件,会产生数据不一致。因为主机各自为政,任意一台客户端要访问目标文件的时候,会向自身内存中的文件系统发起请求,从而执行IO。
下图是进化后的架构,只需要有一个客户端主机上保留一份文件系统,也就是元数据服务器。所以客户端要访问文件的时候,需要先通过网络向元数据服务器发出请求,然后自行向目标发起访问。
非共享存储集群
与共享存储集群相反则是非共享存储集群,每个节点都独占一个LUN。当然集群也可以使用同一台磁盘阵列,但是各自的存储空间是之前划分好的,只能自己访问,别人不能访问。
同样我们也可以单独剥离出元数据服务器,然后把后端主机并行化。
这样的好处在于,客户端从存储节点读取数据的时候,完全可以并行访问。可以大大提升访问效率。
共享与非共享存储集群对比如下:
读写数据的过程:当某节点需要访问其他节点上的数据的时候,
共享存储集群:每个节点可以直接对后端存储中的LUN进行读写,前端传输的只有元数据,而没有实际数据流量。
非共享存储的集群文件系统:如果要访问非当前节点的数据,需要通过前端网络进行传输,速度较慢。
缓存一致性:共享存储需要考虑缓存一致性,一般来说需要把写缓存给关了,非共享式不需要考虑。
某节点故障以后:共享存储,一个节点故障,另外的节点可以直接接管。非共享存储,为了防止单点故障,需要将每个节点的数据镜像一份到其他节点。
是否需要使用SAN阵列:共享存储必须使用SAN阵列,非共享式集群可以不使用SAN阵列,服务器节点的本地槽位多的话,可以使用本地磁盘,但是不可使用DAS磁盘箱。
非共享存储型文件系统
又可称为“分布式文件系统
”,即数据分布存放在集群中多个节点上。
是否引入IO节点
上一小节中讲的架构中,客户端可以直接访问到共享存储。
实际上可以在插入一个中间层,可以对后端文件以另一种形式进行输出。
比如
比如在LUN上层引入了对象存储网关,则就是对象存储。
需要客户端需要使用支持OSD协议的代理,比如pNFS
如果引入了私有设备,则需要使用相应的代理。
如果引入了NAS头,则形成了集群NAS,对外只需要使用标准的NFS客户端即可。
典型代表是:Panasas , Lustre , Ibrix
终上所述,集群文件系统最后演化成了两种:
客户端直接访问后端SAN
客户端和后端FC SAN 之间引入IO节点的模式
这两种方式各有其优劣
客户端直接访问SAN的模式,客户端与后端的磁盘阵列没有其他的处理模块,IO效率最高。
但是成本随着客户端的增加而增加,因为目前FC HBA卡非常贵,如果每个客户端安装FC HBA卡,成本将非常高。此外,因为后端LUN都由元数据服务器来挂载,存在单点故障,一旦元数据服务器出问题了,则系统就瘫痪
客户端与SAN之间引入了IO节点的模式:
客户端可以使用便宜一点的
以太网
来进行IO节点的访问,另一方面如Ibrix这样所有节点的角色对等的架构,每个节点都是MDS和IO节点,这样的话,一旦某个IO节点故障,则其他任何一个IO节点就可以接管故障节点的资源,容错率高了很多。当然有利必有弊,IO效率相对就比较低了,而且受以太网速率的限制,客户端IO速度也不高。
角色是否对等
可以根据每个节点的角色是否对等分为对称式和非对称式文件系统。
所谓对称式集群文件系统指的是集群中所有节点的角色和任务都相同,完全等价。
在对称式集群中,所有节点都很聪明
,每时每刻都能保持精确沟通与合作,共同掌管全局文件系统的元数据。每个节点要更新某元数据的时候,需要先将其锁住,其他节点就必须等待,这样节点之间的沟通量就很大。
所有节点在同一时刻均看到同一片景像。
那么非对称式集群呢?
在非对称集群中,只有少数节点(主备节点)是聪明的,他们掌管着系统内全局文件系统信息,其他节点不清楚。
当其他节点要访问某文件的时候,需要首先联系这个聪明节点,得到要访问文件的具体信息(比如存放在哪个节点中的哪的LUN的什么地址里面。)
每个傻节点上需要安装一个代理
客户端来于聪明节点通信,它获得了文件的具体信息之后,才能让主机从后端的LUN中拉取数据。
我们把聪明
的节点叫Metadata Server, MDS或者MDC
,是系统中唯一掌握文件系统元数据的角色。
那么对称集群文件系统与非对称的典型代表是哪些?
对称式集群:Veritas ClusterFS , HP Ibrix
非对称式集群:中科蓝鲸BWFS,EMC MPFS
显然这两种架构各有优劣势。
非对称式集群易于实现,沟通成本低,对应的产品也多。
客户端只能通过元数据服务器进行挂载,所以性能受限于元数据服务器,不过我们可以引入多个元数据节点来均摊负载。
对称式集群文件系统:因为所有节点的地位相同,所以挂载任何一个节点的目录即可,但是节点之间构成的复杂度高,不利于扩展。
当节点少的时候,由于对称式集群中每个节点都可以充当元数据服务器的角色,所以性能更好。
是否对外提供服务
按照是否对外提供服务分为自助型和服务型
什么叫自助型集群?就是应用是使用本地磁盘的,比如一个集群中每个节点都安装了某种应用,然后现在有共享系统内所有文件的需求,就可以在应用节点上直接部署集群文件系统。
所以每个节点不但是数据的生产者,还是底层文件的消费者,这就是自助型
那什么是服务型集群文件系统
,如下图。
框内是集群文件系统,框外又增加了一排主机,群外的客户端主机通过某种协议来访问集群中文件数据。
集群中的服务节点不是数据的消费者,只是服务者
为什么要使用服务型集群呢?自助型不是挺好的吗?主要原因如下
降低成本。自助型集群中每个节点都需要高速网卡,比如FC HBA卡,集群规模扩大,则成本也会扩大。
可以接入更多的客户端
可以用较少的节点服务于更多的客户端主机。而且内部沟通信息量更小。
统一路径型与统一文件系统型集群
之前我们讲过,为了实现集群的Single Name Space
统一命名空间,有两种方式
- 懒人做法:既然每个节点都有各自的文件系统,那么就直接把输出路径虚拟化一下,集中管理起来就OK。再向外输出一个Single Path Image。只管路径统一,放在那里不管。典型代表就是微软的DFS
- 勤快人做法:让每个节点都知道所有文件的位置,在文件系统层进行整合而不只是在表层路径上进行整合,即Single FileSystem Image。典型代表,CFS等大多数集群FS。
SFI的优点在于可以将一个文件切分到各个节点中,这是SPI无法做到。
但是SFI的扩展性能往往比较有限,SPI则可以整合大量的节点。这是因为SFI的集群FS的节点之间需要同步复杂的状态,每个节点所维护的状态机非常复杂,当节点数量增加的时候,节点状态机的协同加上网络延迟,性能自然上不去。
而SPI模式下,节点相互独立,同步的信息很少。。
串行与并行集群
对于服务型集群,可以提供两种方式的对外访问:
串行的方式:挂载集群中的某个节点的目录,然后所有的通信都通过这个节点执行。
并行访问:
客户端最开始会挂载在某个节点上,但是只是通过这个节点获取元数据信息,客户端可以并行的访问从多个节点中读写数据。
- 对称模式下的并行
- 非对称模式下的并行
- 对称模式下的并行
集群文件系统中的关键问题
集群本质是一堆服务器合作处理任务,这一点集群块存储系统与集群文件存储系统没有区别。但是当我们面对的不是单一节点以后,会多出很多的问题, 比如说能不能用统一的目录对后端的文件进行访问,比如说多主机对某个文件访问的时候会不会有冲突,还有就是每台设备都会缓存数据,会不会有缓存不一致的情况。
下面我们将一一讲解
统一命名空间(Single Name Space)
如果我们要访问某个文件,则需要知道文件的路径,也就是说文件是在哪个目录里面,比如windows下面的路径"D:\data\file.txt",或者Linux下面的"/usr/someone/file.txt"。windows和Linux文件系统的设计方式不同,所以路径看上去也不同。
Windows默认为以各个分区做为入口,所以路径开始会指明是在那个分区里面。
而Linux是以全局为入口,所以开头是根目录"/",而各个分区都
挂载
到某个目录下,比如分区sda2挂载到/home/mnt
下面。那么如果我们进入到/home/mnt
,其实就相当于进入了sda2分区文件系统的根入口。同理Windows也可以把分区挂载到某个目录下。
如果我们把一个目录挂载到另一个目录下面,这个被挂载的目录就可以称为虚拟目录
。也就是说通过虚拟目录访问到的不是原本属于此目录下的文件,而是挂载在其上的目录树。
所以虚拟目录更应该理解为一个路径,它只是提供一个路牌,路牌上的路名不等于路的本身,只是一个名字而已。
现在我们来看一个集群环境下的情况。
每个节点都有各自的路径
,但是既然多节点组成了集群,对外应该呈现为一套路径。
比如说客户端看到路径/cluster/data1
,而这个路径真实应该在节点A上。不管向集群中哪个节点发出请求,所有的请求都应该重定向到节点A来,收到请求的节点就相当于一个代理而已。也就是说已经被某节点使用的路径,不能再被其他节点所使用了。
这就是统一命名空间(Single Name Space):集群中的所有节点上供客户端挂载的路径不重复,对外呈现为单一的NAS服务器。
这就是与非集群环境下最大区别。非集群下,两台NAS设备有同一个路径,而且对外可见,那么客户端可以挂在两个不同的独立存储空间,这样当然管理起来很麻烦。
那么怎么实现统一命名空间呢?有两种形式
单一路径影像(Single Path Image):
节点只需要管理自己的文件系统空间,然后在上面加一个中间层,可以把多个文件系统虚拟为同一个空间。比如/a和/b虚拟化为一个/c,这种方式就是单一路径镜像。
这种方式下,每个节点其实只能看到自己节点上的路径,如果收到了访问其他节点目录的请求,应该将请求重定向到另外的节点上,当然处理的结果还是由收到请求的节点返回给客户端,这样做的目的是保证对客户端的透明。
单一文件系统影像(Single FileSystem Image)
单一路径影像只是在路径上进行了一层虚拟化,所以可以对外呈现出单一的虚拟目录。而单一文件系统影像更彻底,它想将所有节点的文件系统进行融合,所以它会在本地文件系统(如EXT3)上加了一层虚拟化逻辑,这样就改变本地文件系统的逻辑,比如可以这样,客户端看来,某个文件在/fs/a上面,但是实际上有可能前半端在节点A,后半段在节点B。
因为文件系统已经“彻底”融合了,所以集群中的每个节点都知道所有文件的存放位置和状态,所以这种模式下,收到客户端IO请求的节点会对IO进行解析,然后就知道数据应该落到哪些节点上,最后把IO拆分后发到对应的集群节点上进行读取或者写入。而不是像单一路径影像那样将请求重定向到其他节点上。
总之单一路径影像属于松耦合,更利于节点的扩充。而单一文件系统影像是把文件系统都融合了起来,属于紧耦合,扩展性不好,实现难度大。
集群中的分布式锁机制
在单节点的的单一操作系统内,可能有多个应用程序对同一个文件进行修改,这样极有可能出现数据不一致的情况,于是我们引入了锁
,这样一个文件在同一时刻只允许这个应用程序修改,其他应用程序只能等待。
这样又会出现一个问题,若干某个文件加锁了,却迟迟未被处理,其他应用程序就只能等待,时间自然就白白浪费了。
锁也不是,不锁也不是,那么有没有两全其美的方法呢?
当然有,比如
字节锁:
程序只是把某端或者某些字节加锁了,所以多个程序可以并行的读写文件的不同部分。这样锁的粒度就降低了,可以并行的读写同一文件,性能自然得到提高。
集群中的分布式锁
集群其实可以看作一台大的独立系统,集群外的客户端相当于应用程序,因为有并行,自然也需要锁。
但是集群是由多个节点组成的,维护锁需要由哪些节点负责呢?一般有两种方式
集群中所有节点选一个节点负责锁的维护,这就是
集中式锁管理
,用于非对称式集群- 所有节点共同维护锁,锁的信息在节点上同步,这就是
分布式锁管理
,用于对称式集群。
元数据锁
如果一个集群中,所有的节点的角色对等,而且共享存储,那么此时所有的节点掌握着文件系统元数据,而且是实时同步的。
那么当节点要为某个文件分配空间的时候,需要把相关的元数据锁住。为什么呢?因为如果不锁住,如果此时其他节点也在分配空间,则两个节点分配的空间可能有冲突。
那么当一个节点要分配数据了,可以利用分布式锁机制通知其他节点,位图已经由它掌控了。当然分配完成之后,还要再与其他节点同步一下自己的元数据缓存。
缓存一致性
我们知道集群的节点会维护一个读缓存,所以一个节点有可能缓存其他节点的某些内容。那么就存在一种情况,某一时刻节点存储的内容被应用修改
了,但是这段内容的读缓存有可能在其他的节点上,如果此时有终端读到了缓存里面的内容,则出现与实际数据不一致的情况。
那么怎么办?可以把读缓存的数据作废或者读入新数据以更新,这就是写即作废
机制,可以保证全局缓存一致性。
那写缓存呢?
对于有共享存储的集群,
最好不开写缓存,也就是写入的时候最好要直接写到磁盘上再返回成功,就好比公用物品必须放回原处,别人才能继续用,而不能只是放到自己的缓存。
如果实在要使用写缓存也可以,当写的数据放到了缓存里面以后,需要立刻通知到集群中其他节点。那么其他节点要对这段数据进行操作的话,需要与此节点进行联系。不过这就需要花费沟通成本来保证缓存一致性了。
如果集群没有共享存储
写入的数据都缓存在本节点中,其他节点要访问数据的话,必须联系数据的拥有者,不存在不一致的问题。
如果集群文件系统是对外提供服务的,那么写缓存最好关闭,因为集群节点没有类似SAN磁盘阵列的掉电保护机制,一旦掉电,则数据丢失。
集群、并行、分布式、共享文件系统辨析
大家平时可能听到多种叫法:集群文件系统、SAN共享文件系统、分布式文件系统、并行文件系统。这些概念之间是否有什么联系呢?
SAN共享文件系统:指的是共享存储集群文件系统。又可简称为
SAN文件系统
分布式文件系统:可以等价于
非共享存储
集群文件系统,也就是说同一个文件系统下的文件是存放在不同的节点里面并行文件系统:可以提供
并行
访问的集群文件系统,一般需要在主机客户端上安装一个代理
或者新的文件系统挂载器,专门实现并行访问。分布式不一定代表着并行,但是并行一定是分布的。并行文件系统
集群文件系统:分布式文件系统、并行文件系统、共享文件系统统称为
集群文件系统
。分布式
和共享式
指的是数据分布的方式,而并行
指的是用户对数据的访问方式。
集群NAS
在【大话存储】学习笔记(10~13章),NAS、IP SAN这一章中,我们讲到了NFS/CIFS协议,它们是网络文件访问系统,主要的作用是让主机可以通过网络的访问NFS服务器上的文件,所以它其实不是管理文件与扇区的对应关系的。
而FAT、NTFS是实实在在的文件系统,是管理文件与块的对应关系的,我们称为文件管理系统
那么现在我们要构建一个集群NAS,希望他能对外提供文件访问服务。
最底层仍然使用NTFS、EXT3等文件管理系统,主要来管理文件与块的对应关系,
然后在上面增加一层集群文件系统,主要用来管理集群的元数据信息
再包裹一层NFS就可以对外提供文件服务了,形成了分布式并行文件系统。
如下图所示
可以看出一个集群NAS系统其实可以分为三层架构
第一层:底层存储空间层,可以是Share Everything(共享型)或者Share Nothing(非共享型)
- 第二层:集群文件系统层,它建立在共享型或者非共享型存储空间之上
如果底层存储是共享型的话,一般文件系统层都使用Single Filesystem Image。
如果底层存储使用非共享型,则既可使用Single Path Image ,又可使用Single Filesytem Image模式。
第三层:NAS协议输出层,可以有四种访问模式:传统CIFS,传统NFS,pNFS并行客户端,并行或者串行访问。
总结一下,将集群文件系统中的文件用NAS协议输出,就是集群NAS。它可以对外提供统一的命名空间,以及统一管理,若是出现了故障,还可以进行故障的切换,在线平稳的迁移等。
所以集群NAS不是简单的NAS设备的堆砌,它可以更加的灵活,比如
集群NAS有统一命名空间
比如某个应用程序需要在一个目录下放几十万个小文件,如果要把这么多文件放到传统的NAS的同一目录下,性能相当的低。
如果我们把文件分散到不同的目录呢,虽然可以并发读取小文件,但是每个文件存放的路径必须对主机可见,麻烦的事就来了,我们必须得修改应用程序来适应这么多目录。
此时集群NAS的统一命名空间就非常有用了,我们之前说过,统一命名空间指的是对外呈现统一的虚拟目录,屏蔽了底层的细节。具体做法是将文件系统承载于多个Segment,每个Segment又分配到不同的Segment Server上,这样主机只需要挂载一个目录,而且还不影响性能。
统一管理、故障切换、在线迁移。如果集群NAS设备之间共享存储则
集群NAS可以随时将负载过高的节点上的Segment迁移到负载低的,因为这些Segment Server之间共享存储,所以不涉及到数据移动的过程。
独立的NAS Server发生故障,所管理的数据就无法访问了,但是集群NAS因为共享存储,所以在某节点故障之后,可以由正常节点进行接管(后端Segment以及IP地址等),