Cpeh论文阅读翻译:Ceph: A Scalable, High-Performance Distributed File System

目录

2 System Overview(系统概述)

3 Client Operation(客户端操作)

3.1File I/O and Capabilities

3.2 Client Synchronization

3.3 Namespace Operations

4 Dynamically Distributed Metadata(动态分布的元数据)

4.1 Metadata Storage(没读懂)

4.2 Dynamic Subtree Partitioning

4.3 Traffific Control

5 Distributed Object Storage(分布式对象存储)

5.1 Data Distribution with CRUSH

5.2 Replication

5.3 Data Safety

5.4 Failure Detection

5.5 Recovery and Cluster Updates

5.6 Object Storage with EBOFS


2 System Overview(系统概述)        

        Ceph 文件系统有三个主要组件:客户端,它的每个实例都向主机或进程公开一个近 POSIX 文件系统接口;一个OSD集群,集中存储所有数据和元数据;元数据服务器集群,它管理名称空间(文件名和目录),同时协调安全性、一致性和连贯性。我们说 Ceph 接口是近 POSIX 的,因为我们发现为了更好地适应应用程序的需求并提高系统性能,扩展该接口并有选择地放宽一致性语义是合适的

 

        该架构的主要目标是可伸缩性(达到数百 Pb 甚至更高)、性能和可靠性。可伸缩性是从多个方面考虑的,包括系统的总存储容量和吞吐量,以及单个客户端、目录或文件的性能。我们的目标工作负载可能包括这样的极端情况,如成千上万的主机同时读写同一个文件或在同一个目录中创建文件。这种场景在运行在超级计算集群上的科学应用中很常见,越来越能代表未来的通用工作负载。更重要的是,我们认识到分布式文件系统的工作负载本质上是动态的,随着活动的应用程序和数据集随着时间的推移而变化,数据和元数据访问会有显著的变化。Ceph 直接解决了可伸缩性问题,同时通过三个基本设计特性实现了高性能、可靠性和可用性:解耦的数据和元数据、动态分布式元数据管理和可靠的自主分布式对象存储。  

        分离数据和元数据—Ceph 最大限度地将文件元数据管理与文件数据存储分离开来。元数据操作(打开、重命名等)由元数据服务器集群统一管理,而客户端直接与 OSD 交互以执行文件 I/O(读取和写入)。基于对象的存储早就承诺通过以将低层块分配决策委托给各个设备提高文件系统的可伸缩性。然而,与现有的基于对象的文件系统相比,Ceph完全消除了分配列表,现有的基于对象的文件系用较短的对象列表代替了较长的每个文件的块表。相反,文件数据被条带化到预先命名的对象上,一个称为 CRUSH 的专用数据分布函数将对象分配给存储设备。这允许任何一方计算(更确切地说然后查找)包括文件内容的对象的名称和位置,消除了维护和分发对象列表的需要,简化了系统的设计,并减少了元数据集群的工作负荷。 

        动态分布式元数据管理—由于文件系统元数据操占典型文件系统工作负载的一半,有效的元数据管理对整体系统性能至关重要。Ceph 利用了一种基于动态子树划分的新型元数据集群体系结构,该体系结构自适应并智能地在数十甚至数百个MDS 之间分配管理文件系统目录层次结构的责任。(动态)分层分区保留了每个 MDS 工作负载的局部性,有助于高效更新和积极预取,从而提高常见工作负载的性能。值得注意的是,元数据服务器之间的工作负载分布完全基于当前的访问模式,允许Ceph 在任何工作负载下有效地利用可用的 MDS 资源,并实现 MDS 数量的近似线性扩展。

        可靠的自主分布式对象存储—由成千上万个设备组成的大型系统本质上是动态的:它们以增量方式构建,随着新存储的部署和旧设备的淘汰而增长和收缩,设备故障频繁发生且在意料之中,大量数据被创建、移动和删除。所有这些因素都要求数据的分布不断发展,以有效地利用可用资源并保持所需的数据复制级别。Ceph 将数据迁移、复制、故障检测和故障恢复的责任委托给存储数据的 OSD 集群,而在高级别上,OSD 共同向客户端和元数据服务器提供单个逻辑对象存储。这种方法允许 Ceph 更有效地利用每个 OSD 上的智能(CPU 和内存),通过线性扩展实现可靠、高度可用的对象存储。

        我们描述了 Ceph 客户端、元数据服务器集群和分布式对象存储的操作,以及它们如何受到我们的架构的关键特性的影响。我们也描述了原型的状态。

