Ceph论文阅读翻译:RADOS: A Scalable, Reliable Storage Service for Petabyte-scaleStorage Clusters

ABSTRACT

        基于块和对象的存储架构已经成为提升存储集群可扩展性的一种手段。然而,现有的系统仍然将存储节点视为被动的设备,尽管他们能够表现出显著的智能和自主性。我们提出了RADOS的设计和实现,RADOS是一个可靠的对象存储服务,它可以通过利用单个存储节点中的智能从而扩充到大量的设备。RADOS 保留了一致的数据访问和强大的安全语义,同时允许节点通过使用小型集群图半自动地自我管理复制、故障检测和故障恢复。我们的实现有很强的性能、可靠性和可扩展性,并且为客户提供了在使用单一(逻辑上)对象存储的错觉。

1. INTRODUCTION

        提供可靠的、高性能、可扩展的存储一直是系统设计者的挑战。用于文件系统、数据库和相关系统的高吞吐率和低延迟的存储对于很多应用是非常重要的。由存储块或者对象存储设备构建的新兴存储架构想要将低级的块分配的决策和安全策略的执行分配给智能的存储设备,从而通过客户端直接访问数据来简化数据的布局、消除IO瓶颈。由商用组件构建的 OSD 将 CPU、网络接口和本地高速缓存与底层磁盘或 RAID 相结合,并用基于命名的可变长度对象的接口取代了传统的基于块的存储接口。

        然而,使用这种架构的系统很大程度上没有利用设备的智能。在基于本地或网络连接(SAN)磁盘驱动的传统存储系统中,或者在采用 T10 OSD 标准的存储系统中,设备被动地响应读和写命令,尽管它们有封装强大智能的潜力。当存储集群扩展到上千个设备或者更多时,持续的数据放置、故障检测和故障恢复的管理就会越来越成为客户端、控制器或者元数据节点的负担,限制了系统的可扩展性。

        我们设计并实现了RADOS,一个可靠的、自动分布的对象存储,旨在利用设备智能来分散在由大量存储设备组成的集群中数据访问、冗余存储、故障检测和故障恢复等问题的复杂性。作为Ceph分布式文件系统的一部分,RADOS 促进了数据和工作负载在动态异构存储集群中的不断发展、平衡的分布,同时为应用程序提供了一个具有良好定义的安全语义和强大一致性保证的单一逻辑对象存储的幻觉。

        在pb级别上,系统必然是动态的:他们是增量构建的,系统随着新存储的部署和旧设备的退役而增长和收缩,设备不断出现故障和恢复,大量数据被创建和销毁。RADOS 通过使用版本化的集群图来确保数据分布的一致视图以及对数据对象的一致读写访问。该集群图由各方(存储和客户端节点等)复制,并通过lazily传播少量增量更新来更新。

        通过向存储节点提供系统中数据分布的完整信息,设备可以使用类似点对点的协议半自动地完成我管理数据复制,一致且安全地处理更新,参与故障检测,并对设备故障和重新复制或者迁移数据对象所导致的数据分布的改变做出反应。这减轻了小型监控集群的负担,该集群管理集群图的主要副本,并通过它管理存储集群的其余部分,从而使系统能够从几十台设备无缝扩展到几千台设备。

       我们的原型实现公开了一个对象接口,可以在其中读取或写入字节范围(很像一个文件),因为这是我们对Ceph 的最初要求。数据对象被跨多个 OSD n路复制以防止节点故障。然而,RADOS 的可伸缩性绝不依赖于特定的对象接口或冗余策略;存储键/值对的对象和基于奇偶校验(RAID)的冗余都在计划之中。

