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

来源:互联网 发布:河北11选五任6遗漏数据 编辑:程序博客网 时间:2024/05/17 08:55

摘要

基于对象的存储架构已经作为一种新的方法改进存储集群(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包含在急群众,以及以紧凑的方式标识了数据分布,客户端暴露了一个简单的用户接口,将整个存储集群(可能是上万个节点)作为一个单一的逻辑对象存储。
每次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(0)&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有关,典型的是顺序100GP每个的OSD。由于分布式随机的,u也会影响设备利用率的方差:OSD上的PG越多分布约均衡。更重要的是,declustering有利用分布式,通过允许每个PG独立被重新复制到其他OSD可以并行错误恢复。在同一时间,系统可以限制同时出现故障的设备,通过限制每个设备共享相同数据的数量。

Device State
Cluster Map中包含了设备的描述信息,以及数据分布信息。包含所有OSD的当前在线的网络地址,并指明哪些设备是不可达的(down)。RADOS会把OSD的活跃度考虑进去。
对于每个PG,CRUSH会从mapping中找到r个OSD。RADOS然后会过滤掉哪些down状态的设备,为PG产生一个active状态的OSD列表。如果这个active列表是空的,PG数据就会不可用,IO就会被Block。
对应活跃的IO服务,OSD通常是up和in状态。如果它出错,应该是down和out状态,产生一个active列表对应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。在所有的情况下,客户端发送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故障是可以保证数据不可用的时间很短。

Failure Detection
RADOS采用一种异步、有序点到点的消息传递库进行通信。当TCP套接字发生故障是会导致有限次的重新连接尝试,然后才报告monitor集群。存储节点会周期性的交换心跳报文与他们的对端(那些与他们共享相同PG数据的OSD),以保证没有故障能够及时侦测到。当OSD发现他们已经被标记成为down状态,会同步硬盘数据,然后将kill自己保证行为的一致性。

Data Migration and Failure Recovery
RADOS数据迁移和故障恢复完全是由Cluster Map的更新和PG到OSD映射改变驱动的。这个改变可能是由于设备故障、恢复、集群扩展或收缩,已经有一新的CRUSH策略导致所有数据的重新分布。设备故障指示许多可能引起简历新的集群数据分布的一个原因之一。

RADOS没有对数据连续性做任何假设。在所有情况下,RADOS采用了一个鲁棒性peering算法,通过这个算法可以简历一个一致性的PG内容视图,并且可以恢复适当的数据分布和复制。这个策略依赖的基本的设计前提是OSD采用积极复制一个PG的日志,这个记录了一个PG当前内容是什么(即:包含的对象的版本),即使当前对象副本可能本地丢失。因此,即使恢复很慢,一些时候对象安全被降级,PG的元数据能够被保证,从而简化了恢复算法,并且允许系统检测到数据丢失。

Peering
当一个OSD接收到一个Cluster Map更新,它会遍历所有新的Map增量,头弄过最近的检查和可能的调整PG的状态值。任何本地存储的PG的active list中的OSD发生改变必须重新re-peer。考虑到所有的map epoch(不只是最近的),确保中间数据分布要被考虑:如果一个OSD从一个PG移除,然后又加入进来,要确认PG的内容可能在中间发生更新,这一点很重要。与复制、对等以及其他后续的更新对系统中的每个PG进行处理。

Peering是由OS的中的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中包含哪些对象(及时他们本地还没有保存这个对象),这样就可以在后台执行恢复进程。

Recovery
Declustered replication的一个重要的优势是能够进行并行的故障恢复。任何单一故障的设备共享分布在其他OSD的副本,每个PG可以独立选择替换和允许重新复制一样多的OSD。平均而言,在一个大的系统中,任何一个单一故障恢复的OSD,可以采用Push和Pull的方式复制内容,使故障恢复的速度非常快。Recovery可以被激发铜鼓O观察IO读是否被限制。虽然每个独立OSD都拥有所有的PG元数据,可以独立的获取每个确实的对象,但这个策略有两个限制。一个是多个OSD分布回复在相同PG中的对象,这可能在相同时间,不会去下载在相同OSD上的相同对象。这可能导致最大的恢复开销是Seeking和Reading。另外,如果replica OSD确实对象被改变,这个副本更新协议可能会变得很复杂。

基于这个原因,RADOS中的PG恢复时由Primary OSD协调的。和之前类似,知道主OSD有一个本地拷贝后才对确实的对象进行操作。因为Primayr OSD通过peering的过程已经知道了所有replicas确实哪些对象。他可以将任何对象推送到replica OSD,也保证了着在拷贝的对象只能读一次。如果主OSD正在推送一个对象或者他已经刚刚下载了一个对象,他将总是会推送给所有replicas。因此,每个被复制的对象只读一次。

Monitors
Monitors是一个小的集群,通过存储Cluster Map的主Copy,并走周期性的更新配置的改变和OSD状态,管理整个存储系统。集群是建立在Paxos part-time parliament算法的基础上,这个算法有利于可用性和更新延迟的一致性和持久性。

阅读全文
0 0
原创粉丝点击