3 Client Operation(客户端操作)

3.1File I/O and Capabilities

        当一个进程打开一个文件时,客户端就向MDS cluster(元数据服务器集群)发送一个请求。一个MDS遍历系统来将文件名转换成文件索引(file inode),其中包含了文件的一些信息。如果这个文件存在并且访问已经被授权,MDS就将该文件的索引节点号(inode number)、文件大小、和将文件转换成对象的方法(striping strategy)返回。MDS也可以授予客户端一些他目前还不具有的权限,即客户端可以做哪些操作,目前包括:读,缓存读,写,缓冲写四个。

        ceph归纳了很多将文件数据转换成一些对象的条带化策略。为了避免对文件分布元数据的使用,对象的名字也简单地由文件索引号(inode number)和条带号来组成。

什么是条带化:背景:当多个进程同时访问一个磁盘时,会出现磁盘冲突,排队访问,性能低。条带法:把连续的数据分割成相同大小的数据块,把每段数据分别写入到阵列中的不同磁盘上的方法。(多路并行)多个物理磁盘条带逻辑上组合成一体(一个卷)。

之后对象的副本就由大名鼎鼎的CRUSH算法来分配到OSD中。例如,如果一个或多个客户端打开一个文件进行读取 访问,MDS 将授予它们读取和缓存文件内容的能力,并且返回索引号、文件大小、条带化方法等返回。这样客户端就可以组成对象名,然后直接从OSD集群中找到并读取所有包含该文件数据的对象。类似的,如果一个客户端想写入文件,他被授予缓冲写的能力,他在文件如何偏移处做出的修改都会简单地被写到适当OSD的适当对象中。

3.2 Client Synchronization

        POSIX 语义合理地要求读操作反映以前写入的任何数据,并且写操作是原子性的(即,重叠、并发写操作的结果将反映特定的发生顺序)。当一个文件被很多读写混合的客户端打开,MDS就会收回之前授予的所有读写端粒,强制让该文件的客户端IO同步。也就是说所有读写的应用都会被阻塞直到被OSD确认。这种方法有效的将更新序列化和一致性的负担交给了储存每个对象的OSD。当写入跨越对象边界时,客户端获得受影响对象上的独占锁(由它们各自的 OSD 授予),并立即提交写入和解锁操作以实现所需的序列化。对象锁同样用于通过异步获取锁和刷新数据来掩盖大型写入的延迟。

        同步IO会毫不意外地成为性能杀手,特别是哪些做少量读写的应用,因为你至少会有一次与OSD的往返交互。因此,在应用程序 不依赖一致性的情况下,以牺牲严格的标准一致性为代价来放松一致性通常是可取的。尽管 Ceph 通过 全局开关支持这种放松,并且许多其他分布式文件系统也在这个问题上犹豫不决,但这是一个不精确且不令人满意的解决方案:要么性能受损,要么系统范围内的一致性丧失。

        正是因为这个原因,高性能计算(HPC)社区已经提 出了一组针对 POSIX I/O 接口的高性能计算扩展,其中一部分由 Ceph 实现。

        ......

        Ceph 同步模型通过同步 I/O 在客户端之间提供正确的读写和共享写语义,并扩展应用程序接口以放宽对性能要求较高的分布式应用程 序的一致性,从而保持了其简单性。

3.3 Namespace Operations

        客户端与文件系统命名空间(file system namespace)的交互是由元数据服务器集群管理的。读取和更新都由MDS来一致地执行,为了保证串行化、一致性、正确的安全性和安全性。

namespace是什么?

