RADOS:一种可扩展高可用的PB级存储集群(Ceph)

把Ceph的基础论文RADOS的原理介绍的前部分翻译了一下,与大家分享

-------------------------------------------------

摘要

基于对象的存储架构已经作为一种新的方法改进存储集群(Storage Clusters)的扩展性而出现。尽管存储节点已经表现得足够智能和自主,但现有的系统仍然将存储节点作为一种被动的设备(passive devices)。我们目前的设计和实现的RADOS,是一个可靠的对象存储服务,它通过利用多个独立的存储节点能够扩展到成千上万的设备集群。RADOS能够保持一致的数据访问和强大的语义安全,同时允许节点半自主地行动,通过使用一个小的Cluster Map实现自我管理复制、故障检测、故障恢复。我们的实现提供了出色的性能、可靠性和可扩展性,同时为客户提供了一个单一的逻辑对象存储的错觉。
介绍
提供可靠的、可扩展的高性能存储设计一直是一个挑战。高吞吐量和低延时的存储,对应文件系统、数据库以及其他相关抽象是很多应用性能的关键。新兴的集群存储架构基于对象存储设备(OSD)构建,通过发布存储设备的低级别的块分配策略和安全策略,使用户之间访问数据,以简化数据布局和消除IO瓶颈。OSDs是由一些带有CPU、网络接口、本地缓存以及磁盘或RAID的商用服务器构成,并将原有的通用的基于块的存储接口替换为具有名称的可变长度的对象。
然而,采用这种架构的很大程度上没有充分利用设备的职能性。那些基于本地或SAN磁盘设备或者那些遵照T10 OSD标准传统存储系统,设备都是被动的响应读取和写入的命令,尽管这些存储节点都具有潜在的职能。当存储集群达到成千上万或者更多时,一致的管理数据布局、错误检查和错误恢复,放置到客户端、控制器或者原目录节点就会越来越大,限制了扩展性。
我们设计和实现了RADOS,一种可靠的、自主的分布式对象存储,旨在利用设备的职能性将集群中成千上万的存储设备的一致性数据访问、存储冗余、错误检测和错误恢复的复杂性分布到各个存储节点上。作为内置于Ceph分布式文件系统的一部分,RADOS有利于不断演进,能够在动态和异构的存储集群环境中均衡分布式数据和工作负载,同时应用程序提供一个具有良好安全语义接口和很强一致性保证的单一楼价对象存储空间。
PB级别的存储系统必然是动态的,它们是增量建立的,逐渐增长伴随着新的存储部署和旧的设备退役,设备出现故障和恢复能够保持业务连续性的基础上,以及大量的数据创建和销毁。RADOS通过使用Cluster Map,能够保证一致的数据分布和一致数据对象的读取和写入。这个Cluster Map被保存在各个节点(存储和客户端节点),并且可以能够通过延迟传播作少量的增量更新。
通过提供存储节点完整的系统数据分布信息,设备就能够采用类似P2P协议完成自我管理数据副本,持续安全地处理更新,参与故障检测和应对设备故障和重新复制或迁移数据对象引起的数据分布的变化。这就减轻了减小的监控集群管理主副本Cluster Map的负担,存储集群就能够从几十到几千设备无缝地扩展。
我们的原型实现通过暴露一个对象接口,可以读取和写入字节(类似一个文件),和我们最初的要求的Ceph一样。数据对象被复制n份到多个OSD上以防止节点故障。然而,RADOS的可扩展性不依赖于特定的对象接口和冗余策略;对象以key/value的形式存储和奇偶校验(RAID)冗余策略都可以使用。
可伸缩的集群管理
一个RADOS系统由大量的OSD和少量用于管理OSD集群成员的Monitor组成。每个OSD包括CPU、RAM、网络接口和本地磁盘设备或RAID。Monitor一个独立的进程,它只需要少量的本地存储。
Cluster Map
存储集群是由Monitor集群通过操纵Cluster Map来管理的。Cluster Map标识了哪些OSD包含在集群中,以及以紧凑的方式标识了系统中数据在各个设备上的分布,它被复制到每个存储节点以及与这个RADOS集群交换的客户端。由于Cluster Map完整的标识了数据分布,客户端暴露了一个简单的用户接口,将整个存储集群(可能是上万个节点)作为一个单一的逻辑对象存储。
每次Cluster Map改变,由于OSD状态改变(例如:设备故障)或其他事件影响数据布局,Map epoch就会增加。Map epoch运行通信双方对当前数据分布达成共识,并决定什么时间这个信息过时。由于Cluster Map可能会频繁变化,作为一个大的系统,OSD故障和恢复应该是比较普遍的,以增量Map的形式分发更新,通过一个小的消息描述两个连续的epoch之间的不同。在大多数情况下,这样的更新简单陈述为一个或者多个OSD故障或恢复,虽然一般情况可能包含多个设备的状态改变,但是多个更新可以捆绑在一起来描述map epoch见的不同。
Data Placement
         RADOS采用对象伪随机地分配给设备的数据分布策略。当新的存储设备加入时,现有数据的随机子样本会被迁移到新的设备上以恢复平衡。这个策略是鲁棒的,因为他维护了一个概率分布均衡,平均而言,保持所有设备类似的负载,让系统在任意的负载下,能够保持较好的运行。最重要的是,数据放置的位置是一个两阶段过程,计算对象的适当位置,不再需要大而繁琐的集中分配表。
         每个对象存放到系统时,都要映射到一个Placement Group(PG),PG是存储到一组相同设备的对象的逻辑集合。每个对象的PG是由对象名称O的hash、所需复制的级别r,以及一个用于控制系统中PG数量的位掩码 m决定的。pgid = (r, hash(o)&m),其中掩码m = 2k−1,限制了PG的数量必须是2的整数次幂,为了集群的扩展性,通过调整m来周期性的调整PG的总数是有必要的,这样做是为了尽量避免PG在设备间迁移。
         为PG指定OSD是基于cluster map,它将PG映射到一个用来存储对象副本的具有r个OSD的有序列表。我们的实现采用CRUSH算法,它是用来计算稳定的伪随机映射的一个鲁棒分布式算法。其他的放置策略也是可以的,甚至用一个映射表显示将PG与一组设备映射也只需要几MB。从比较高的角度看,CRUSH的行为与Hash算法类似,PG是确定的,但是随机分布的。与Hash算法不同的是CRUSH是稳定的:当一个或者多个设备加入或者离开时,大部分PG保持原来的位置不变,CRUSH仅转移足够的数据以保持负载分布。相比之下,典型的Hash方法是强制重新安排所有之前的映射。CRUSH还是用权重值,基于设备容量和性能来控制分配给每个设备的数据量。
         PG提供了一种方法控制副本分布策略的级别。也就是说,一个OSD不是与另外一个或者多个设备共享所有副本(镜像),或与其他不同的设备共享每个对象(complete declustering),副本Peer数量与它存储的PG数量u有关,典型的是顺序100PG每个OSD。由于分布是随机的,u也会影响设备利用率的方差:OSD上的PG越多分布越均衡。更重要的是,declustering有利用分布式,通过允许每个PG独立被重新复制到其他OSD可以并行错误恢复。在同一时间,系统可以限制同时出现故障的设备,通过限制每个设备共享相同数据的数量。