2. SCALABLE CLUSTER MANAGEMENT

       RADOS 系统由大量的 OSD 和一小组负责管理 OSD 集群成员的监视器组成(图 1)。每个 OSD 包括一个 CPU、一些易失性 RAM、一个网络接口和一个本地连接的磁盘驱动器或 RAID。监视器是独立的进程,需要少量的本地存储。

 2.1 Cluster Map

        存储集群是由monitor集群对于集群图的操作老专门管理的。cluster map指定了哪些OSD在集群中,并且简洁地指定了系统中所有数据在这些设备上的分布。集群图被每个存储节点以及与RADOS集群交互的客户端复制。由于集群映射完全指定了数据分布,所以客户端公开了一个简单的接口,该接口将整个存储集群(可能有数万个节点)视为单个逻辑对象存储。

        每当一个OSD的状态改变或者其他影响到数据分布的时间导致集群图改变时,该图的epoch就增加。epoch让交流的各方可以就当下的数据分布情况达成一致,并且也决定了何时他们自己的数据会(相对)过时。由于在非常大的系统中OSD的故障和恢复是很正常的,集群图的变化可能是频繁的。因此更新被分解成增量映射:描述两个连续epoch之间差异的小型消息。在大多数情况下,这种更新简单地说明一个或多个 OSD 出现故障或已恢复,尽管通常它们可能包括许多设备的状态变化,并且多个更新可能被捆绑在一起以描述epoch差距很大的的的集群图之间的差异。

2.2 Data Placement

            RADOS使用了一种数据分发策略,将对象伪随机地分发给设备。当新的存储设备增加到系统,现有数据的随机子样本会被迁移到新的设备来恢复平衡。这种策略是健壮的,因为它保持了概率上平衡的分布,平均来说,使所有设备保持类似的负载,允许系统在任何潜在的工作负载下都表现良好。最重要的是,数据放置是一个计算对象正确位置的两阶段过程;不需要大型或笨重的集中分配表。

        被系统存储的每个对象都先被映射到一个placement group (PG)中,pg是被同一组设备所复制的对象的逻辑集合。每个对象的pg由以下内容的哈希函数决定:对象名o,需要的复制等级r,控制系统中pg总数的二进制掩码m。也就是说pgid = (r, hash(o)&m),其中&是按位的与,掩码 m = 2^{k}-1,将 pg 的数量限制为 2 的幂。当集群扩张时,有必要周期性地通过改变m的值来控制pg的总数;这是逐渐完成的,以抑制设备之间的 pg 迁移。

        pg基于集群图被分配到OSD上,集群图将每个pg映射到一个有序的OSD列表,在那里存储对象的副本。我们的实现采用了CRUSH,一种健壮的副本分发算法,可以计算稳定的伪随机映射。从高层次来开,CRUSH的香味与哈希函数类似:pg的位置是确定的,但却是伪随机分布的。但是与哈希函数不同,CRUSH是稳定的:当一个(或者很多)设备加入或者离开集群时,大多是的pg会留在原位;CRUSH仅仅移动足够的数据来保持分布的均衡。相反的,哈希函数通常会强制重新排列所有先前的映射。CRUSH 还根据设备的容量或性能,使用权重来控制分配给每个设备的相对数据量。

        pg提供了一个控制副本去集群化级别的方法。与一个OSD向其他对象共享它的所有副本(mirroring)或者将每个对象与不同的设备共享(完全去集群)不同,replication peers的数量与它存储的 pg 数量 u 是相关的——通常每个OSD大约有100个 pg 。因为分布是随机的,所以也会影响设备利用率的变化:每个 OSD 更多的 pg 会导致更平衡的分布。更重要的是,通过允许每个PG被独立地从不同的OSD重新复制,去集群化有助于分布式的、并行的故障恢复。同时,系统可以通过限制每个设备能够共享公共数据的OSD的数量来减少该设备暴露于同时发生的设备故障的风险。