存储系统中的namespace指的是该系统中name的集合。比如:

  • 在非层次化的存储系统中,namespace可以理解为所有的文件/对象名;
  • 在层次化的存储系统(如文件系统)中,除了文件名、目录名外,还包括他们之间隐含的父子关系。

此外,文件/对象的其它属性信息,如权限、大小等信息,也往往被认为是namespace的一部分

        Ceph对最常见的元数据访问场景做了优化。一个readdir后面跟着每个文件的stat(比如 ls -l)是非常常见的语句并且在大的目录里是性能杀手。而在cpeh中,一个readdir命令仅仅需要一个简单的MDS请求,它可以获取整个目录包括索引节点(inode)的内容。默认情况下,如果 readdir 后面紧跟着一个或多个 stats,则返回短暂缓存的信息;否则它将被丢弃。虽然这稍微放松了一致性,因为中间的节点内修改可能会被忽略,但我们很乐意做出这种交易来大大提高性能。readdirplus 扩展显式地捕获了这种行为,它返回带有目录条目的 lstat 结果(就像 getdir 的一些特定于操作系统的实现已经做的那样)。

        Ceph本可以通过长时间的缓存元数据来进一步放松一致性,就像早期版本的 NFS 一样,通常缓存 30 秒。然而,这种方法在某种程度上破坏了一致性,这对应用程序来说经常是非常关键的。例如那些使用 stat 来确定文件是否被更新的应用程序,它们要么行为不正确,要么等待旧的缓存值超时。

        我们选择再次提供正确的行为,为了返回正确的文件大小和修改时间,MDS会收回所有的写授权,来停止更新,收集最新的大小和改动时间。stat返回最高的值,然后重新授权。尽管停止一大批的写活动看起来有些极端,但是为了保证适当的可串行性这是必要的。

4 Dynamically Distributed Metadata(动态分布的元数据)

        源数据操作经常占据了文件系统工作的一半,并且处于关键路径中,这就让MDS集群对整体系统的表现很重要。Ceph 中的文件和目录元数据非常小,几乎全部由目录条目(文件名)和索引节点(80 字节)组成。与传统的文件系统不同,不需要文件分配元数据——对象名使用索引节点号构建,并使用 CRUSH 分发到 OSD。这简化了元数据工作负载,并允许我们的 MDS 高效地管理非常大的文件工作集,而与文件大小无关。

4.1 Metadata Storage(没读懂)

        尽管 MDS 集群旨在满足来自其内存缓存的大多数请求,但为了安全起见,元数据更新必须提交到磁盘。一组大的、有界的、延迟刷新的日志允许每个MDS 以高效和分布式的方式将其更新的元数据快速流式传输到 OSD 集群。每个MDS的日志都有数百mb,并且会重复的吸收元数据的更新,这样当旧的日志条目最终被刷新到长期存储中时,许多就已经过时了。虽然我们的原型尚未实现 MDS 恢复,但日志的设计使得在发生 MDS故障时,另一个节点可以快速重新扫描日志,以恢复故障节点的内存缓存中的关键内容(用于快速启动),并在此过程中重新覆盖文件系统状态。

        这种策略提供了两个最好的结果:用高效的方式将流式更新传到磁盘,并大大减少了重写的工作负载,从而允许为了未来的读取来优化在磁盘上长期存储的布局。特别的,索引节点直接内嵌在目录中,允许MDS通过单个的OSD请求来获取整个目录,并且利用了大多数工作负载中存在的高度目录局部性。每个目录中的内容被使用与元数据日志和文件数据相同条带化策略和分配策略写入到OSD集群中。

4.2 Dynamic Subtree Partitioning

        我们的主副本缓存策略让单个授的MDS负责管理缓存一致性,并序列化任何给定元数据的更新。虽然大多数现有的分布式文件系统使用一些基于静态子树的划分去委托这些权限(经常迫使管理员将数据集切割成更小的静态“卷”),但是一些最近的和实验性的文件系统已经使用哈希函数来分配目录和文件的源数据,有效的减少了负载的局部性。这两种方法都由局限性:静态子树分区无法处理动态工作负载和数据集,而哈希算法破坏了元数据的局部性和有效的元数据预取和存储的关键机会。

        Ceph的MDS集群是基于动态子树划分的策略,该策略会自适应地将缓存的元数据分配到一些节点上。每个MDS都会使用一个指数衰减的计数器来测量目录分层结构中农元数据的流行度。任何的操作都会让该操作影响的节点和该节点上溯一直到根目录的所有节点的计数器增加,从而为每个MDS提供一个描述近期负载分布的加权树。

     

