随着数据量的增加,提供高效、易用和可靠的存储解决方案已成为科学计算的主要问题之一。而分布式文件系统 (DFS) 是该问题的主要解决方案之一. 论文研究了六种主流的分布式文件系统.
- HDFS
- MooseFS
- iRDOS
- Ceph
- GlusterFS
- Lustre
分布式文件系统定义 #
DFS 提供了永久存储,不受系统故障的影响。该永久存储由多个服务器资源提供,客户可以在其中创建,删除,读取或写文件。与本地文件系统不同,存储资源和客户端分散在网络中。
分布式文件系统应该具备以下特点:
-
Transparency (底层系统的复杂性必须对用户隐藏)
- 使用方面: 用户无论在哪里,都应该可以访问系统,能够在DFS和本地文件系统上执行相同的操作,同时DFS 提供容错,用户不关心因文件系统是分布式的而导致的故障。
- 性能方面: 数据操作应该和传统文件系统一样有效(至少能达到相似的性能)。
-
Fault tolerance, 具有容错的DFS不应该在部分故障时停止, 考虑到的故障包括:网络和服务器故障导致数据和服务不可用,当几个用户同时访问数据时的数据完整性和一致
性。 -
Scalability, 通常可以管理几万个节点.
可扩展架构 #
DFS 没有一步到位的设计, 但为了构建一个可伸缩的系统, 应该避免一些设计:
- 首先避免单点故障 (需要复制)
- 避免单个服务器过载 (需要流量控制)
- 避免网络拥塞
一些 DFS 系统采用的架构:
- 客户端服务端架构:多客户端,单服务端,全局共享,类似NFS
- 基于集群的分布式存储架构:元数据和数据分离,一个或多个服务器专用于管理元数据,几个服务器用于存储数据。
- 完全分布式:元数据也是分布式的。
DFS 应该是并行的:数据分为多个块,同时分布式在几个服务器上,可以最大化吞吐量(client可以并行读取多个块).
透明性 #
在DFS中,最终用户不需要知道系统是如何设计的,如何定位和访问数据,以及如何检测故障。
Naming #
Naming 是逻辑名称到数据物理位置的映射.
DFS应该是位置透明性:文件存储的方式和位置的细节对客户是隐藏的。此外,一个文件可能存在多个副本,因此 mapping 必须返回所有可用副本的一组位置。
DFSs还应该是独立于位置的: 即使文件被移动到另一个物理位置,逻辑名称也不应该改变。为此,使用 allocation table或复杂算法(ceph crush) 来提供一个全局名称空间结构,即对所有客户端都是相同的名称空间.
数据访问 #
- CLI, 提供传统的 unix command (cp, rm, mv…)
- Java, c/c++… rest api
- mount, 使用 fuse
缓存 #
客户端第一次访问数据时可以将数据缓存在本地, 减少网络开销, 但会遇到缓存一致性问题.
故障检测 #
所有机器通过交换消息 (小), 以透明的方式通信。例如,hadoop report 允许管理namenode 知道哪个服务器持有什么数据。允许系统在服务器变得不可用或过载时识别哪些数据丢失、需要移动或重新复制.
另一个消息是heartbeats,用于确认服务器的可用性。如果有一段时间没有发送心跳,它将被移至隔离区,并使用 report 消息来应用正确的决策.
容错 #
在DFS,网络和服务器故障是规范而不是例外。
复制和副本放置策略 #
一般提高容错能力是多副本,副本可以存储在不同的节点、不同的机架、不同的地理位置,这样如果系统的任何地方发生故障,数据仍然可用。
但是,这可能会带来导致一致性问题.
同步 #
数据重写时, 所有副本需要同步, 以提供给用户最新的版本, 有几种方式:
- 同步,对修改数据的任何请求会阻塞,直到所有副本更新完成,这确保了用户可以访问最新版本的数据,但时会延迟查询的执行。
- 异步,允许对旧的副本进行操作,会导致用户读取旧数据。
- 半异步,请求被阻塞,直到一些副本被更新(不是全部).
缓存一致性 #
与同步复制是一个问题:当缓存中的一个副本被修改时,如何更新其中的所有副本。
当用户更改其中一个副本时,这可能会导致副本之间的不一致。这些修改需要传播到缓存中的所有副本和数据,以便为用户提供它们的最新版本. 有几种方式:
- Write Only Read Many (WORM) 文件一旦创建,就不能修改,缓存文件处于只读模式。
- 事务锁定:获取所有读数据集的读锁,可以组织其他用户的写锁,或者反之。
每次读取都反应最新的写入,每次先写入都是按顺序完成的。 - 租约:持有租约的客户端可以操作数据,并且在租约持有期间其他客户端没有其他用户可以修改数据。
负载均衡 #
提供集群负载均衡的能力:删除节点时,可以将数据恢复并存储到其他节点。添加节点时,可以将 hot 的数据节点平衡到新的节点。一般采用一个调度列表周期性的进行迭代。例如 ceph 的 crush。
分布式文件系统分析 #
这部分将总结六个主流 DFS 的特点,从以下几个方面入手
- Architecture,DFS 的体系结构。
- Naming,是否有 metadata server, metadata server 是集中式的还是完全分布式的。
- API and client access, 访问 DFS 的方式,提供 lib/fuse mount 等。
- Cache Consistency, 是否提供客户端缓存,如果提供如何保证客户端缓存一致性的。
- Replication and synchronization, 是否提供基于副本的容错,如果提供,如何进行复制和同步的。
- Load balancing, 系统如何平衡数据,元数据的。
- Fault detection, 系统如何进行故障检测的。
先放个论文最终对六个系统的总结,对 DFS 了然于胸的读者可以之间看此表。
HDFS #
HDFS 是 Apache 软件基金会开发的 (Apache Licence 2.0) 下的 Hadoop 分布式文件系统, 最初由雅虎内部实现。
Architecture #
HDFS 集中式的分布式文件系统。元数据由一台namenode server管理,提供 secondary namenode 容错。
Naming #
使用 inode 在文件和目录的层次结构上处理 namespace。inode保存磁盘配额、访问时间、元数据等.
namespace 由namenode管理。提供文件名和存储在datanode上的block的映射。
API and Client access #
HDFS 提供代码库,C, Java 或者 REST API 可以透明的使用。也提供 fuse mount。
Cache consistency #
单写多读模型:文件创建 -> 数据写入 ->文件关闭之后不能在被修改。创建新文件的Client 被授予租约,租约独占写访问,不允许并发写。
但是,HDFS 允许用户读取当前正在写入的文件。在这种情况下,若网络或服务器出现故障的情况下,通过为每个数据块生成的校验和来确保数据一致性。当客户端想要读取一个文件时,客户端将存储在HDFS中的校验和与自身计算的校验和进行比较。
Replication and synchronisation #
没有一个datanode拥有一个以上的块副本,也没有一个机架拥有同一块的两个以上的副本。Namenode 维护预期的副本数。
如果块被过度复制,Namenode 会选择删除一个副本:尽量不去减少机架上的存储副本的数量,同时倾向于删除可用磁盘空间最少的datanode上的副本。
如果数据块复制不足,则会计划创建一个新的副本,并将其放入优先级队列中,该队列会定期进行验证。将根据放置策略存储新块。
如果一个块的所有副本都在同一个机架上,Namenode 将在不同的机架上添加一个新副本: 这样导致该数据块将被过度复制,从而触发某些副本的删除。
数据异步复制,但提供了工具来支持同步模式。
Load balancing #
HDFS 将服务器(或集群)的利用率定义为已用空间与服务器(或集群)总容量的比率,并将阈值固定在(0,1)的范围内。如果对于每个 datanode,服务器的使用情况与群集的使用情况相差不超过阈值,则认为群集是平衡的.在
HDFS中,如果一个节点是不平衡的,副本将根据放置策略从该节点移动到另一个节点。
Fault detection #
startup: 在启动时,每个 datanode 将 version (系统版本) 和 namespace id (在格式化datanode时分配) 与 namenode 进行比较。如果它们不匹配,datanode就会关闭,从而保持系统的完整性。
register: datanode 还向 namenode 进行注册,namenode 会识别并记录 datanode 的 ip 和端口。
block report: 注册后,datanode 每小时向 namenode 发送blocks report (datanode 持有的数据块的信息), 以便向 namenode 提供每个数据块位置的最新信息。
heartbeat: 每隔三秒,datanodes 向 namenode 发送 heartbeat,以便 namenode 确认 datanode 的可用性。如果 namenode 在十分钟内没有收到任何心跳信号,则认为datanodes停止服务。heartbeat 还提供统计信息 (存储容量、正在进行的数据传输数量等…) 到 namenode,这样 namenode 就可以负载平衡决策。Namenode 的指令(用于纠正故障)如删除或复制数据块也会通过心跳发送到datanodes。Namenode 发现故障时,也通过 heartbeat 纠正故障(例如删除或复制块)。
MooseFS #
MooseFS 是一个开源的 (GPL 协议)分布式文件系统,由 Gemius SA 开发。
Architecture #
MooseFS 类似 HDFS。一个管理元数据的主服务器,几个存储和复制数据块的块服务器。和HDFS不同的是,MooseFS 存在多个 metalogger server, 定期向 master 下载元数据,在出现故障时提升为新的master。
Naming #
MooeFS 和 HDFS 一样管理 namespace,为用户提供全局的 namespace。namespace 存储了 metadata (permission,last access 等)和目录层次结构。metadata 会在 metalogger server 上复制。
API and client access #
基于 fuse 实现的 mfsmount。
Replication and synchronisation #
每个文件都要维护副本特定的数量,客户端写入时:
- 联系master,master返回一个块服务器列表。
- 客户端将数据发送到一个块服务器,后者以同步方式复制到其他块服务器。
Load balancing #
MooseFS 提供负载平衡。当服务器出现故障不可用时,数据无法达到它们的目标副本数。在这种情况下,系统将在其他块服务器上存储副本。
此外,文件可以超过他们的目标。如果出现这种情况,系统将从块服务器中移除副本。
MooseFS 维护版本号,块服务器再次可用时,使用最新的版本可以更新它存储的数据。
最后,可以动态添加新的数据服务器,用于存储新的文件和副本,MooseFS 会自动平衡副本数量。
Fault detection #
在 MooseFS 中,当服务器变得不可用时会被隔离,客户端不能对隔离的服务器执行任何 I/O 操作。
iRODS #
iRODS 是由数据密集型网络环境(DICE)研究小组开发的高度可定制的系统。
Architecture #
iRODS是一个集中式系统,有两个主要组成部分:
- 一个iCat Server,它在数据库中存储元数据,并处理对这些元数据的查询。
- 几个iRODS Server,数据存储。
一台iCat Server 和几台 iRODS Server 构成一个 zone。
与其他分布式文件系统相比,iRODS 依赖于存储资源的本地文件系统 (Unix文件系统,NTFS…) 并且不格式化或部署自己的文件系统。
Naming #
iRODS 将 namespace 和 metadata 存储在数据库中,使用类 SQL 来查询元数据。用户可以看到与 Unix 文件系统中相同的文件和目录层次结构(例如/home/myname/myfile.txt)。
iRODS 提供了聚合不同 zone 的工具,使得一个 zone 的文件可以被另一个zone 的客户端访问。
API and client access #
提供 cli 工具,fuse 和 api (php, java…)。客户端联系 iCat server 查询 metadata,然后从 iRODS server 执行数据 I/O。
Cache consistency #
iRODS 使用WORM 机制。在某些情况下,可以使用 -force 选项重写数据。在这种情况下,提供了wlock 和 -rlock 读写锁选项保证一致性。
Replication and synchronisation #
iRODS 默认情况下不会自动复制数据。相反,它实现了一个复制命令(irepl ), 该命令可以像其他常规操作(iput,iget)一样手动运行。
比较有趣的是,iRODS 是一个可定制的系统,用户可以创建规则,也就是说,设计一些在特定操作后运行的小命令。例如,建立一个规则,命令系统在数据创建后复制数据。在这种情况下,副本是以同步方式进行的。然而,副本放置策略是用户的责任。iRODS 还允许用户创建存储资源组,并选择在哪个组中存储数据和副本。
Load balancing #
在 iRODS中,存储资源属于一个默认的组或由用户创建的组。规则定期运行检测每当服务器过载时,根据可配置的参数(CPU负载、使用的磁盘空间…) 并允许iRODS在组中选择合适的存储来放置新数据。
和复制一样,用户可以选择如何平衡系统:可以使用其他规则告诉 iRODS 避免或强制将数据放在特定的资源上。用户还可以将数据从一个存储器移动到另一个存储器。
Fault detection #
iRODS 是以 p2p 方式实现的。因此,服务器可以一起通信以检测服务器何时变得不可用。在这种情况下,故障的服务器将从存储资源组中删除,并且客户端无法从该服务器执行任何I/O操作。
Ceph #
Ceph是由Sage Weil开发的开源(LGPL)分布式文件系统。
Architecture #
Ceph 完全分布式的:与HDFS不同,为了确保可伸缩性,Ceph 使用元数据集群(MDS) 提供动态分布式元数据管理,并将数据和元数据存储在 Object Storage Devices (OSD)中。
MDS 管理系统的 namespace、安全性和一致性,并在OSD执行I/O操作时执行元数据查询。
Naming #
相比于通过元数据服务器查找每个数据块的位置 DFS Naming ,Ceph 可以通过客户端计算哪些对象包含所请求的数据。
事实上,每个数据都被划分为分配给对象的块。这些对象由同一个 索引节点号加上一个对象号来标识,通过 CRUSH 函数定位到存储设备。当客户端请求数据时,联系 MDS 集群中的一个节点,该节点会向它发送inode编号和文件大小。然后客户端可以计算文件包含多少个对象,通过 crush 联系OSD 集群获取数据。
API and client access #
提供 REST API 和 fuse 实现的文件系统。
Cache consistency #
Ceph 是类 POSIX 的分布式文件系统,读取必须反映最新版本的数据,写入必须反映特定的发生顺序。
Ceph 使用一种简单的功能的锁定机制进行并发读写访问。锁由 MDS 授予,给予用户读取、读取和缓存、写入或写入和缓冲数据的能力。
Ceph还提供了 一些 relax 一致性的工具。例如,O_LAZY选项允许用户读取一个文件,即使它当前被重写。
Replication and synchronisation #
当客户端写入数据时,相应的对象被放在不同的放置组(PG)上,然后存储在OSD上。PG 和 OSD 的选择通过 CRUSH 确保根据可用磁盘空间和加权设备运行,并且使用与HDFS相同的放置策略。
Ceph 实现了三种同步复制策略: primary-copy、chain 和 splay replication。
- primary-copy,PG 中的第一个 OSD 将写入转发给其他 OSD,一旦后者返回确认,第一个 OSD 将其写入,然后允许读取。
- chain copy, 写入按顺序执行,一旦在最后一个OSD 上完成最后一次复制,就允许读取。
- splay replication,一半数量的副本按照顺序并行写入。一旦所有OSD都执行了写操作,就允许读操作。
Load balancing #
Ceph 确保两个层面的 loca balancing: data 和 metadata。
- metadata, Ceph 为每个元数据实现了一个计数器,这样就可以知道 metadata 的访问频率。因此,Ceph 能够将最常访问的元数据从过载的 MDS 复制或移动到另一个 MDS 上。
- data,Ceph 对设备加权。假设有两个权重分别为 1 和 2 的存储资源,第二个存储的数据是第一个的两倍。Ceph 监视每个 OSD 使用的磁盘空间,并根据与每个 OSD 关联的权重移动数据以平衡系统。假如添加了一个新设备。Ceph 将能够把不平衡的 OSD 数据移动到这个新设备上。
Fault detection #
Ceph 使用与 HDFS 相同的故障检测模型。OSD 定期交换心跳来检测故障。
Ceph提 供了一个小型monitor 集群 MON,MON 保存了一份集群映射。每个 OSD 可以向任何 monitor 发送 failure report。错误的的 OSD 将被标记为 down。每个 OSD 还可以从 MON 中查询集群映射的最新版本。因此,以前默认的 OSD 可以再次加入系统。
GlusterFS #
GlusterFS 是由 gluster 核心团队开发的开源(GPL)分布式文件系统。
Architecture #
GlusterFS 不同于其他 DFS。它采用 client-server 设计,没有元数据服务器。
GlusterFS 将数据和元数据存储在附加到多个服务器的几个设备上。这组设备称为 volume,可以配置为将数据分条成块或者复制它们。因此,块将跨 volume 内的几个设备分布或复制。
Naming #
GlusterFS 不在专用的中心服务器上管理元数据,而是使用弹性哈希算法(EHA),通过算法定位文件,以提供一个全局名称空间。
EHA 使用哈希函数将文件的路径名转换为固定长度、统一且唯一的值。会分配给存储设备一组值,系统基于其值存储文件。例如, 假设有两个存储器设备: disk1和disk2,分别存储值为 (1, 20), (21, 40) 的文件。文件 myfile.txt被转换为值30。因此,它将存储在disk2上。
API and client access #
GlusterFS 提供了一个 REST API和一个mount模块(FUSE或mount命令),让客户端能够 访问系统。客户端与 volume 进行交互,向 volume 发送文件以及从 volume 中检索文件。
Cache consistency #
GlusterFS 没有客户端缓存,因此没有缓存一致性。
Replication and synchronization #
不复制数据,依赖 RAID。
使用同步写入将整个存储设备的多个副本复制到同一 volume 内的其他副本中。也就是说,一个 volume 由几个子集组成,其中有一个初始存储磁盘及其镜像。因此,volume 中存储设备的数量必须是所需复制的倍数。例如,假设我们有四个存储介质,复制固定为两个。第一个存储将被复制到第二个存储中,从而形成一个子集。同样,第三和第四存储器形成另一个子集。
Load balancing #
GlusterFS 使用 EHA 确保每个逻辑存储几乎保存相同数量的文件。
由于文件的大小不同,并且可以添加或删除存储设备,GlusterFS 会根据使用的磁盘空间,通过每个逻辑存储来影响物理存储。因此,当添加或移除磁盘时,可以将虚拟存储移动到不同的物理存储,以平衡系统。
Fault detection #
当服务器变得不可用时,它将从系统中移除,并且不能对其执行任何I/O操作。
因为没有中心的server,所以不像其他 DFS 系统那样执行复杂的通信来进行故障检测。
Lustre #
Lustre 是一个适用于Linux的 DFS,GPL许可。
Architecture #
Lustre 是一个集中式分布式文件系统,与其他的 DFS 不同,它不提供任何数据和元数据的副本。
Lustre 将元数据存储在 MDT 共享存储上,两台元数据服务器(MDS) 连接 MDT,从而提供主动/被动故障转移。MDS 是处理元数据请求的服务器。
数据本身也以同样的方式进行管理。数据分成对象并分布在几个共享对象存储目标(OST)上,这些目标可以连接到几个对象存储服务器(OSS)上,以提供主动/主动故障转移。
Naming #
MDS 提供 global namespace,使用 inodes 和扩展属性将文件对象名称映射到其对应的ost。客户端通过 MDS 查询请求的数据应该查询哪些 OST。
API and client access #
fuse,文件传输和其他 DFS 类似:先通过 MDS 定位数据吗,然后对 OST 执行 I/O。
Cache consistency #
Lustre 实现了分布式锁管理器(DLM)来管理缓存一致性。这是一种复杂的锁机制,允许 Lustre 支持并发读写。
Replication and synchronisation #
不提供复制,依赖其他软件。
Load balancing #
提供了简单的 load balancing 工具。当OST不平衡时,即它比其他OST使用更多的空间磁盘时,MDS 将选择具有更多可用空间的 OST 来存储新数据
Fault detection #
Lustre 不同于其他 DFS,故障是在客户端操作(元数据查询或数据传输 期间检测到 的,而不是在服务器通信期间检测到的)。
当客户端请求文件时,它首先联系 MDS。如果 后者不可用,客户机将询问 LDAP Server,通过它查询其他可用的MDS。然后系统执行故障切换,即第一个 MDS被标记为失效,第二个成为活跃的。
OST 中的一个故障也是这样做的。如果客户端向某个OST发送数据,而该OST在某段时间内没有响应,它将被重定向到另一个OST。
分析和对比 #
1. Scalability #
DFS 需要面对的一个真实情况就是:随着数据爆发式的增长,需要面对越来越多的客户端执行请求和I/O操作,以及越来越多的不同大小的文件需要存储。
在这种情况下,在不影响系统性能的情况下的可伸缩性是 DFS 最核心的一个能力,会响应回答上述问题的能力。
Discussion about architecture #
- 在Lustre中,元数据由单个服务器管理,并存储在存储设备上。每秒可以执行的客户 端请求数量取决于单个服务器的计算能力和磁盘延迟。所以这个系统是有局限性的。
- HDFS 和 MooseFS 遇到了同样的问题,但他们选择将元数据存储在元数据服务器的内存中。这减少了一定的延迟,但是可以创建的文件数量比 Lustre 少,取决于内存的数量。
- iRODS 也使用集中式架构,但依赖于数据库来管理和存储元数据。这允许 iRODS 可以使用 SQL 查询,同时存储比HDFS或MooseFS更多的文件。但是,文件的数量取决于可用的磁盘空间,并且仍然有限。
- GuusterFS 元数据存储在 data server上,文件数量不受可创建的限制。此外,GlusterFS没有分离data和metadata管理,可以快速添加服务器进行快速扩展。
- Ceph类似GlusterFS,但是将元数据管理分布在几个元数据服务器上。这使它能够面对大量的客户请求。然而,为了增加数据量和客户端的查询,Ceph 需要添加两种服务器: 元数据服务器或数据服务器,这使得系统的规模更加复杂。
Small or big files? #
HDFS、MooseFS、iRODS 和 Lustre 更适合存储少量的大文件,而 Ceph 和 GlusterFS 可以同时适合小文件和大文件。除了 iRODS 之外,所有被调查的 DFS 都使用分块来加速数据传输,但是分块它只对大文件有益,因为小文不能(很少)分成块。
表3.2显示了读写操作的结果。红色表示最佳结果,而蓝色表示最差结果。
我们可以看到 GlusterFS 的架构在写入小文件方面比其他架构表现得更好。这可能是由于元数据的分布式请求管理。第二个发现是分块提高了大文件的性能。唯一不使用这种方法的系统(iRODS)获得了最差的结果。
2. Transparency #
在DFS中,底层系统的复杂性必须对用户隐藏。它们应该像在本地文件系统中一样访问 文件和执行操作,并且不应该关心由于文件系统的分布式特性而导致的错误。
File access & operations transparency #
HDFS、MooseFS、iRODS 和 Lustre 维护一个索引,其中物理位置与文件名相关联。当文件从一个存储设备移动到另一个存储设备、被创建或删除时,只需更新索引。主要缺点是当客户端请求文件时,元数据服务器负责查找数据存储的位置,这增加了该服务器的计算压力。
此外,HDFS和MooseFS将元数据存储在内存中,限制了要创建的文件数量。这与iRODS和Lustre不同,因为它们将元数据放在磁盘上。
Ceph 和 GlusterFS 使用算法来计算数据的位置。这种方式减少了元数据服务器的工作负载。元数据服务器只需提供正确运行算法所需的信息。然而,与维护索引相反,使用这种方法,当客户端请求文件时,他们不会立即知道数据存储在哪里,而是需要计算数据的位置。(增加了客户端的压力)
Fault detection #
HDFS、MooseFS、iRODS、Ceph 和 GlusterFS 提供了强大的故障检测功能。当故障检测到时,故障节点被隔离或从系统中删除,从而限制用户知道此类故障的风 险,确保了透明性。
然而,故障检测这意味着在服务器之间交换大量的消息,这可能会影响性能。
在Lustre中,没有提供检测和纠正不可用服务器的机制。故障识别由客户端感知并处理。因此,它不具备 transparency。
System access #
Moose 和 iRODS 的提供客户端可以透明的读写文件
HDFS 使用客户端访问 namenode 元数据,通过转发访问 datanode 的数据,使用起来比较复杂。
Ceph 和 GlusterFS 需要使用内部的客户端与系统交互,这种配置中,不如其他系统透明。
3 Fault tolerance #
System availability #
Ceph 和 GlusterFS 可用性比较高:元数据被复制。相反,在集中式系统中,元数据服务器是单点故障(SPOF ) , 这会导致元数据丢失和系统不可用。
HDFS 选择定期将元数据和namespace 保存在secondary namenode 中。但是在重新启动期间,系统仍然不可用。iRODS 提供了复制数据库的工具(pgpool ) ,但与HDFS一样,系统在 iCAT Server 重启之前不可用。
最后,MooseFS 和 Lustre 成功避免了SPOF, 他们使用故障转移: 几个处于备用状态的元数据服务器定期保存元数据,以接管故障系统。
Data availability and Data synchronization #
除Lustre之外,分析的 DFS 都使用多副本而,但也带来了一致性问题: 所有副本需要同步。
- HDFS 异步复制: 当写入数据时,即使副本没 有提交到磁盘,也可以请求数据。如果仅是这样,会带来一致性问题,因为一些过时的副本可以被访问,但 HDFS 依靠 WORM 机制解决了这个问题: 一旦创建,数据就不能被修改。因此,一致性问题只会在创建文件时出现。HDFS 通过在创建期间授予文件 lease 来解决此问题,文件在提交到磁盘之前无法访问。
- iRODS、Ceph 和 GlusterFS 使用同步复制:在所有副本保存到磁盘之前,对文件的查询会被阻塞。它避免了一致性问题,但在同步过程中数据不可用。
此外,通过提供放置策略,一些DFS可以更好地防止故障。
- HDFS 和 Ceph 自动将副本存储在不同的地理机架上
- iRODS 和 GlusterFS 让管理员决定要使用的放置策略。
- MooseFS方面,它没有提供任何放置策略,这使得它更容易受到中断或网络故障的影响。
HDFS、MooseFS 和 Ceph 会自动验证所需的复制是否得到满足,并在不满足时复制或删除副本,在iRODS中这是手动完成的。
最后,默认情况下,Lustre 无法保证数据始终可用。它依赖于另外安装的软件。如果没有这些独立的工具,这个系统就不能很好地防止故障。
Load balancing & cache consistency #
过载的服务器会延迟或中止请求的执行。Ceph和GlusterFS提供了分配元数据工作负载的算法,并允许动态添加新的服务器,但集中式 DFS 使用单一元数据服务器是一个瓶颈。为了解决这个问题,这些DFS使用线程并在客户端缓存数据。然而,这些解决方案仅仅是推动了系统的极限,而 不是删除它。
缓存数据会导致一致性问题: 被更新的数据不能被其他用户访问。
- HDFS 租约持有期间不允许修改文件,消除了一致性问题。
- iRODS和Lustre使用文件锁 来确保并发访问。但是,锁对数据可用性有影响: 如果操作由于失败而不能很好地执行,文件可能会被无限期地阻塞。这类 DFS 需要定期执行死锁检测。注意,Ceph 对缓存也是用了锁。
另一个问题是数据服务器过载,这会致网络拥塞: 如果一个数据服务器比其他服务 器存储更多的文件,它将执行更多的I/O操作。DFS以不同的方式检测过载的服务器:
- MooseFS 和 Lustre 在拥有最多空闲磁盘空间的服务器上存储新数据,但它们并没有减轻过载的服务器。iRODS 则需要配置规则以避免过载。
- HDFS、Ceph 和 GlusterFS 根据空闲磁盘空间放置数据并将数据从过载的服务器移动到另一个服务器,成功地做到了 这一点。
此外,DFS 允许动态添加新的数据服务器。
- MooseFS 和 Lustre 中,添加新服务器仅用于新数据存储,不会缓解过载的服务器。
- iRODS、Ceph 和 GlusterFS中,需要手动执命令来平衡负载,
- HDFS更好,自动完成。
系统性能 #