2.3 Device State

        集群图包括了有关于数据分布在其中的设备的描述和当前的状态。这包括当前在线且可达(up)的所有 OSD 的当前网络地址,以及哪些设备当前关闭(down)的提示。RADOS 考虑了 OSD 活跃的一个额外维度:in状态的 设备被包括在映射和分配的pg中,而 out 设备不包括在内。

        OSD状态应处于集群内(in)、集群外(out),并且处于运行(up)或关闭(down)。如果OSD处于up,他可能位于集群中(可以读写数据),也可能不在集群中。如果OSD原本在集群中但是最近被移除了集群,ceph会将整个PG移动到其他OSD中。如果OSD不在集群中,则CRUSH不会将PG分配给OSD。

         对于每个PG而言,CRUSH会生成一个准确的在集群中(in)的OSD列表。然后,RADOS 过滤掉down 的设备,为 PG 生成活动 OSD 列表。如果活动列表当前为空,PG 数据暂时不可用,未完成的 I/O 被阻塞。

        OSDs通常在集群中既up又in,可以正常提供IO服务,或者当他们出现故障的时候会既down又out,因此产生一个正好是r个的OSD活动列表。OSD 也可能是down,但仍在集群中(in),这意味着它们当前不可访问,但PG 数据尚未重新映射到另一个 OSD。同样的,他们可能既up又out,这意味着他们在线但处于闲置状态。这有助于各种情况,包括可以在不启动任何数据迁移的情况下容忍不可用的间歇周期(例如,OSD 重启或网络中断),能够使新部署的存储在线而不立即使用(例如,允许测试网络),以及能够在旧设备退役之前安全地从旧设备中迁移数据。

2.4 Map Propagation

        由于RADOS可能包含数千个甚至更多的设备,简单地将更新向各方广播是不现实的。幸运的是,集群图不同epoch之间的差异只有当期存在于两个正在交流的OSD之间(或者一个客户端一个OSD)才是很重要的,这两个OSD 必须就它们相对于 I/O 引用的特定 PG 的适当角色达成一致。这一特性允许 RADOS 通过将地图更新与现有的OSD 间消息相结合来延迟发布map更新,这有效地将负担交给了OSD。

        每个OSD 维护过去的集群图的增量更新的历史,用自己最新的epoch标记自己的所有消息,并且跟踪每个peer上观察到的最新的epoch。如果一个OSD收到持有旧的epoch的peer的信息,它将共享必要的增量以使该对等体同步。相似的,当主动联系一个持有旧的epoch的对等体时,增量更新被先共享。为故障检测而定期交换的心跳消息确保了更新的快速传播,对于 n 个 OSD 的集群来说,更新在 O(log n)时间内完成。

        例如,当一个 OSD 第一次启动时,它首先通知一个监视器,该监视器已经与一个 OSDBoot 消息联机,该消息包括其最近的地图纪元epoch。监控集群将 OSD 的状态更改为 up,并回复必要的增量更新以使 OSD 完全更新。当新的 OSD 开始联系与其共享数据的 OSD 时,受其状态改变影响的确切设备集合了解适当的地图更新。因为正在引导的 OSD 还不知道它的对等体拥有哪个纪元,所以它共享一个安全的最近增量更新历史(至少 30 秒)。

        这种抢先地图共享策略是保守的:OSD 在联系对等体时将总是共享更新,除非它确定对等体已经看到它,这导致 OSD 接收相同更新的副本。然而,OSD 接收的副本数量受到它拥有的对等体数量的限制,而对等体数量又由它管理的 pg 数量决定。实际上,我们发现更新复制的实际水平比这低得多。

3. INTELLIGENT STORAGE DEVICES

        集群映射中封装的数据分布知识允许 RADOS 将数据冗余、故障检测和故障恢复的管理分配给组成存储集群的 OSD。这通过在高性能集群环境中利用类似点对点的协议来利用 OSD 中的智能。

        RADOS目前为每个pg实现了n向复制和每个对象的版本与短期日志的结合。复制是由OSD他们自己进行的:客户端将一个写操作提交给第一个主OSD,主OSD负责一致和安全地更新所有副本。这将与复制有关的带宽转移到了存储集群的内部网络,并简化了客户端的设计。对象版本和短期日志有助于在间歇性节点故障(例如,网络断开或节点崩溃/重启)的情况下快速恢复。

        我们将简要描述 RADOS 集群架构(尤其是集群映射)如何支持分布式复制和恢复操作,以及如何将这些功能推广到包括其他冗余机制(如基于奇偶校验的 RAID 代码)。