Device State
         Cluster Map中包含了设备的描述信息,设备但却的状态信息,以及数据分布信息。包含所有OSD的当前在线的网络地址,并指明哪些设备是不可达的(down)。RADOS会把OSD的活跃度考虑进去。
         对于每个PG,CRUSH会从mapping中找到r个OSD。RADOS然后会过滤掉那些down状态的设备,为PG产生一个avtive状态的OSD列表。如果这个active列表是空的,PG数据就会不可用,IO就会被Block。
         对应活跃的IO服务,OSD通常是up和in状态。如果它出错,应该是down和out状态,产生一个actvie列表对应 r个OSD。OSD也可能处在down但是仍然是in 某个Mapping,意味着他们目前是不可达的,但是PG数据还没有被remapped到其他OSD(类似于degraded mode在RAID系统中)。反过来,它们也可能是up和out状态,意味着他们是在线的,但是仍然处在空闲状态。这有利于应对各种场景,包括对间歇性的不可用容忍(例如:OSD重启或网络间歇性中断)而不初始化任何数据迁移;新的部署存储而暂时不使用(例如:用来测试),并且在就设备推出前,将数据安全的迁移出去。
Map Propagation
         由于RADOS集群坑内包含成千上万的设备,简单的广播Map更新消息到每个节点是不实际的。幸运的是map epoch的不同是很明显的,只有当两个通信的OSD(或者一个客户端和OSD)不同时,他们才会根据适当的规则更新。这个特性可以是RADOS分发延迟分发Map更新,通过经OSD内部消息结合,高效的转移分布负载。
       每个OSD都会维护map更新的历史记录,为每个消息带一个epoch的tag,并持续跟踪出现在每个peer中的最新的epoch。如果OSD接收到一个peer带来一个老的map,它就会将必要的增量带给这个peer以保持同步。类似的当发送peer有一个老的map,增量更新也会从对端共享。心跳消息会周期的交换以检测异常保证更新快速扩散,对于一个有n个OSD的集群,用到的时间为O(logn)。
         例如,当一个OSD启动时,它会通过OSDboot消息通知一个monitor,这个消息中包含了其最新的map epoch。Monitor集群更新该OSD的状态为up,然后将更新后的cluster Map带给该OSD,当这个新的OSD与其他OSD通信时,这个状态更新后的Map就会共享给这些OSD。因为这个新OSD不知道其他Peer拥有的epoch,它会共享一个安全的当前增量更新历史。
         这种Map共享机制是保守的:一个OSD与其他Peer联系时都会共享和更新Map,另外,当这个peer以及看到它时,就会导致OSD接收到充分的更新信息。然而,一个OSD接收到重复的Map的数量是与它有多少Peer有关,这个数量又由它管理PG的数量u决定。实际情况下,我们发现update重复的级别原少于这个值。