Ceph会根据当前的工作负载,动态地将目录层次结构的子树映射到元数据服务器。只有当单个目录成为热点时,它们才会跨多个节点进行散列)  

MDS负载值会被定期的比较,并且适当大小的子树会被迁移,用于让负载均衡分布。

4.3 Traffific Control

        跨多个节点来划分目录层次结构可以平衡各种工作的负载,但是不是总可以应对多个客户端访问一个目录或者文件的热点地区。ceph利用它关于元数据流行度的知识仅仅在需要时为热点提供广泛的分布,并且在一般情况下不会导致相关的开销和目录局部性的损失。频繁读取的目录(例如,许多打开的目录)的内容被选择性地跨多个节点复制,以分布负载。特别大或经历繁重写入工作负载(例如,许多文件创建)的目录在群集中按文件名对其内容进行哈希处理,以牺牲目录本地性为代价实现平衡分布。这种自适应的方法允许 Ceph 包含广泛的分区粒度,在特定的环境和文件系统中这些策略最有效的部分,获取粗分区和细分区的优点。

        每个MDS响应都会将有关于授权和相关索引节点及其祖先的副本的更新信息提供给客户端,使得客户端可以了解与他们交互的那一部分文件系统中元数据的分布。通常,客户知道不受欢迎的(未复制的)元数据的位置,并且能够直接联系适当的 MDS。然而,访问流行元数据的客户机被告知元数据驻留在不同的或多个 MDS 节点上,这有效地限制了相信任何特定元数据驻留在任何特定 MDS 上的客户机的数量,从而在潜在的热点和闪光人群出现之前将其驱散。

5 Distributed Object Storage(分布式对象存储)

        在高层次来看,Ceph客户端和元数据服务器将整个对象存储集群(很可能有几万或几十万个OSD)视为单个的逻辑对象存储和命名空间。Ceph的可靠的自主分布式对象存储(RADOS)以分布式的方式将对对象复制,集群扩张,失败检测和恢复的管理委托给OSD,从而实现了在容量和聚合表现方面的线性扩展。

5.1 Data Distribution with CRUSH

        Ceph必须在由数千个存储设备组成的集群中分发pb级别的数据,从而有效的利用存储和带宽资源。为了避免不平衡(新加入的设备几乎都是空闲的或者空的)和负载的不对称(热点数据只在新加入的设备上),我们采用随机分配新数据的策略,将现有数据的随机子样本迁移到新的设备,并统一地重新分配来自被移除设备的数据。这种随机方法是稳健的,因为它在任何潜在的工作负载下都表现得一样好。

        Ceph首先利用一个简单的哈希函数将对象(object)映射到放置组(pgs)中,并使用一个可调的位掩码来控制 pg 的数量。我们选择给每个OSD100个pg来平衡 OSD 利用率的变化和每个 OSD 维护的复制相关元数据的数量。然后使用CRUSH来将pgs分配给OSD。这与传统的方法不同,因为数据的放置没有依赖任何块或者对象表的元数据。CRUSH仅仅需要放置组(pg)和一个OSD集群图(对组成存储集群的设备的一种紧凑的分层描述)来定位任何的对象。这种方法有两个主要的优点:首先,它是完全分布式的,任何一方(客户端,OSD,MDS)都可以独立的计算对象的位置。其次,OSD集群图很少更新,实际上消除了任何与分布相关的元数据的交换。这样CRUSH就同时解决了数据分布和数据定位的问题。通过这样设计,存储集群的小改变对于已经存在的pg映射影响很小,因此由于设备失效或者集群扩张而引起的数据迁移被最小化了。