3.1 Replication

        RADOS实现了三种复制的策略。主拷贝(primary copy),链式(chain)和一个我们称之为splay的混合方式。在更新过程中的消息传递如图2所示。在所有情况下,客户端将 I/O 操作发送到单个(尽管可能不同)OSD,并且群集确保副本被安全地更新,并且保持一致的读/写语义(即,可串行化)。所有副本更新后,将向客户端返回一个确认信息。

        Primary的方式平行地更新所有副本,并且读和写操作都是在primary OSD进行的。相反,chain方式以串行更新副本:写操作被发送给主OSD(头节点),读操作发送到尾节点,确保读操作始终反映完全复制的更新。splay复制只是将primary复制的并行更新与chain复制的读/写角色分离结合起来,主要优势是双向镜像的消息跃点数较少。

3.2 Strong Consistency

        所有的消息—来自客户端和其他OSD的消息—都标有发送方的 map epoch,以确保以完全一致的方式应用所有更新操作。如果一个客户端由于过时的map而吧IO请求发给了错误的OSD,该OSD会回应适当的增量,从而让客户端可以重定向请求。这避免了主动与客户端共享地图更新的需要:客户端将在与存储集群交互时了解地图更新。在大多数情况下,他们将了解到不影响当前操作的更新,但允许未来的 I/o 被准确地定向。

        如果集群图的主副本已经被更新以改变一个特定PG的成员身份,在旧成员没有听闻改变的情况下,更新操作可能还是由旧成员来处理的。如果这个改变被一个pg的副本发现了,首先,当主OSD 将更新转发给副本,并且副本使用新的增量映射更新进行响应时,就会发现这一点。这是完全安全的,因为任何对一个pg负责的新OSD都需要联系所有以前负责的(非故障)节点,以便确定 PGs 的正确内容;这就确保了之前的OSD知晓变化并且在新负责的OSD启动之前停止IO行为。

        与更新相比,读操作实现类似的一致性稍微不太自然。如果网络故障导致 OSD 变得仅部分不可访问,那么对 PG 的 OSD 服务读取可能被声明为“失败”,但是仍然可以被具有旧 map 的客户端访问。同时,更新的集群图可以在其位置指定新的 OSD。为了防止在新的OSD已经处理了新的更新之后,还有读操作在旧OSD上执行,我们需要每个PG 中 OSD 之间的及时心跳消息,以便 PG 保持可读。也就是说,如果 OSD 服务读取在 H 秒内没有收到来自其他副本的消息,读取将会阻塞。在另一个 OSD 接管 PG 的主要角色之前,它必须从旧 OSD 获得肯定的确认(确保它们知道它们的角色变化),或者延迟相同的时间间隔。在当前的实现中,我们使用两秒钟的相对较短的心跳间隔。这确保了及时的故障检测,并且在主OSD故障之后PG的数据只有短时间的不可访问。

3.3 Failure Detection

        RADOS 采用异步、有序的点对点消息传递库进行通信。TCP 套接字上的故障会导致在向监视器集群报告故障之前进行有限次数的重新连接尝试。存储节点与其对等节点(与它们共享 PG数据的 OSD)定期交换心跳消息,以确保检测到设备故障。发现自己标记为down的 OSD 只需同步到磁盘,然后自我销毁以确保一致的行为。

3.4 Data Migration and Failure Recovery

        RADOS数据迁移和故障恢复完全由集群图的更新和将pg映射到 OSD 的后续更改驱动。这种改变可能是由于设备故障、恢复、集群扩展或收缩,或者甚至是来自全新的CRUSH副本分布策略的完全数据重新洗牌——设备故障仅仅是在存储集群上建立新的数据分布的普遍问题的许多可能原因之一。

        RADOS 对一幅map和下一幅map之间的数据分布没有连续性假设。在所有情况下,RADOS 都采用强大的peering算法来建立 PG 内容的一致视图,并恢复数据的正确分发和复制。这种策略依赖于基本的设计前提,即 OSD 积极地复制 PG 日志及其关于 PG 的当前内容应该是什么的记录(即,它包含什么对象版本),即使对象副本可能在本地丢失。因此,即使恢复速度很慢,对象安全性有时会下降,PG 元数据也会得到精心保护,从而简化了恢复算法并允许系统可靠地检测数据丢失。

