ceph存储 ceph中对crush算法的认知

2024-01-05 11:38
文章标签 算法 存储 认知 ceph crush

本文主要是介绍ceph存储 ceph中对crush算法的认知,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

cephCRUSH数据分布算法介绍

CRUSHceph的一个模块,主要解决可控、可扩展、去中心化的数据副本分布问题。

1、摘要

随着大规模分布式存储系统(PB级的数据和成百上千台存储设备)的出现。这些系统必须平衡的分布数据和负载(提高资源利用率),最大化系统的性能,并要处理系统的扩展和硬件失效。ceph设计了CRUSH(一个可扩展的伪随机数据分布算法),用在分布式对象存储系统上,可以有效映射数据对象到存储设备上(不需要中心设备)。因为大型系统的结构式动态变化的,CRUSH能够处理存储设备的添加和移除,并最小化由于存储设备的的添加和移动而导致的数据迁移。

2、简介

对象存储设备(object-based storage devices)管理磁盘数据块的分配,并提供对象的读写接口。在一些对象存储系统中,每个文件的数据被分成多个对象,这些对象分布在整个存储集群中。对象存储系统简化了数据层(把数据块列表换成对象列表,并把低级的数据块分配问题交给各个设备)。对象存储系统的基本问题是如何分布数据到上千个存储设备上。

一个robust解决方案是把数据随机分布到存储设备上,这个方法能够保证负载均衡,保证新旧数据混合在一起。但是简单HASH分布不能有效处理设备数量的变化,导致大量数据迁移。ceph开发了CRUSHControoled Replication Under Scalable Hashing),一种伪随机数据分布算法,它能够在层级结构的存储集群中有效的分布对象的副本。CRUSH实现了一种伪随机(确定性)的函数,它的参数是object idobject group id并返回一组存储设备(用于保存object副本)CRUSH需要cluster map(描述存储集群的层级结构)、和副本分布策略(rule)

CRUSH有两个关键优点:

  1. 任何组件都可以独立计算出每个object所在的位置(去中心化)
  2. 只需要很少的元数据(cluster map),只要当删除添加设备时,这些元数据才需要改变

3CRUSH算法

CRUSH算法通过每个设备的权重计算数据对象的分布。对象分布是由cluster mapdata distribution policy决定的。cluster map描述了可用存储资源和层级结构(比如有多少个机架,每个机架上有多少个服务器,每个服务器上有多少个磁盘)data distribution policyplacement rules组成。rule决定了每个数据对象有多少个副本,这些副本存储的限制条件(比如3个副本放在不同的机架中)

CRUSH算出x到一组OSD集合(OSD是对象存储设备)

(osd0, osd1, osd2 … osdn) = CRUSH(x)

CRUSH利用多参数HASH函数HASH函数中的参数包括x,使得从xOSD集合是确定性的和独立的。CRUSH只使用了cluster mapplacement rulesxCRUSH是伪随机算法,相似输入的结果之间没有相关性。

3.1 层级的Cluster map

Cluster mapdevicebucket组成,它们都有id和权重值。Bucket可以包含任意数量itemitem可以都是的devices或者都是buckets。管理员控制存储设备的权重。权重和存储设备的容量有关Bucket的权重被定义为它所包含所有item的权重之和CRUSH基于4种不同的bucket type,每种有不同的选择算法。

3.2 副本分布

副本在存储设备上的分布影响数据的安全。cluster map反应了存储系统的物理结构CRUSH placement policies决定把对象副本分布在不同的区域(某个区域发生故障时并不会影响其他区域)。每个rule包含一系列操作(用在层级结构上)

这些操作包括:

  1. tack(a) :选择一个item,一般是bucket,并返回bucket所包含的所有item。这些item是后续操作的参数,这些item组成向量i
  2. select(n, t):迭代操作每个item(向量i中的item),对于每个item(向量i中的item)向下遍历(遍历这个item所包含的item),都返回n个不同的item(typetitem),并把这些item都放到向量i中。select函数会调用c(r, x)函数,这个函数会在每个bucket中伪随机选择一个item
  3. emit:把向量i放到result中。

存储设备有一个确定的类型。每个bucket都有type属性值,用于区分不同的bucket类型(比如”row””rack””host”等,type可以自定义)rules可以包含多个takeemit语句块这样就允许从不同的存储池中选择副本的storage target

3.3 冲突、故障、超载