INTELLIGENT STORAGE DEVICES
数据分布的信息封装在了Cluster Map中,这使得RADOS可以将存储集群的数据冗余管理、故障检测和故障恢复分布到各个OSD上。通过采用类似P2P的协议,在高性能的集群环境中,充分利用了OSD节点的智能性。
         RADOS实现了结合每个对象版本和短的日志的多路复制。复制是由OSD自己完成的:客户端只会提交一个写的操作到主OSD,主OSD复制一致性和安全更新所有副本。这样移动和复制相关的操作利用的是存储集群内部的网络带宽,同时这样也可以简化客户端的设计。对象版本和日志有助于节点故障时快速恢复。
         我们将主要描述RADOS集群架构,特别是Cluster Map是如何将复制和故障恢复分布化,已经如何将这个能力推广到引入其他冗余机制(例如基于RAID码的分片)。
Replication
RADOS实现了三种不同的复制策略:Primary copy、chain、splay。更新操作的消息交换可以参考图2。在所有的情况下,客户端发送IO操作到一个OSD,集群来保证副本能够安全地更新以及一致性的读和写。一旦所有的副本被更新,就会返回一个ACK消息给客户端。
         Primary-copy 复制并行地更新所有的副本,并处理读和写在primary OSD。Chain采用串行更新的方式:当写命令发送给Primary节点,而读命令发送给Tail节点,保证read总是可以反映整个副本的更新。Splay是将Primary-copy中的并行更新和chain-copy中的读写角色分离想结合,这个好处是减少了消息的跳数对于两路镜像。