3.4.1 Peering

        当一个OSD收到集群的更新时,它遍历直到最近以来所有新的地图增量,以检查并可能调整PG的状态值。任何其OSD活动列表改变了的本地PG都被标记成必须重新对等(re-peer)。考虑所有地图时期(不仅仅是最近的)确保了中间的数据分布被纳入考虑中:如果从 PG 中移除 OSD,然后再次添加,重要的是要意识到可能已经发生了对 PG 内容的中间更新。与复制一样,对等(peering)(以及任何后续恢复)对系统中的每个 PG独立进行。

        Peering由PG中的第一个OSD驱动(primary)。对于OSD存储的每个并不是当前primary的PG,一个通知信息(Notify message)发送到目前的primary主副本。该消息包括关于本地存储的 PG 的基本状态信息,包括最近的更新、PG 日志的界限以及已知的PG 成功peer的最新时期。(epoch)。Notify message 确保了 一个PG 的新primary认识到自己的角色和任务,而不必为每次地图改变考虑所有可能的 PG(可能有数百万个)。一旦意识到,主节点将生成一prior集合,其中包括自上次成功对等以来可能已加入 PG 的所有 OSD。显式地查询prior集合以请求通知,从而避免无限期地等待实际上没有存储 PG 的prior OSD(例如,如果对于中间 PG 映射,对等从未完成)。

        有了整个prior集合的 PG 元数据,primary可以确定应用于任何副本的最新更新,并从prior的 OSD 请求任何必要的日志片段,以便使 PG 日志与活动副本保持最新。如果可用的 PG 日志不足(例如,如果一个或多个 OSD 没有PG 的数据),则生成完整的 PG 内容列表。但是,对于节点重新启动或其他短暂中断,这是不必要的—最新的PG 日志足以快速重新同步副本。

        最后,主 OSD 与副本 OSD 共享丢失的日志片段,以便所有副本都知道 PG 应该包含什么对象(即使它们在本地仍然丢失),并在恢复在后台进行时开始处理 I/O。

读了几遍还是有些疑惑。peering过程的大概意思就是,负责一个PG的所有非primary的OSD给primary发消息,包含一些信息。有了这些信息之后primary就能确定所有与PG有关的OSD,获取日志信息,确定该PG应当包含什么内容。这样就可以恢复数据了。重点就是前面说的,OSD会积极的保存PG的日志信息。

3.4.2 Recovery

        去集群复制的一个关键优势是能够并行执行故障恢复。与任何单个故障设备共享的副本分布在许多其他 OSD上,每个 PG 将独立选择一个替代品,允许复制到更多的 OSD。平均而言,在一个大型系统中,任何涉及单个故障恢复的 OSD 将只推送或拉取单个 PG 的内容,使得恢复非常快。

        RADOS中这样恢复是由于我们观察到IO通常是收到读吞吐率的限制而不是写。尽管配备了所有 PG 元数据的每个 OSD 都可以独立地获取任何丢失的对象,这种策略还是有两个局限性。首先,在一个PG中的大量OSD独立地恢复对象,它们可能不会同时从同一个 OSD 中提取相同的对象,会导致恢复中最昂贵的部分——寻找和读取两个过程的重复。第二,如果副本OSD丢失了正在被修改的对象,那么更新复制协议就会变得越来越复杂。

        由于这些原因,RADOS中PG的恢复是由 primary 协调的。与前面一样,对丢失对象的操作会延迟,直到主对象有一个本地副本。由于主对象已经通过peering过程知道了所有副本所缺少的对象,它可以先发制人地“推送”任何即将被修改的丢失的对象到副本OSD中,简化复制逻辑,同时还确保对象的幸存副本只读取一次。如果 primary副本 push了一个对象(例如,响应拉请求),或者它只是为自己 pull 了一个对象,它总是将该对象推到所有需要此副本的replicaOSD中。因此,总的来说,每个重复复制的对象只被读取一次。

