Ceph分布式存储实战3.3 CRUSH关系分析

简介:

3.3 CRUSH关系分析


从本质上讲,CRUSH算法是通过存储设备的权重来计算数据对象的分布的。在计算过程中,通过Cluster Map(集群映射)、Data Distribution Policy(数据分布策略)和给出的一个随机数共同决定数据对象的最终位置。

1. Cluster Map

Cluster Map记录所有可用的存储资源及相互之间的空间层次结构(集群中有多少个机架、机架上有多少服务器、每个机器上有多少磁盘等信息)。所谓的Map,顾名思义,就是类似于我们生活中的地图。在Ceph存储里,数据的索引都是通过各种不同的Map来实现的。另一方面,Map 使得Ceph集群存储设备在物理层作了一层防护。例如,在多副本(常见的三副本)的结构上,通过设置合理的Map(故障域设置为Host级),可以保证在某一服务器死机的情况下,有其他副本保留在正常的存储节点上,能够继续提供服务,实现存储的高可用。设置更高的故障域级别(如Rack、Row等)能保证整机柜或同一排机柜在掉电情况下数据的可用性和完整性。

(1)Cluster Map的分层结构

Cluster Map由Device和Bucket构成。它们都有自己的ID和权重值,并且形成一个以Device为叶子节点、Bucket为躯干的树状结构,如图3-3所示。

 

图3-3 CRUSH架构图

Bucket拥有不同的类型,如Host、Row、Rack、Room等,通常我们默认把机架类型定义为Rack,主机类型定义为Host,数据中心(IDC机房)定义为Data Center。Bucket的类型都是虚拟结构,可以根据自己的喜好设计合适的类型。Device节点的权重值代表了存储设备的容量与性能。其中,磁盘容量是权重大小的关键因素。

OSD 的权重值越高,对应磁盘会被分配写入更多的数据。总体来看,数据会被均匀写入分布于群集所有磁盘,从而提高整体性能和可靠性。无论磁盘的规格容量,总能够均匀使用。

关于OSD权重值的大小值的配比,官方默认值设置为1TB容量的硬盘,对应权重值为1。

可以在/etc/init.d/ceph 原码里查看相关的内容。

363             get_conf osd_weight "" "osd crush initial weight"

364             defaultweight="$(df -P -k $osd_data/. | tail -1 | awk '{ print sprintf("%.2f",$2/1073741824) }')"  ###此处就是ceph默认权重的设置值

            get_conf osd_keyring "$osd_data/keyring" "keyring"

366             do_cmd_okfail "timeout 30 $BINDIR/ceph -c $conf --name=osd.$id --keyring=$osd_keyring     osd crush create-or-move -- $id ${osd_weight:-${defaultweight:-1}} $osd_location"

(2)恢复与动态平衡

在默认设置下,当集群里有组件出现故障时(主要是OSD,也可能是磁盘或者网络等),Ceph会把OSD标记为down,如果在300s内未能回复,集群就会开始进行恢复状态。这个“300s”可以通过“mon osd down out interval”配置选项修改等待时间。PG(Placement  Groups)是Ceph数据管理(包括复制、修复等动作)单元。当客户端把读写请求(对象单元)推送到Ceph时,通过CRUSH提供的Hash算法把对象映射到PG。PG在CRUSH策略的影响下,最终会被映射到OSD上。

2. Data Distribution Policy

Data Distribution Policy由Placement Rules组成。Rule决定了每个数据对象有多少个副本,这些副本存储的限制条件(比如3个副本放在不同的机架中)。一个典型的rule如下所示。

rule replicated_ruleset {    ##rule名字

    ruleset 0         # rule的Id

    type replicated   ## 类型为副本模式,另外一种模式为纠删码(EC)

    min_size 1        ## 如果存储池的副本数大于这个值,此rule不会应用

    max_size 10       ## 如要存储池的副本数大于这个值,此rule不会应用

    step take default  ## 以default root为入口

    step chooseleaf firstn 0 type host  ## 隔离域为host级,即不同副本在不同的主机上

    step emit        ## 提交

}

根据实际的设备环境,可以定制出符合自己需求的Rule,详见第10章。

3. CRUSH中的伪随机

先来看一下数据映射到具体OSD的函数表达形式。

CRUSH(x) -> (osd1, osd2, osd3.....osdn)  

CRUSH使用了多参数的Hash函数在Hash之后,映射都是按既定规则选择的,这使得从x到OSD的集合是确定的和独立的。CRUSH只使用Cluster Map、Placement Rules、X。CRUSH是伪随机算法,相似输入的结果之间没有相关性。关于伪随机的确认性和独立性,以下我们以一个实例来展示。

 [root@host-192-168-0-16 ~]# ceph osd tree

ID WEIGHT  TYPE NAME               UP/DOWN  REWEIGHT  PRIMARY-AFFINITY

-1 0.35999 root default                                                 

-3 0.09000     host host-192-168-0-17                                   

 2 0.09000         osd.2                   up  1.00000          1.00000

-4 0.09000     host host-192-168-0-18                                   

 3 0.09000         osd.3                   up  1.00000          1.00000