select(n, t)操作会循环选择第 r=1,…,n 个副本,r作为选择参数。在这个过程中,假如选择到的item遇到三种情况(冲突,故障,超载)时,CRUSH会拒绝选择这个item,并使用r'(r’r、出错次数、firstn参数有关)作为选择参数重新选择item

  1. 冲突:这个item已经在向量i中,已被选择。
  2. 故障:设备发生故障,不能被选择。
  3. 超载:设备使用容量超过警戒线,没有剩余空间保存数据对象。

故障设备和超载设备会在cluster map上标记(还留在系统中),这样避免了不必要的数据迁移。

3.4 MAP改变和数据迁移

当添加移除存储设备,或有存储设备发生故障时(cluster map发生改变时),存储系统中的数据会发生迁移。好的数据分布算法可以最小化数据迁移大小。

3.5 Bucket的类型

CRUSH映射算法解决了效率和扩展性这两个矛盾的目标。而且当存储集群发生变化时,可以最小化数据迁移,并重新恢复平衡分布。CRUSH定义了四种具有不同算法的的buckets。每种bucket基于不同的数据结构,并有不同的c(r,x)伪随机选择函数。

不同的bucket有不同的性能和特性:

  1. Uniform Buckets:适用于具有相同权重的item,而且bucket很少添加删除item。它的查找速度是最快的。
  2. List Buckets:它的结构是链表结构,所包含的item可以具有任意的权重CRUSH从表头开始查找副本的位置,它先得到表头item的权重Wh、剩余链表中所有item的权重之和Ws,然后根据hash(x, r, item)得到一个[0~1]的值v,假如这个值v[0~Wh/Ws)之中,则副本在表头item中,并返回表头itemid。否者继续遍历剩余的链表。
  3. Tree Buckets链表的查找复杂度是O(n)决策树的查找复杂度是O(log n)item是决策树的叶子节点,决策树中的其他节点知道它左右子树的权重,节点的权重等于左右子树的权重之和。CRUSHroot节点开始查找副本的位置,它先得到节点的左子树的权重Wl,得到节点的权重Wn,然后根据hash(x, r, node_id)得到一个[0~1]的值v,假如这个值v[0~Wl/Wn)中,则副本在左子树中,否者在右子树中。继续遍历节点,直到到达叶子节点Tree Bucket的关键是当添加删除叶子节点时,决策树中的其他节点的node_id不变。决策树中节点的node_id的标识是根据对二叉树的中序遍历来决定的(node_id不等于itemid,也不等于节点的权重)
  4. Straw Buckets:这种类型让bucket所包含的所有item公平的竞争(不像listtree一样需要遍历)。这种算法就像抽签一样,所有的item都有机会被抽中(只有最长的签才能被抽中)。每个签的长度是由length = f(Wi)*hash(x, r, i) 决定的,f(Wi)item的权重有关,iitemid号。c(r, x) = MAXi(f(Wi) * hash(x, r, i))

2 不同Bucket的算法复杂度和数据迁移大小

4、结论

要根据存储系统中设备的情况和预期扩展计划来选择不同的bucket

Ceph数据分布:CRUSH算法与一致性Hash

数据分布是分布式存储系统的一个重要部分,数据分布算法至少要考虑以下三个因素:

1) 故障域隔离。同份数据的不同副本分布在不同的故障域,降低数据损坏的风险;

2) 负载均衡。数据能够均匀地分布在磁盘容量不等的存储节点,避免部分节点空闲部分节点超载,从而影响系统性能;

3) 控制节点加入离开时引起的数据迁移量。当节点离开时,最优的数据迁移是只有离线节点上的数据被迁移到其它节点,而正常工作的节点的数据不会发生迁移。

对象存储中一致性HashCephCRUSH算法是使用地比较多的数据分布算法。在AmazonDyanmo键值存储系统中采用一致性Hash算法,并且对它做了很多优化。OpenStackSwift对象存储系统也使用了一致性Hash算法。

一致性Hash算法

假设数据x存储节点数目N。将数据分布到存储节点的最直接做法是,计算数据xHash值,并将结果同节点数目N取余数,余数就是数据x的目的存储节点。即目的存储节点为 Hash(x) % N对数据计算Hash值的目的为了可以让数据均匀分布在N个节点中。这种做法的一个严重问题是,当加入新节点或则节点离开时,几乎所有数据都会受到影响,需要重新分布。因此,数据迁移量非常大

一致性Hash算法将数据和存储节点映射到同个Hash空间,如上图所示。Hash环中的3存储节点把Hash空间划分成3个分区,每个存储节点负责一个分区上的数据。例如,落在分区[N2,N0]上的数据存储在节点N0