4. MONITORS

        一个小型的监控器集群存储集群图的主副本,并且针对配置改变或者OSD状态的改变做定期的更新,以此来管理存储系统。该集群部分基于Paxos算法,旨在支持一致性和持久性,而不是可用性和更新延迟。值得注意的是,为了读取或更新聚类图,大多数监视器必须可用,并且保证更改是持久的。

4.1 Paxos Service

        该集群基于基于 Paxos 的分布式状态机服务,其中集群图是当前的机器状态,并且每次成功的更新都会产新的集群图时期(epoch)。该实现稍微简化了标准 Paxos,一次只允许一个并发map 变化,同时将基本算法与允许请求指向任何监视器的租用机制相结合,同时确保一致的排序一读取和更新操作。
        集群最初会选举一个领导者来序列化地图更新和管理一致性。一旦当选,领导者开始请求由每个监视器存储的地图历元。监控器有固定的时间量 T(目前为两秒)来响应探测并加入法定人数,如果大多数监视器是活动的,
则 Paxos 算法的第一阶段确保每个监视器具有最近提交的 map 纪元epoch(根据需要从其他监视器请求增量更新),然后开始向活动的监视器分配短期租约。

        每个租约授权给活动的监视器可以将集群图的副本分发给需要的OSD和客户端。如果租期 T 到期而没有续签,则认为领导者已经死亡,并要求进行新的选举。每份租约在收到后都要向领导确认;如果在分发新的租约时,领导者没有收到及时的确认,则它假定活动的监视器已经死亡,并且调用新的选举(以建立新的法定人数)。当监视器第一次启动时,或者发现先前调用的选举在合理的时间间隔后没有完成,则调用选举。

        当活动监视器接收到更新请求(例如,失败报告)时,它首先检查它是否是新的。例如,如果有问题的 OSD 已经被标记为 down,监视器简单地用必要的增量地图更新来响应,以使报告的OSD 是最新的。新的故障被转发给领导者,领导者汇总更新。周期性地,领导者将通过增加地图历元和使用 Paxos 更新协议来发起地图更新,以将更新提议分发给其他监视器,同时撤销租约。如果更新被大多数监视器确认,则最终提交消息发布新的租约。

        同步两阶段提交和探测间隔 T 的组合确保了如果监视器的活动集改变,则保证所有先前的租约(具有匹配期限T)将在任何后续 map 更新发生之前会到期。因此,任何顺序的映射查询和更新都将导致映射版本的一致进展——重要的是,映射版本将永远不会“倒退”——不管向哪个监视器发送消息,也不管任何介于其间的监视器故障,只要大多数监视器可用。

4.2 Workload and Scalability

        在一般情况下,监视器做的工作很少:大多数 map 分发是由存储节点处理的,并且设备状态的改变(例如,由于设备故障)通常很少。

        监视器集群内部使用的租用机制允许任何监视器为请求集群图最新副本OSD 或的客户机的读取提供服务。由于抢先地图共享,这种请求很少来自 OSD,并且客户端仅在 OSD 操作超时并且怀疑失败时才请求更新。可以扩展监视集群,以便为大型集群分配这种工作负载(超出纯粹为了可靠性所必需的范围)。

        需要地图更新的请求被转发给当前领导者。引导者将多个变化聚集到单个地图更新中,使得地图更新的频率是可调的,并且与集群的大小无关。然而,当大量 OSD 在短时间内出现故障时,会出现最坏的负载情况。如果每个 OSD 存储u个pg,并且 f 个 OSD 发生故障,则所生成的故障报告数量的上限约为 uf,如果大型 OSD 集群经历网络分区,这可能会非常大。为了防止这样的消息泛滥,OSDs以半随机间隔发送心跳信息,以错开地检测故障,然后限制和批处理故障报告,对监视器集群负载施加一个与集群大小成比例的上限。非领导者监视器然后只转发任何给定故障的报告一次,这样对于有m个监视器的集群来说,领导者上的请求工作负载就与fm成正比。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值