Strong Consistency
所有的RADOS消息(包括从客户端发起的消息,以及从其他OSD发起的消息)都携带了发送端的map epoch,以保证所有更新操作都能够在最新的版本上保持一致。如果一个客户端因为使用了一个过期的map,发送一个IO到一个错误的OSD,OSD会回复一个适当的增量,客户端再重新发送这个请求到正确的OSD。这就避免了主动共享map到客户端,客户端会在与Cluster联系的时候更新。大部分时候,他们都会在不影响当前操作的时候学到更新,让接下来的IO能够准确的定位。
如果cluster map的主拷贝已经更新,改变了一个特定的PG的成员,老的成员仍然可以处理更新,就像没有感觉到变化一样。如果这个改变先被一个PG副本节点知道,它将被发现,当主OSD转发更新消息到副本节点,副本节点就会返回map的增量给主OSD。这是完全安全的,因为任何新负责一个PG的一组OSD都需要与之前负责这个PG的OSD联系,以保证PG的内容是正确的,这样就可以保证之前的OSD能够学到这个Map的改变,并在新的OSD接手之前停止执行IO操作。
完成类似读的一致性操作会没有更新那么自然。当网络故障时,会导致一个OSD部分不可达,为某个PG提供读服务的OSD可能被标记为故障,但是可能对那些拥有过期的map的client是可达的。同时,更新后的map可能指定了一个新的OSD。为了避免新的更新由一个新的OSD处理后,老的OSD还能处理接收到的读操作,我们需要周期性的心跳报文,在那些负责相同PG的OSD之前,为了保持这个PG是可读的。如果一个提供读的OSD在H秒钟没有听到其他副本的心跳报文,读操作就会被阻塞。在其他OSD接收一个PG的主要角色前,他必须获得老的OSD的确认(保证它们都知道自己的角色发生了变化),或延迟一定的时间间隔。目前的实现,我们采用2秒钟一个相对较小的心跳间隔。这可以抱着故障可以及时的被侦测,并且当主OSD故障是可以保证数据不可用的时间很短。
3.3 Failure Detection
RADOS采用一种异步、有序点到点的消息传递库进行通信。当TCP套接字发生故障是会导致有限次的重新连接尝试,然后才报告monitor集群。存储节点会周期性的交换心跳报文与他们的对端(那些与他们共享相同PG数据的OSD),以保证设备故障能够及时侦测到。当OSD发现他们已经被标记成为down状态,会同步硬盘数据,然后将kill自己保证行为的一致性。
3.4 Data Migration and Failure Recovery
RADOS数据迁移和故障恢复完全是由Cluster Map的更新和PG到OSD映射改变驱动的。这个改变可能是由于设备故障、恢复,集群扩展或收缩,已经有一新的CRUSH策略导致所有数据的重新分布。设备故障只是许多可能引起建立新的集群数据分布的一个原因之一。
RADOS没有对数据连续性做任何假设。在所有情况下,RADOS采用了一个鲁棒性peering算法,通过这个算法可以建立一个一致性的PG内容视图,并且可以恢复适当的数据分布和复制。这个策略依赖的基本的设计前提是OSD采用积极复制一个PG的日志,这个记录了一个PG当前内容是什么(即:包含的对象的版本),即使当前对象副本可能本地丢失。因此,即使恢复很慢,一些时候对象安全被降级,PG的元数据能够被保证,从而简化了恢复算法,并且允许系统检测到数据丢失。
3.4.1 Peering
         当一个SD接收到一个Cluster Map更新,它会遍历所有先的Map增量,通过最近的检查和可能的调整PG的状态值。任何本地存储的PG的atcive list中的OSD发生改变必须重新re-peer。考虑到所有的map epoch(不只是最近的),确保中间数据分布要被考虑:如果一个OS从一个PG移除,然后有加入进来,要确认PG的内容可能在中间发生更新,这一点很重要。与复制、对等以及其他后续的更新对系统中的每个PG进行处理。
         Peering是由OSD中的Primary OSD驱动的。对于每个PG不是Primary的OSD,通知消息都发送给primary OSD。这个消息包括:本地存储的PG的基本状态信息,包括最近的更新,一定范围的PG日志信息,已经最近知道的epoch。通知消息保证一个新的primary OSD对于一个PG能够发现他的新的角色,不用考虑所有可能的PG(可能有几百万个)对于每个map改变。一旦知道这些,Primary OSD就可以生成一个prior set,其包含了所有加入到这个PG的OSD,因为刚刚与这些成功建立peer关系。这个prior set可以被显式查询以达到一个稳定状态,避免对一个OSD没有政治存储这个PG的无限等待。
         有了PG现有集的元数据,Primary OSD就能够决定应用于任何副本的最近更新,并且知道从prior OSD请求哪段log片段,以便是PG日志在active副本上得到更新。如果一个可用的PG日志是不充足的(例如,一个或多个OSD没有PG数据),一个完整的PG内容就会生成。对于节点重启或者其他端的中断,为了足够快的同步副本PG日志是有足够的信息。
         最好,Primary OSD与其他replica OSD 共享缺失的日志片段,所有replica知道都知道PG中包含哪些对象(即使他们本地还没有保存这个对象),这样就可以在后台执行恢复进程。