一致性Hash算法能够很好地控制节点加入离开导致的迁移数据的数量。如图(b)所示,当节点N0离开时,原来由它负责的[N2, N0]分区将同[N0, N1]分区合并成[N2, N1]分区,并且都由节点N1负责。也就是说,本来存储在节点N0上的数据都迁移到节点N1,而原来存储在N1N2节点的数据不受影响。图(c)给出了当节点N3加入时,原来[N2, N0]分区分裂成[N3, N0][N2, N3]两个分区,其中[N3, N0]分区上是数据迁移到新加入的N3节点。

虚拟节点

一致性Hash的一个问题是存储节点不能将Hash空间划分地足够均匀。如上图(a)所示,分区[N2, N0]的大小几乎是其它两个分区大小之和。这容易让负责该分区的节点N0负载过重。假设3个节点的磁盘容量相等,那么当节点N0的磁盘已经写满数据时其它两个节点上的磁盘还有很大的空闲空间,但此时系统已经无法继续向分区[N2, N0]写入数据,从而造成资源浪费。

虚拟节点是相对于物理存储节点而言的,虚拟节点负责的分区上的数据最终存储到其对应的物理节点。在一致性Hash中引入虚拟节点可以把Hash空间划分成更多的分区,从而让数据在存储节点上的分布更加均匀。如上图(b)所示,黄颜色的节点代表虚拟节点,Ni_0代表该虚拟节点对应于物理节点i的第0个虚拟节点。增加虚拟节点后,物理节点N0负责[N1_0, N0][N0, N0_0]两个分区,物理节点N1负责[N0_0, N1][N2_0, N1_0]两个分区,物理节点N2负责[N2, N1][N2_0, N2]两个分区,三个物理节点负责的总的数据量趋于平衡。

实际应用中,可以根据物理节点的磁盘容量的大小来确定其对应的虚拟节点数目。虚拟节点数目越多,节点负责的数据区间也越大。

分区与分区位置

前文提到,当节点加入或者离开时,分区会相应地进行分裂或合并。这不对新写入的数据构成影响,但对已经写入到磁盘的数据需要重新计算Hash值以确定它是否需要迁移到其它节点。因为需要遍历磁盘中的所有数据,这个计算过程非常耗时。如下图(a)所示,分区是由落在Hash环上的虚拟节点Ti来划分的,并且分区位置(存储分区数据的节点)也同虚拟节点相关,即存储到其顺时针方向的第1个虚拟节点。

Dynamo的论文中提出了分离分区和分区位置的方法来解决这个问题。该方法将Hash空间划分成固定的若干个分区,虚拟节点不再用于划分分区而用来确定分区的存储位置。如上图(b)所示,将Hash空间划分成[A,B][B,C], [C,D][D,A]四个固定的分区。虚拟节点用于确定分区位置,例如T1负责分区[B,C]T2负责分区[C,D]T0负责[D,A][A,B]两个分区。由于分区固定,因此迁移数据时可以很容易知道哪些数据需要迁移哪些数据不需要迁移。

上图(b)中虚拟节点T0负责了[D,A][A,B]两个分区的数据,这是由分区数目和虚拟节点数目不相同导致的。为让分区分布地更加均匀,Dyanmo提出了维持分区数目和虚拟节点数目相等的方法。这样每个虚拟节点负责一个分区,在物理节点的磁盘容量都相同并且虚拟节点数目都相同的情况下,每个物理节点负责的分区大小是完全相同的,从而可以达到最佳的数据分布。

CRUSH算法

Ceph分布数据的过程:首先计算数据xHash并将结果和PG数目取余,以得到数据x对应的PG编号。然后,通过CRUSH算法将PG映射到一组OSD中。最后把数据x存放到PG对应的OSD。这个过程中包含了两次映射,第一次是数据xPG的映射。如果把PG当作存储节点,那么这和文章开头提到的普通Hash算法一样。不同的是,PG是抽象的存储节点,它不会随着物理节点的加入或则离开而增加或减少,因此数据到PG的映射是稳定的。

在这个过程中,PG起到了两个作用:第一个作用是划分数据分区。每个PG管理的数据区间相同,因而数据能够均匀地分布到PG上;第二个作用是充当DyanmoToken的角色,即决定分区位置。实际上,这和Dynamo中固定分区数目,以及维持分区数目和虚拟节点数目相等的原则是同一回事。

在没有多副本的情况下,Dynamo中分区的数据直接存储到Token,而每个Token对应唯一的一个物理存储节点。在多副本(假设副本数目为N)的情况下,分区的数据会存储到连续的NToken中。但这会引入一个新问题:因为副本必须保持在不同的物理节点,但是如果这组Token中存在两个或多个Token对应到同个物理存储节点,那么就必须要跳过这样的节点。Dynamo采用Preference列表来记录每个分区对应的物理节点。然而,Dynmao论文中没有详述分区的Preference列表如何选取物理节点,以及选取物理节点时该如何隔离故障域等问题。