一个PG负责若干个object(可以为数千个甚至更多),但一个object只能被映射到一个PG中,即,PG和object之间是一对多映射关系。同时,一个PG会被映射到n个OSD上,而每个OSD上都会承载大量的PG,即,PG和OSD之间是多对多映射关系

        集群图的层次结构被设计成与集群的物理或者逻辑组成和潜在的故障源一致。比如,一个集群可能会形成一个四层的结构:OSD组成shelves,shelves组成cabinets,cabinets组成rows。每个OSD也拥有一个加权值来控制分配给它数据的相对量。CRUSH 基于放置规则(placement rules)将 pg 映射到OSD,布局规则定义了复制的级别和对布局的任何约束。例如,可以在三个 OSD 上复制每个 PG,这三个OSD 都位于同一row(以限制行间复制流量),但被分隔到不同的cabinet中(以最大限度地减少电源电路或边缘交换机故障的风险)。集群图还包括停机或不活动设备的列表和纪元编号,该编号在每次集群图改变时递增。所有 OSD 请求都标记有客户端的地图纪元号,以便各方能够就当前的数据分发达成一致。增量地图更新在协作的 OSD 之间共享,并且如果客户端的地图过时,则搭载在 OSD 回复上。

5.2 Replication

        与假设用户可以使用 RAID 或 SAN 上的故障转移等机制构建足够可靠的 OSD的Lustre系统不同,我们假设在pb级别的系统中故障的发生会是正常情况而不是例外,并且在任何时间点一些OSD都可能会变得无法操作。为了以可扩展的方式维护系统和保证数据安全,RADOS使用主副本复制(primary-copy replication)的方法来管理他的数据副本,同时也采取措施把对性能的影响降到最低。

        数据是按照pg进行复制的,而每个pg被映射到n个OSD上(也就是n路复制)。客户端将所有的写内容发送给这个对象的pg对应的第一个可用的OSD上(也就是主副本),这将为这个对象和PG分配新的版本号然后将写的内容提交到其他的副本OSD。在每个副本都实施了更新并且向主副本回应之后,主副本在本地实施更新,让向客户端确认写操作已经完成。读操作直接在主副本上做。这种方法使得客户端免除了围绕副本的串行化和一致性的任何复杂操作,这些操作在当有其他写入者或者故障恢复的时候可能是繁重的。这种方法同时也将复制的带宽消耗由客户端转向了OSD集群的内部网络,我们觉得在那里有更多的资源可以利用。中间副本OSD的故障是可以忽略的,因为任何后续的恢复都会可靠的重建副本的一致性。