3.4.2 Recovery
       Declustered replication的一个重要的优势是能够进行并行的故障恢复。任何单一故障的设备共享分布在其他OSD的副本,每个PG可以独立选择替换和允许重新复制一样多的OSD。平均而言,在一个大的系统中,任何一个单一故障恢复的OSD,可以采用Push和Pull的方式复制内容,是故障恢复的速度非常快。Recovery可以被激发通过观察IO读是否被限制。虽然每个独立OSD都拥有所有的PG元数据,可以独立的获取每个缺失的对象,但这个策略有两个限制。一个是多个OSDOSD分布恢复在相同PG中的对象,这可能在相同时间,不会去下载在相同OSD上的相同对象。这可能导致最大的恢复开销是Seeking和Reading。另外,如果replica OSD缺失对象被改变,这个副本更新协议可能会变得很复杂。
         基于这个原因,RADOS中的PG恢复是由primary OSD协调的。和之前类似,知道主OSD有一个本地拷贝后才对缺失的对象进行操作。因为Primary OSD通过peering的过程已经知道了所有replicas缺失哪些对象。它可以将任何对象推送到replica OSD,简化的复制楼价也保证了这在拷贝的对象只能读一次。如果主 OSD正在推送一个对象或者它已经刚刚下载了一个对象,它将总是会推送给所有replicas。因此,每个被复制的对象只读一次。
4. MONITORS
         Monitors是一个小的集群,通过存储Cluster Map的主Copy,并周期性的更新配置的改变和OSD状态,管理整个存储系统。集群是建立在Paxos part-time parliament算法的基础上,这个算法有利与可用性和更新延迟的一致性和持久性。值得注意的是,大部分Monitors必须是可用的,为了保持Cluster Map的读取和更新,以及Cluster Map的改变能够持久性。
4.1 Paxos Service
集群是基于分布式状态机服务,基于Poxos,Cluster Map是当前的集群状态,并且每次更新都会到只一个新的Map epoch。实现轻微地简化了标准的Poxos,通过任何时候只允许一个突变对于当前的Map。将基本的Paxos算法与租约机制相结合,允许任何monitor之前直接请求,确保读和更新按照一致的顺序。集群初始化选出的一个领导这能够序列化Map更新和管理一致性。一旦被选出来,Leader就会请求每个monitor上的所有map epoch。Monitor有一个固定的时间探测和家人到quorum。如果大多数monitor是active的,Poaxos算法的第一阶段能够保证每个Monitor有一个最近提交的map epoch,然后分发短的租约到没有active monitor。每个租约都会授权给active monitor想OSD和Client分发他们请求的Cluster Map拷贝的权利。如果租约T超时,并没有更新,就认为leader已经故障,就重新进行选举。当收到租约时要给leader发送确认消息。如果leader没有及时收到确认消息,他就假设这个active monitor已经崩溃,重新选举建立一个新的quorum。当一个monitor第一次启动,或者过了一定时间间隔后之前的选举没有完成,都会激发重新选举。
         当一个active monitor接收到一个更新请求(例如一个错误报告),它会先看一下这个请求是否是新的。例如一个OSD已经被标记为down,这个monitor就会给发送这个消息的OSD相应的Map增量。新的报错会转发给Leader,leader会初始化Map更新通过增加Map epoch,并使用Paxos 更新协议将共享分发给其他Monitor,同时撤销租约。如果更新被大部分Monitor确认,最后会提交新的租约消息。
         一个两个阶段的指派和周期性的探测可以保证,是否active monitor集合改变,它保证所有当前的租约,在Map更新时过期。因此,任何顺序的Map更新查询和更新都能够在一个Map版本上一致的进行。重要的是Map的版本将永远不会回退,只要大部分monitor是是可用的,无论哪个Monitor消息被发送到或任何干预Monitor的错误。
4.2 Workload and Scalability
通常情况下,Monitor工作负载是很小的,大部分Map分发是由Storage Node完成的,设备状态的改变也是不经常发生的。
         Monitor集群采用的租约机制,可以允许任何Monitor可以从OSD或者Client请求Cluster Map拷贝。这种请求很少由OSD发起,因为抢先的Map共享,Client通常请求Update只发生在OSD操作超时,或者可能发生错误的时候。Monitor集群能够分发这些复制到更大的集群。
         需要Map update的请求会被转发给当前的Leader。Lead会汇集多个根系到一个Map更新,Map Update的频率是可以调节的,而且是与Cluster的大小不相关的。尽管如此,最坏的负载发生在,当大量的OSD在一个短时间内同时发生故障。如果一个OSD存放了u个PG,并且有f个OSD故障,就会有最多uf个错误报告产生。当OSD比较大时,这些消息会非常多。为了防止消息饭量,OSD会在伪随机的时间间隔发送心跳报文,保证陆续检测到这些错误,压制和分配的报告错误。那些不是Leader的monitor只会针对一个报错转发一次,这样Leader的请求负载就相应的为fm,其中m为集群中monitor的数量。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值