-2 0.17999     host host-192-168-0-16                                   

 0 0.09000         osd.0                   up  1.00000          1.00000

 1 0.09000         osd.1                   up  1.00000          1.00000

以上是某个Ceph集群的存储的CRUSH结构。在此集群里我们手动创建一个pool,并指定为8个PG和PGP。

[root@host-192-168-0-16 ~]# ceph  osd pool create  crush  8   8

pool 'crush' created

PGP是PG的逻辑承载体,是CRUSH算法不可缺少的部分。在Ceph集群里,增加PG数量,PG到OSD的映射关系就会发生变化,但此时存储在PG里的数据并不会发生迁移,只有当PGP的数量也增加时,数据迁移才会真正开始。关于PG和PGP的关系,假如把PG比作参加宴会的人,那么PGP就是人坐的椅子,如果人员增加时,人的座位排序就会发生变化,只有增加椅子时,真正的座位排序变更才会落实。因此,人和椅子的数量一般都保持一致。所以,在Ceph里,通常把PGP和PG设置成一致的。

可以查看PG映射OSD的集合,即PG具体分配到OSD的归属。

 [root@host-192-168-0-16 ~]# ceph pg dump | grep ^22\. | awk '{print $1 "\t"   $17}'    ## 22 表示 Pool id ##

dumped all in format plain

22.1 [1,2,3]    

22.0   [1,2,3]

22.3 [3,1,2]

22.2 [3,2,0]

22.5 [1,3,2]

22.4 [3,1,2]

22.7 [2,1,3]

22.6 [3,0,2]

上面示例中,第一列是PG的编号(其中22表示的Pool的ID),共计8个,第二列是PG映射到了具体的OSD集合。如“22.1 [1,2,3]”表示PG 22.1分别在OSD1、OSD2和OSD3分别存储副本。

在Ceph集群里,当有数据对象要写入集群时,需要进行两次映射。第一次从object→PG,第二次是PG→OSD set。每一次的映射都是与其他对象无相关的。以上充分体现了CRUSH的独立性(充分分散)和确定性(可确定的存储位置)。

相关文章
|
1月前
|
存储 分布式计算 大数据
HBase分布式数据库关键技术与实战:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析了HBase的核心技术,包括数据模型、分布式架构、访问模式和一致性保证,并探讨了其实战应用,如大规模数据存储、实时数据分析及与Hadoop、Spark集成。同时,分享了面试经验,对比了HBase与其他数据库的差异,提出了应对挑战的解决方案,展望了HBase的未来趋势。通过Java API代码示例,帮助读者巩固理解。全面了解和掌握HBase,能为面试和实际工作中的大数据处理提供坚实基础。
50 3
|
2月前
|
设计模式 安全 Java
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
36 0
|
12天前
|
监控 NoSQL 算法
探秘Redis分布式锁:实战与注意事项
本文介绍了Redis分区容错中的分布式锁概念,包括利用Watch实现乐观锁和使用setnx防止库存超卖。乐观锁通过Watch命令监控键值变化,在事务中执行修改,若键值被改变则事务失败。Java代码示例展示了具体实现。setnx命令用于库存操作,确保无超卖,通过设置锁并检查库存来更新。文章还讨论了分布式锁存在的问题,如客户端阻塞、时钟漂移和单点故障,并提出了RedLock算法来提高可靠性。Redisson作为生产环境的分布式锁实现,提供了可重入锁、读写锁等高级功能。最后,文章对比了Redis、Zookeeper和etcd的分布式锁特性。
122 16
探秘Redis分布式锁:实战与注意事项
|
14天前
|
数据采集 存储 运维
如何使用SkyWalking收集分析分布式系统的追踪数据
通过以上步骤,你可以使用 SkyWalking 工具实现对分布式系统的数据采集和可视化。SkyWalking 提供了强大的追踪和度量功能,帮助开发者和运维人员更好地理解系统的性能状况。欢迎关注威哥爱编程,一起学习成长。
|
2月前
|
存储 Java 应用服务中间件
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
【分布式技术专题】「架构实践于案例分析」盘点互联网应用服务中常用分布式事务(刚性事务和柔性事务)的原理和方案
62 0
|
2月前
|
缓存 应用服务中间件 数据库
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
46 1
|
2月前
|
存储 缓存 监控
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(场景问题分析+性能影响因素)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(场景问题分析+性能影响因素)
47 0
|
17天前
|
NoSQL Java 关系型数据库
【Redis系列笔记】分布式锁
分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行执行,这就是分布式锁的核心思路
119 2
|
1月前
|
NoSQL Java Redis
redis分布式锁
redis分布式锁
|
14天前
|
NoSQL Java 大数据
介绍redis分布式锁
分布式锁是解决多进程在分布式环境中争夺资源的问题,与本地锁相似但适用于不同进程。以Redis为例,通过`setIfAbsent`实现占锁,加锁同时设置过期时间避免死锁。然而,获取锁与设置过期时间非原子性可能导致并发问题,解决方案是使用`setIfAbsent`的超时参数。此外,释放锁前需验证归属,防止误删他人锁,可借助Lua脚本确保原子性。实际应用中还有锁续期、重试机制等复杂问题,现成解决方案如RedisLockRegistry和Redisson。