5.3 Data Safety

        在分布式存储系统中,数据被写到共享存储上主要有两个原因:首先,客户端对让他们自己的更新被别的客户端看见是很感兴趣的。这个应该很快,因为写入的内容应当被尽可能快的看到,特别是当很多的写和读者混合的时候,会强制让客户端去同步地操作。第二,客户有兴趣知道他们写入的数据被安全的复制到了磁盘,并且在断电或者别的故障下会很安全。RADOS在确认更新的时候将同步和安全分离,允许 Ceph 实现高效应用同步的低延迟更新和定义良好的数据安全语义。

 (在所有复制对象的 OSD 上的缓冲区缓存中写入数据后,RADOS 以 ack 响应。只有在安全提交到磁盘后,才会向客户端发送最终提交通知

        图4描述了在一个对象的写入期间发送的信息。主副本将更新传递到别的副本,并在更新应用到所有OSD 的内存缓冲区缓存后回复一个 ack。当数据被安全的提交到磁盘之后,一个最终的确认就提交了(可能会在很多秒之后)。我们仅在更新完全复制后才向客户端发送 ack,以无缝容忍任何单个 OSD 的故障,即使这增加了客户端的延迟。默认情况下,客户端还会缓存写入的数据,直到提交(commit),以避免在放置组中的所有 OSD 同时断电的情况下丢失数据。在这种情况下进行恢复时,RADOS允许在接收新的更新之前 回滚之前已经确认过的更新。

5.4 Failure Detection

        即时的故障检测对于保持数据安全是很重要的,但是当一个集群扩展到数千台设备之后这也是很困难的。OSD可以自动报告一些特定的错误,比如磁盘错误或者数据冲突。但是一些让OSD在网络上无法访问的错误需要主动的监控,RADOS通过让每个OSD来监控那些与他共享PGs的同等OSD(peers)来实现。在大多是情况下,现有的复制流是对OSD活跃的被动确认,并没有额外的通信开销。如果一个OSD最近都没有从一个peer收到消息,就会发送一个明确的ping。

        RADOS考虑到OSD活跃的两个维度:OSD是否可达、OSD是否被CRUSH分配了数据。一个没有反应的OSD最初被标记为“down”,然后任何主要的责任(更新,序列化,复制)都被暂时的传递给他的每个放置组的下一个OSD。如果这个OSD没有很快的恢复过来,他在数据分布里就被标记为“out”,然后另一个OSD会加入它的每个pg去重新复制它的内容。对故障OSD有未完成操作的客户端只需向主OSD重新提交操作即可。

        因为有各种各样的网络异常会导致OSD连接的间接性中断,所以有一小组监视器收集故障报告,并集中过滤掉瞬时的或者系统的问题(例如网络中断)。监控器(仅部分实现)使用选举、主动对等监控、短期租赁和两阶段提交来共同提供对集群图的一致且可用的访问。当这个集群图被更新来反应任何的故障或者恢复时,被影响的OSD将被提供递增的集群图更新,该更新搭载在现有的OSD内部通信上而在整个集群中传播。分布式检测允许快速检测,并且不会过度加重监视器的负担,同时解决了与集中式仲裁不一致的情况。最重要的是,RADOS 通过将 OSD 标记为 down 而不是 out(例如,在一半的 OSD 断电后),避免了由 于系统问题而引发的大范围数据复制

5.5 Recovery and Cluster Updates

        OSD集群图会由于OSD故障、OSD恢复和明确的集群变化(如新存储的部署)儿改变。Ceph用相同的办法处理所有这些改变。为了方便快速的恢复,OSDs会为每个对象维护一个版本号,为每个PG维护一个最近改变的日志。

        当一个活跃的OSD收到更新的集群图,它遍历所有本地存储的pg,并计算CRUSH映射,以确定它负责哪个放置组,作为主还是副本。如果一个pg的成员发生了变化,或者这个OSD刚刚启动,这个OSD必须和此pg的其他OSD进行比对。对于复制的PG(replica),OSD向主PG提供其当前PG的版本号。如果 OSD是PG的主副本,它将收集当前(和以前)副本的PG版本。如果主节点缺少最新的 PG 状态,它会从 PG中的当前或先前 OSD 中检索最近 PG 更改的日志(或完整的内容摘要,如果需要的话),以确定正确的(最新的)PG 内容。然后主副本给其他副本发送增量日志更新(或完整的内容摘要,如果需要的话),这样各方都知道这个PG的内容应当是什么样子,即使可能跟他们本地储存的对象不匹配。只有在主服务器确定了正确的 PG 状态并与任何副本服务器共享该状态后,才允许对 PG 中的对象进行 I/O 操作。OSD们之后独立负责从他们的对等OSD中检索丢失或者过时的对象。如果一个OSD收到一个过时或者丢失对象的请求,它会延迟处理该请求并将该对象放到恢复队列的最前面。

        例如,假设 osd1 崩溃并被标记为down,osd2 接管pgA 的主服务器。如果 osd1 恢复,它将在启动时请求最新的地图,监视器会将其标记为up。当 osd2接收到最终的map更新时,它将意识到它不再是pgA 的主副本,并将 pgA 版本号发送给 osd1。osd1将从 osd2 检索最近的 pgA 日志条目,告诉 osd2 其内容是最新的,然后开始处理请求,同时所有被更新的对象会在后台恢复。

     因为故障恢复完全是由单个 OSD 驱动的,所以受故障 OSD 影响的每个 PG 将平行于不同的代替的OSD 。这种方法基于快速恢复机制(FaRM) ,减少了恢复时间,提高了整体数据安全性。

5.6 Object Storage with EBOFS

        没看懂......

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值