(osd0, osd1, osd2 … osdn) = CRUSH(x)

CephPG担当起DynamoToken固定分区以及Preference列表的角色,解决的是同样的问题。PGActing集合对应于DynamoPreference列表。CRUSH算法解决了Dynamo论文中未提及的问题。

OSD层级结构和权重大小

CRUSH算法的目的是,为给定的PG(即分区)分配一组存储数据的OSD节点。选择OSD节点的过程,要考虑以下几个因素:

1) PGOSD间均匀分布。假设每个OSD的磁盘容量都相同,那么我们希望PG在每个OSD节点上是均匀分布的,也就是说每个OSD节点包含相同数目的PG。假如节点的磁盘容量不等,那么容量大的磁盘的节点能够处理更多数量的PG

2) PGOSD分布在不同的故障域。因为PGOSD列表用于保存数据的不同副本,副本分布在不同的OSD中可以降低数据损坏的风险。

Ceph使用树型层级结构描述OSD空间位置以及权重(同磁盘容量相关)大小。如上图所示,层级结构描述了OSD所在主机、主机所在机架以及机架所在机房等空间位置。这些空间位置隐含了故障区域,例如使用不同电源的不同的机架属于不同的故障域。CRUSH能够依据一定的规则将副本放置在不同的故障域

OSD节点在层级结构中也被称为Device,它位于层级结构的叶子节点,所有非叶子节点称为BucketBucket拥有不同的类型,如上图所示,所有机架的类型Rack,所有主机的类型Host。使用者还可以自己定义Bucket的类型。Device节点的权重代表存储节点的性能磁盘容量是影响权重大小的重要参数Bucket节点的权重是其子节点的权重之和

CRUSH通过重复执行Take(bucketID)Select(n, bucketType)两个操作选取副本位置Take(bucketID)指定从给定的bucketID中选取副本位置,例如可以指定从某台机架上选取副本位置,以实现将不同的副本隔离在不同的故障域; Select(n, bucketType)则在给定的Bucket下选取n个类型为bucketTypeBucket,它选取Bucket主要考虑层级结构中节点的容量,以及当节点离线或者加入时的数据迁移量。

 

算法流程

上图给出了CRUSH选取副本的流程图。

bucket: Take操作指定的bucket

type: Select操作指定的Bucket的类型;

repnum: Select操作指定的副本数目;

rep:当前选择的副本编号;

x: 当前选择的PG编号;

item: 代表当前被选中的Bucket

c(r, x, in): 代表从Bucket in中为PG x选取第r个副本;

collide: 代表当前选中的副本位置item已经被选中,即出现了冲突;

reject: 代表当前选中的副本位置item被拒绝,例如,在item已经处于out状态的情况下;

ftotal: Descent域中选择的失败次数,即选择一个副本位置的总共的失败次数;

flocal: Local域中选择的失败次数;

local_retries: Local域选择冲突时的尝试次数;

local_fallback_retries: 允许在Local域的总共尝试次数为bucket.size + local_fallback_retires次,以保证遍历完Buckt的所有子节点;

tries: Descent的最大尝试次数,超过这个次数则放弃这个副本。

Take操作指定的BucketSelect操作指定的Bucket类型之间隔着几层Bucket时,算法直接深度优先地进入到目的Bucket的直接父母节点。例如,从根节点开始选择NHost时,它会深度优先地查找到Rack类型的节点,并在这个节点下选取Host节点。为了方便表述,将Rack的所有子节点标记为Local域,将Take指定的Bucket的子节点标记为Descent域,如上图所示。

选取过程中出现冲突、过载或者故障时,算法先在Local域内重新选择,尝试有限次数后,如果仍然找不到满足条件的Bucket,那就回到Descent域重新选择每次重新选择时修改副本数目r += ftotal。因此每次选择失败都会递增ftotal,所以可以尽量避免选择时再次选到冲突的节点。

Bucket选取Item算法

流程图中的item=c(r,x,in)从给定的Bucket in中选取一个子节点。

参考资料

1CephCRUSH数据分布算法介绍

2CRUSH:Controlled,Scalable,Decentralized Placement of Replicated Data

3Dynamo:Amazon Highly Available Key-value Store

 

 


这篇关于ceph存储 ceph中对crush算法的认知的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/572734

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费