Ceph 存储集群5-数据归置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ceph 存储集群5-数据归置相关的知识,希望对你有一定的参考价值。

 

一、数据归置概览

 

Ceph 通过 RADOS 集群动态地存储、复制和重新均衡数据对象。很多不同用户因不同目的把对象存储在不同的存储池里,而它们都坐落于无数的 OSD 之上,所以 Ceph 的运营需要些数据归置计划。 Ceph 的数据归置计划概念主要有:

存储池( Pool ): Ceph 在存储池内存储数据,它是对象存储的逻辑组;存储池管理着归置组数量、副本数量、和存储池规则集。
          要往存储池里存数据,用户必须通过认证、且权限合适,存储池可做快照。详情参见存储池。
归置组( Placement Group ): Ceph 把对象映射到归置组( PG ),归置组是一逻辑对象池的片段,这些对象组团后再存入到 OSD 。
          归置组减少了各对象存入对应 OSD 时的元数据数量,更多的归置组(如每 OSD
100 个)使得均衡更好。详情见归置组。
CRUSH 图( CRUSH Map ): CRUSH 是重要组件,它使 Ceph 能伸缩自如而没有性能瓶颈、没有扩展限制、没有单点故障,它为 CRUSH 算法提供集群的物理拓扑,
          以此确定一个对象的数据及它的副本应该在哪里、怎样跨故障域存储,以提升数据安全。详情见 CRUSH 图

 

二、存储池

 

如果你开始部署集群时没有创建存储池, Ceph 会用默认存储池存数据。存储池提供的功能:

自恢复力: 你可以设置在不丢数据的前提下允许多少 OSD 失效,对多副本存储池来说,此值是一对象应达到的副本数。
      典型配置存储一个对象和它的一个副本(即 size = 2 ),但你可以更改副本数;对纠删编码的存储池来说,此值是编码块数(即纠删码配置里的 m=2 )。
归置组: 你可以设置一个存储池的归置组数量。典型配置给每个 OSD 分配大约
100 个归置组,这样,不用过多计算资源就能得到较优的均衡。
      配置了多个存储池时,要考虑到这些存储池和整个集群的归置组数量要合理。
CRUSH 规则: 当你在存储池里存数据的时候,与此存储池相关联的 CRUSH 规则集可控制 CRUSH 算法,
      并以此操纵集群内对象及其副本的复制(或纠删码编码的存储池里的数据块)。你可以自定义存储池的 CRUSH 规则。
快照: 用 ceph osd pool mksnap 创建快照的时候,实际上创建了某一特定存储池的快照。
设置所有者: 你可以设置一个用户 ID 为一个存储池的所有者。

要把数据组织到存储池里,你可以列出、创建、删除存储池,也可以查看每个存储池的利用率。

 

 

列出存储池

 

要列出集群的存储池,命令如下:

ceph osd lspools

在新安装好的集群上,只有一个 rbd 存储池。

 

创建存储池

创建存储池前先看看存储池、归置组和 CRUSH 配置参考。你最好在配置文件里重置默认归置组数量,因为默认值并不理想。关于归置组数量请参考设置归置组数量

 

例如:

 

osd pool default pg num = 100
osd pool default pgp num = 100

要创建一个存储池,执行:

ceph osd pool create {pool-name} {pg-num} [{pgp-num}] [replicated]         [crush-ruleset-name] [expected-num-objects]
ceph osd pool create {pool-name} {pg-num}  {pgp-num}   erasure         [erasure-code-profile] [crush-ruleset-name] [expected_num_objects]

 

参数含义如下:

{pool-name}
描述:    存储池名称,必须唯一。
类型:    String
是否必需:    必需。

{pg-num}
描述:    存储池拥有的归置组总数。关于如何计算合适的数值,请参见归置组。默认值 8 对大多数系统都不合适。
类型:    整数
是否必需:    Yes
默认值:    8

{pgp-num}
描述:    用于归置的归置组总数。此值应该等于归置组总数,归置组分割的情况下除外。
类型:    整数
是否必需:    没指定的话读取默认值、或 Ceph 配置文件里的值。
默认值:    8

{replicated|erasure}
描述:    存储池类型,可以是副本(保存多份对象副本,以便从丢失的 OSD 恢复)或纠删(获得类似 RAID5 的功能)。多副本存储池需更多原始存储空间,但已实现所有 Ceph 操作;纠删存储池所需原始存储空间较少,但目前仅实现了部分 Ceph 操作。
类型:    String
是否必需:    No.
默认值:    replicated

[crush-ruleset-name]
描述:    此存储池所用的 CRUSH 规则集名字。指定的规则集必须存在。
类型:    String
是否必需:    No.
默认值:    对于多副本( replicated )存储池来说,其默认规则集由 osd pool default crush replicated ruleset 配置决定,此规则集必须存在。 对于用 erasure-code 编码的纠删码( erasure )存储池来说,不同的 {pool-name} 所使用的默认( default )纠删码配置是不同的,如果它不存在的话,会显式地创建它。

[erasure-code-profile=profile]
描述:    仅用于纠删存储池。指定纠删码配置框架,此配置必须已由 osd erasure-code-profile set 定义。
类型:    String
是否必需:    No.

创建存储池时,要设置一个合理的归置组数量(如 100 )。也要考虑到每 OSD 的归置组总数,因为归置组很耗计算资源,所以很多存储池和很多归置组(如 50 个存储池,各包含 100 归置组)会导致性能下降。收益递减点取决于 OSD 主机的强大。

如何为存储池计算合适的归置组数量请参见归置组。

[expected-num-objects]
描述:    为这个存储池预估的对象数。设置此值(要同时把 filestore merge threshold 设置为负数)后,在创建存储池时就会拆分 PG 文件夹,以免运行时拆分文件夹导致延时增大。
类型:    Integer
是否必需:    No.
默认值:    0 ,创建存储池时不拆分目录。

 

 

设置存储池配额

存储池配额可设置最大字节数、和/或每存储池最大对象数。

 

ceph osd pool set-quota {pool-name} [max_objects {obj-count}] [max_bytes {bytes}]

 

例如:

ceph osd pool set-quota data max_objects 10000

 

要取消配额,设置为 0

 

删除存储池

要删除一存储池,执行:

 

ceph osd pool delete {pool-name} [{pool-name} --yes-i-really-really-mean-it]

 

如果你给自建的存储池创建了定制的规则集,你不需要存储池时最好删除它。如果你曾严格地创建了用户及其权限给一个存储池,但存储池已不存在,最好也删除那些用户。

 

重命名存储池

要重命名一个存储池,执行:

 

ceph osd pool rename {current-pool-name} {new-pool-name}

如果重命名了一个存储池,且认证用户有每存储池能力,那你必须用新存储池名字更新用户的能力(即 caps )。

 

查看存储池统计信息

要查看某存储池的使用统计信息,执行命令:

 

rados df

 

拍下存储池快照

 

要拍下某存储池的快照,执行命令:

 

ceph osd pool mksnap {pool-name} {snap-name}

 

删除存储池快照

要删除某存储池的一个快照,执行命令:

ceph osd pool rmsnap {pool-name} {snap-name}

 

调整存储池选项值

要设置一个存储池的选项值,执行命令:

ceph osd pool set {pool-name} {key} {value}

 

你可以设置下列键的值:

size
描述:    设置存储池中的对象副本数,详情参见设置对象副本数。仅适用于副本存储池。
类型:    整数

min_size
描述:    设置 I/O 需要的最小副本数,详情参见设置对象副本数。仅适用于副本存储池。
类型:    整数
适用版本:    0.54 及以上。

crash_replay_interval
描述:    允许客户端重放确认而未提交请求的秒数。
类型:    整数

pgp_num
描述:    计算数据归置时使用的有效归置组数量。
类型:    整数
有效范围:    等于或小于 pg_num 。

crush_ruleset
描述:    集群内映射对象归置时使用的规则集。
类型:    整数

hashpspool
描述:    给指定存储池设置/取消 HASHPSPOOL 标志。
类型:    整数
有效范围:    1 开启, 0 取消
适用版本:    0.48 及以上。

nodelete
描述:    给指定存储池设置/取消 NODELETE 标志。
类型:    整数
有效范围:    1 开启, 0 取消
适用版本:    Version FIXME

nopgchange
描述:    给指定存储池设置/取消 NOPGCHANGE 标志。
类型:    整数
有效范围:    1 开启, 0 取消
适用版本:    Version FIXME

nosizechange
描述:    给指定存储池设置/取消 NOSIZECHANGE 标志。
类型:    整数
有效范围:    1 开启, 0 取消
适用版本:    Version FIXME

write_fadvise_dontneed
描述:    设置或取消指定存储池的 WRITE_FADVISE_DONTNEED 标志。
类型:    Integer
有效范围:    1 开启, 0 取消

noscrub
描述:    设置或取消指定存储池的 NOSCRUB 标志。
类型:    Integer
有效范围:    1 设置, 0 取消

nodeep-scrub
描述:    设置或取消指定存储池的 NODEEP_SCRUB 标志。
类型:    Integer
有效范围:    1 开启, 0 取消

hit_set_type
描述:    启用缓存存储池的命中集跟踪,详情见 Bloom 过滤器。
类型:    String
有效值:    bloom, explicit_hash, explicit_object
默认值:    bloom ,其它是用于测试的。

hit_set_count
描述:    为缓存存储池保留的命中集数量。此值越高, ceph-osd 守护进程消耗的内存越多。
类型:    整数
有效范围:    1. Agent doesn’t handle > 1 yet.

hit_set_period
描述:    为缓存存储池保留的命中集有效期。此值越高, ceph-osd 消耗的内存越多。
类型:    整数
实例:    3600 1hr

hit_set_fpp
描述:    bloom 命中集类型的假阳性概率。详情见 Bloom 过滤器。
类型:    Double
有效范围:    0.0 - 1.0
默认值:    0.05

cache_target_dirty_ratio
描述:    缓存存储池包含的脏对象达到多少比例时就把它们回写到后端的存储池。
类型:    Double
默认值:    .4

cache_target_dirty_high_ratio
描述:    缓存存储池内包含的已修改(脏的)对象达到此比例时,缓存层代理就会更快地把脏对象刷回到后端存储池。
类型:    Double
默认值:    .6

cache_target_full_ratio
描述:    缓存存储池包含的干净对象达到多少比例时,缓存代理就把它们赶出缓存存储池。
类型:    Double
默认值:    .8

target_max_bytes
描述:    达到 max_bytes 阀值时 Ceph 就回写或赶出对象。
类型:    整数
实例:    1000000000000 #1-TB

target_max_objects
描述:    达到 max_objects 阀值时 Ceph 就回写或赶出对象。
类型:    整数
实例:    1000000 #1M objects

hit_set_grade_decay_rate
描述:    在两个连续 hit_sets 间的热度衰退速率。
类型:    Integer
有效范围:    0 - 100
默认值:    20

hit_set_grade_search_last_n
描述:    计算热度时,在 hit_sets 里最多计数 N 次。
类型:    Integer
有效范围:    0 - hit_set_count
默认值:    1

cache_min_flush_age
描述:    达到此时间(单位为秒)时,缓存代理就把某些对象从缓存存储池刷回到存储池。
类型:    整数
实例:    600 10min

cache_min_evict_age
描述:    达到此时间(单位为秒)时,缓存代理就把某些对象从缓存存储池赶出。
类型:    整数
实例:    1800 30min

fast_read
描述:    在纠删码存储池上,如果打开了这个标志,读请求会向所有分片发送子操作读,然后等着,直到收到的分片足以解码给客户端。对 jerasure 和 isa 纠删码插件来说,只要前 K 个请求返回,就能立即解码、并先把这些数据发给客户端。这样有助于资源折衷,以提升性能。当前,这些标志还只能用于纠删码存储池。
类型:    Boolean
默认值:    0

scrub_min_interval
描述:    在负载低时,洗刷存储池的最大间隔秒数。如果是 0 ,就按照配置文件里的 osd_scrub_min_interval 。
类型:    Double
默认值:    0

scrub_max_interval
描述:    不管集群负载如何,都要洗刷存储池的最大间隔秒数。如果是 0 ,就按照配置文件里的 osd_scrub_max_interval 。
类型:    Double
默认值:    0

deep_scrub_interval
描述:    “深度”洗刷存储池的间隔秒数。如果是 0 ,就按照配置文件里的 osd_deep_scrub_interval 。
类型:    Double
默认值:    0

 

获取存储池选项值

 

要获取一个存储池的选项值,执行命令:

ceph osd pool get {pool-name} {key}

 

你可以获取到下列选项的值:

 

 

size
描述:    见 size
类型:    整数

min_size
描述:    见 min_size
类型:    整数
适用版本:    0.54 及以上

crash_replay_interval
描述:    见 crash_replay_interval
类型:    整数

pgp_num
描述:    见 pgp_num
类型:    整数
有效范围:    小于等于 pg_num 。

crush_ruleset
描述:    见 crush_ruleset
类型:    整数

hit_set_type
描述:    见 hit_set_type
类型:    String
有效选项:    bloom 、 explicit_hash 、 explicit_object

hit_set_count
描述:    见 hit_set_count
类型:    整数

hit_set_period
描述:    见 hit_set_period
类型:    整数

hit_set_fpp
描述:    见 hit_set_fpp
类型:    Double

cache_target_dirty_ratio
描述:    见 cache_target_dirty_ratio
类型:    Double

cache_target_dirty_high_ratio
描述:    见 cache_target_dirty_high_ratio
类型:    Double

cache_target_full_ratio
描述:    见 cache_target_full_ratio
类型:    Double

target_max_bytes
描述:    见 target_max_bytes
类型:    整数

target_max_objects
描述:    见 target_max_objects
类型:    整数

cache_min_flush_age
描述:    见 cache_min_flush_age
类型:    整数

cache_min_evict_age
描述:    见 cache_min_evict_age
类型:    整数

fast_read
描述:    见 fast_read
类型:    Boolean

scrub_min_interval
描述:    见 scrub_min_interval
类型:    Double

scrub_max_interval
描述:    见 scrub_max_interval
类型:    Double

deep_scrub_interval
描述:    见 deep_scrub_interval
类型:    Double

 

 

设置对象副本数

要设置多副本存储池的对象副本数,执行命令:

ceph osd pool set {poolname} size {num-replicas}

注意:{num-replicas} 包括对象自身,如果你想要对象自身及其两份拷贝共计三份,指定 3。

 

 

例如:

ceph osd pool set data size 3

你可以在每个存储池上执行这个命令。注意,一个处于降级模式的对象其副本数小于规定值 pool size ,但仍可接受 I/O 请求。为保证 I/O 正常,可用 min_size 选项为其设置个最低副本数。例如:

 

ceph osd pool set data min_size 2

这确保数据存储池里任何副本数小于 min_size 的对象都不会收到 I/O 了。

 

获取对象副本数

要获取对象副本数,执行命令:

ceph osd dump | grep replicated size

 

Ceph 会列出存储池,且高亮 replicated size 属性。默认情况下, Ceph 会创建一对象的两个副本(一共三个副本,或 size 值为 3 )

 

三、分级缓存

 

分级缓存可提升后端存储内某些(热点)数据的 I/O 性能。分级缓存需创建一个由高速而昂贵存储设备(如 SSD )组成的存储池、作为缓存层,以及一个相对低速/廉价设备组成的后端存储池(或纠删码编码的)、作为经济存储层。 Ceph 的对象处理器决定往哪里存储对象,分级代理决定何时把缓存内的对象刷回后端存储层;所以缓存层和后端存储层对 Ceph 客户端来说是完全透明的

 

技术分享图片

 

 

 缓存层代理自动处理缓存层和后端存储之间的数据迁移。然而,管理员仍可干预此迁移规则,主要有两种场景:

 

回写模式: 管理员把缓存层配置为 writeback 模式时, Ceph 客户端们会把数据写入缓存层、并收到缓存层发来的 ACK ;
      写入缓存层的数据会被迁移到存储层、然后从缓存层刷掉。直观地看,缓存层位于后端存储层的“前面”,当 Ceph 客户端要读取的数据位于存储层时,
      缓存层代理会把这些数据迁移到缓存层,然后再发往 Ceph 客户端。从此, Ceph 客户端将与缓存层进行 I/O 操作,直到数据不再被读写。
      此模式对于易变数据来说较理想(如照片/视频编辑、事务数据等)。
只读模式: 管理员把缓存层配置为
readonly 模式时, Ceph 直接把数据写入后端。读取时, Ceph 把相应对象从后端复制到缓存层,
      根据已定义策略、脏对象会被缓存层踢出。此模式适合不变数据(如社交网络上展示的图片/视频、 DNA 数据、 X-Ray 照片等),
      因为从缓存层读出的数据可能包含过期数据,即一致性较差。对易变数据不要用 readonly 模式。

 

 正因为所有 Ceph 客户端都能用缓存层,所以才有提升块设备、 Ceph 对象存储、 Ceph 文件系统和原生绑定的 I/O 性能的潜力。

 

 

配置存储池

要设置缓存层,你必须有两个存储池。一个作为后端存储、另一个作为缓存。

 

 配置后端存储池

 设置后端存储池通常会遇到两种场景:

标准存储: 此时,Ceph存储集群内的存储池保存了一对象的多个副本;
纠删存储池: 此时,存储池用纠删码高效地存储数据,性能稍有损失。

在标准存储场景中,你可以用 CRUSH 规则集来标识失败域(如 osd 、主机、机箱、机架、排等)。

当规则集所涉及的所有驱动器规格、速度(转速和吞吐量)和类型相同时, OSD 守护进程运行得最优。

创建规则集的详情见 CRUSH 图。创建好规则集后,再创建后端存储池。

在纠删码编码情景中,创建存储池时指定好参数就会自动生成合适的规则集,详情见创建存储池

在后续例子中,我们把 cold-storage 当作后端存储池。

 

配置缓存池

缓存存储池的设置步骤大致与标准存储情景相同,但仍有不同:缓存层所用的驱动器通常都是高性能的、且安装在专用服务器上、有自己的规则集。制定规则集时,要考虑到装有高性能驱动器的主机、并忽略没有的主机。详情见给存储池指定 OSD

在后续例子中, hot-storage 作为缓存存储池、 cold-storage 作为后端存储池。

关于缓存层的配置及其默认值的详细解释请参考存储池——调整存储池

 

创建缓存层

 

设置一缓存层需把缓存存储池挂接到后端存储池上:

 

ceph osd tier add {storagepool} {cachepool}

例如:

ceph osd tier add cold-storage hot-storage

 

用下列命令设置缓存模式:

 

ceph osd tier cache-mode {cachepool} {cache-mode}

 

例如:

 

ceph osd tier cache-mode hot-storage writeback

 

缓存层盖在后端存储层之上,所以要多一步:必须把所有客户端流量从存储池迁移到缓存存储池。用此命令把客户端流量指向缓存存储池:

 

ceph osd tier set-overlay {storagepool} {cachepool}

 

例如:

 

ceph osd tier set-overlay cold-storage hot-storage

 

配置缓存层

缓存层支持几个配置选项,可按下列语法配置:

 

ceph osd pool set {cachepool} {key} {value}

 

目标尺寸和类型

 

生产环境下,缓存层的 hit_set_type 还只能用 Bloom 过滤器:

ceph osd pool set {cachepool} hit_set_type bloom

 

例如:

ceph osd pool set hot-storage hit_set_type bloom

 

hit_set_counthit_set_period 选项分别定义了 HitSet 覆盖的时间区间、以及保留多少个这样的 HitSet 。

 

ceph osd pool set {cachepool} hit_set_count 1
ceph osd pool set {cachepool} hit_set_period 3600
ceph osd pool set {cachepool} target_max_bytes 1000000000000

 

保留一段时间以来的访问记录,这样 Ceph 就能判断一客户端在一段时间内访问了某对象一次、还是多次(存活期与热度)。

min_read_recency_for_promote 定义了在处理一个对象的读操作时检查多少个 HitSet ,检查结果将用于决定是否异步地提升对象。

它的取值应该在 0 和 hit_set_count 之间,如果设置为 0 ,对象会一直被提升;

如果设置为 1 ,就只检查当前 HitSet ,如果此对象在当前 HitSet 里就提升它,否则就不提升;

设置为其它值时,就要挨个检查此数量的历史 HitSet ,如果此对象出现在 min_read_recency_for_promote 个 HitSet 里的任意一个,那就提升它。

还有一个相似的参数用于配置写操作,它是 min_write_recency_for_promote

 

ceph osd pool set {cachepool} min_read_recency_for_promote 1
ceph osd pool set {cachepool} min_write_recency_for_promote 1

 

注意:统计时间越长、 min_read_recency_for_promotemin_write_recency_for_promote 取值越高, ceph-osd 进程消耗的内存就越多,特别是代理正忙着刷回或赶出对象时,此时所有 hit_set_count 个 HitSet 都要载入内存。

 

 

缓存空间消长

缓存分层代理有两个主要功能:

 

 刷回: 代理找出修改过(或脏)的对象、并把它们转发给存储池做长期存储。
 赶出: 代理找出未修改(或干净)的对象、并把最近未用过的赶出缓存。

 

相对空间消长

 

缓存分层代理可根据缓存存储池相对大小刷回或赶出对象。当缓存池包含的已修改(或脏)对象达到一定比例时,缓存分层代理就把它们刷回到存储池。用下列命令设置 cache_target_dirty_ratio

 

ceph osd pool set {cachepool} cache_target_dirty_ratio {0.0..1.0}

 

例如,设置为 0.4 时,脏对象达到缓存池容量的 40% 就开始刷回:

 

ceph osd pool set hot-storage cache_target_dirty_ratio 0.4

 

当脏对象达到其容量的一定比例时,要更快地刷回脏对象。用下列命令设置 cache_target_dirty_high_ratio:

 

ceph osd pool set {cachepool} cache_target_dirty_high_ratio {0.0..1.0}

 

例如,设置为 0.6 表示:脏对象达到缓存存储池容量的 60% 时,将开始更激进地刷回脏对象。显然,其值最好在 dirty_ratio 和 full_ratio 之间:

 

ceph osd pool set hot-storage cache_target_dirty_high_ratio 0.6

 

当缓存池利用率达到总容量的一定比例时,缓存分层代理会赶出部分对象以维持空闲空间。执行此命令设置 cache_target_full_ratio

 

ceph osd pool set {cachepool} cache_target_full_ratio {0.0..1.0}

例如,设置为 0.8 时,干净对象占到总容量的 80% 就开始赶出缓存池:

 

ceph osd pool set hot-storage cache_target_full_ratio 0.8

 

绝对空间消长

缓存分层代理可根据总字节数或对象数量来刷回或赶出对象,用下列命令可指定最大字节数:

 

ceph osd pool set {cachepool} target_max_bytes {#bytes}

 

例如,用下列命令配置在达到 1TB 时刷回或赶出:

 

ceph osd pool set hot-storage target_max_bytes 1000000000000

 

用下列命令指定缓存对象的最大数量:

 

ceph osd pool set {cachepool} target_max_objects {#objects}

 

例如,用下列命令配置对象数量达到 1M 时开始刷回或赶出:

 

ceph osd pool set hot-storage target_max_objects 1000000

 

注意:如果两个都配置了,缓存分层代理会按先到的阀值执行刷回或赶出。

 

 

缓存时长

你可以规定缓存层代理必须延迟多久才能把某个已修改(脏)对象刷回后端存储池:

 

ceph osd pool set {cachepool} cache_min_flush_age {#seconds}

 

例如,让已修改(或脏)对象需至少延迟 10 分钟才能刷回,执行此命令:

ceph osd pool set hot-storage cache_min_flush_age 600

 

你可以指定某对象在缓存层至少放置多长时间才能被赶出:

 

ceph osd pool {cache-tier} cache_min_evict_age {#seconds}

 

例如,要规定 30 分钟后才赶出对象,执行此命令:

ceph osd pool set hot-storage cache_min_evict_age 1800

 

 

拆除缓存层

回写缓存和只读缓存的去除过程不太一样。

 

拆除只读缓存

只读缓存不含变更数据,所以禁用它不会导致任何近期更改的数据丢失。

 

    1.把缓存模式改为 none 即可禁用。

    ceph osd tier cache-mode {cachepool} none

    例如:

    ceph osd tier cache-mode hot-storage none

    2.去除后端存储池的缓存池。

    ceph osd tier remove {storagepool} {cachepool}

    例如:

    ceph osd tier remove cold-storage hot-storage

 

拆除回写缓存

回写缓存可能含有更改过的数据,所以在禁用并去除前,必须采取些手段以免丢失缓存内近期更改的对象。

 

1.把缓存模式改为 forward ,这样新的和更改过的对象将直接刷回到后端存储池。

    ceph osd tier cache-mode {cachepool} forward

    例如:

    ceph osd tier cache-mode hot-storage forward

2.确保缓存池已刷回,可能要等数分钟:

    rados -p {cachepool} ls

    如果缓存池还有对象,你可以手动刷回,例如:

    rados -p {cachepool} cache-flush-evict-all

3. 去除此盖子,这样客户端就不会被指到缓存了。 ceph osd tier remove
-overlay {storagetier} 例如: ceph osd tier remove-overlay cold-storage 4.最后,从后端存储池剥离缓存层存储池。 ceph osd tier remove {storagepool} {cachepool} 例如: ceph osd tier remove cold-storage hot-storage

 

 

四、归置组

 

预定义 pg_num

 

用此命令创建存储池时:

ceph osd pool create {pool-name} pg_num

 

确定 pg_num 取值是强制性的,因为不能自动计算。下面是几个常用的值:

1.少于 5 个 OSD 时可把 pg_num 设置为 128
2.OSD 数量在 510 个时,可把 pg_num 设置为 512
3.OSD 数量在 1050 个时,可把 pg_num 设置为 4096
4.OSD 数量大于 50 时,你得理解权衡方法、以及如何自己计算 pg_num 取值
5.自己计算 pg_num 取值时可借助 pgcalc 工具

 

随着 OSD 数量的增加,正确的 pg_num 取值变得更加重要,因为它显著地影响着集群的行为、以及出错时的数据持久性(即灾难性事件导致数据丢失的概率)。

 

归置组是如何使用的

 

存储池内的归置组( PG )把对象汇聚在一起,因为跟踪每一个对象的位置及其元数据需要大量计算——即一个拥有数百万对象的系统,不可能在对象这一级追踪位置。

 

技术分享图片

 

 

 Ceph 客户端会计算某一对象应该位于哪个归置组里,它是这样实现的,先给对象 ID 做哈希操作,然后再根据指定存储池里的 PG 数量、存储池 ID 做一个运算。

详情见 PG 映射到 OSD。

 

 

放置组中的对象内容存储在一组操作系统中。例如, 在第二个大小的复制池中, 每个放置组将在两个操作系统上存储对象, 如下所示。
 

技术分享图片

 

 

 

注释:

1.如果 osd #2 失败, 另一个将被分配到放置组 #1 并将在 osd #1 中填充所有对象的副本。

2.如果将池大小从两个更改为三, 将为放置组分配一个额外的 OSD, 并将接收放置组中所有对象的副本。

3.放置组不拥有 OSD, 它们与来自同一池甚至其他池的其他放置组共享它。如果 osd #2 失败, 则放置组 #2 还必须使用 osd #3 还原对象的副本。

4.当放置组的数量增加时, 新的放置组将被分配操作系统。粉碎功能的结果也会改变, 一些来自前置组的物体将被复制到新的放置组中, 并从旧的位置上移除。

 

 

放置组权衡

数据的耐用性, 甚至在所有OSD的分布调用更多的放置组, 但他们的数量应该减少到最低, 以节省 CPU 和内存。

 

数据耐久性

在 OSD 失败后, 数据丢失的风险会增加, 直到它所包含的数据完全恢复。让我们设想一个在单个放置组中导致永久数据丢失的方案:

1.OSD 失败, 它所包含的对象的所有副本都将丢失。对于放置组中的所有对象, 复制突然的数量从三下降到2。
2.Ceph 通过选取新的 OSD 来重新创建所有对象的第三个副本, 从而开始恢复此放置组
3.在同一位置组中的另一个 osd 在新 osd 完全填充第三个副本之前失败。有些对象只会有一个幸存的副本。
4.Ceph 选择另一个 OSD, 并不断复制对象, 以恢复所需的副本数。
5.在相同的放置组中, 第三个 OSD 在恢复完成之前失败。如果此 OSD 包含对象的唯一剩余副本, 则它将永久丢失。

 

在群集中,三副本池中包含 10 OSD 和512放置组,CRUSH将给每个放置组三个 OSD。最后, 每个 OSD 将最后出于托管 (512 * 3)/10 = ?150放置组。当第一个 OSD 失败时, 上述方案将同时启动所有150位置组的恢复。

150个放置组很可能是均匀地传播在9剩余的 OSD被恢复。因此, 每个剩余的 OSD 都可能将对象的副本发送给所有其他osd, 并且还会接收一些新的对象来存储, 因为它们成为新的放置组的一部分。

完成此恢复所需的时间完全取决于 Ceph 群集的体系结构。让我们说, 每个 osd 由一个1TB 固态硬盘托管在一台机器上, 所有这些都连接到一个 10 gb/s 交换机和恢复为一个单一的 osd 完成在 M 分钟内。如果每台机器有两个操作系统, 并且没有 SSD 日志和 1 gb/s 开关, 那么它至少会有一个数量级的慢速。

 

在这种规模的集群中, 放置组的数量对数据的耐久性几乎没有影响。它可能是128或 8192, 恢复不会慢或快。

 

但是, 将相同的 Ceph 群集增加到 20 osd 而不是 10 osd, 可能会加速恢复, 从而显著提高数据的耐久性。每个 osd 现在只参与 ~ 75 放置组, 而不是? 150, 当只有 10 osd, 它仍然需要所有19剩余的操作系统执行相同数量的对象副本, 以恢复。但是, 10 OSD 必须复制大约100GB 每个, 他们现在必须复制 50GB, 而不是。如果网络是瓶颈, 恢复的速度将会加倍。换言之, 当操作系统的数量增加时, 恢复速度会更快。

 

 

如果这个集群增长到 40 OSD, 他们中的每个将只托管?35的位置组。如果 OSD 死了, 恢复将保持更快, 除非它被另一个瓶颈阻止。但是, 如果这个集群增长到 200 OSD, 他们中的每一个只会托管?7的位置组。如果 osd 死亡, 恢复将在这些位置组中的 21 (7 * 3) osd 之间发生: 恢复的时间比 40 osd 时要长, 这意味着应增加放置组的数量。

不论恢复时间有多短,在此期间都可能有第二个 OSD 失败。在前述的有 10 个 OSD 的集群中,不管哪个失败了,都有大约 17 个归置组(即需恢复的大约 150 / 9 个归置组)将只有一份可用副本;并且假设剩余的 8 个 OSD 中任意一个失败,两个归置组中最后的对象都有可能丢失(即正在恢复的、大约 17 / 8 个仅剩一个副本的归置组)。

当集群大小变为 20 个 OSD 时, 3 个 OSD 丢失导致的归置组损坏会降低。第二个 OSD 丢失会降级大约 4 个(即需恢复的归置组约为 75 / 19 )而不是约 17 个归置组,并且只有当第三个 OSD 恰好是包含可用副本的四分之一个 OSD 时、才会丢失数据。换句话说,假设在恢复期间丢失一个 OSD 的概率是 0.0001% ,那么,在包含 10 个 OSD 的集群中丢失 OSD 的概率是 17 * 10 * 0.0001% ,而在 20 个 OSD 的集群中将是 4 * 20 * 0.0001% 。

简而言之, 更多的 OSD 意味着更快的恢复和较低的连锁失败风险导致了一个位置组的永久性损失。在数据耐久性方面, 有512或4096的放置组大致相当于一个少于 50 OSD 的群集中。简而言之, 更多的 OSD 意味着更快的恢复和较低的连锁失败风险导致了一个位置组的永久性损失。在数据耐久性方面, 有512或4096的放置组大致相当于一个少于 50 OSD 的群集中。

 

注意: 添加到群集中的新 OSD 可能需要很长时间才能填充分配给它的放置组。但是, 没有任何对象的退化, 它对集群中所包含的数据的耐久性没有影响。

 

池中的对象分布

理论上对象在每个放置组中均匀分布。由于CRUSH计算每个对象的放置组, 但实际上并不知道在这个放置组中每个 osd 中存储了多少数据, 因此, 放置组数与 osd 数之间的比率可能会影响数据的分布显著.

 

例如, 如果在三复制池中有一个十 osd 的单个放置组, 则只有3个osd会被使用, 因为粉碎将没有其他选择。当有更多的放置组可用时, 对象更有可能均匀地分布在其中。CRUSH还尽一切努力均匀地传播 OSD 在所有现有的放置组。

 只要放置组比 OSD多一个或两个数量级或更多, 分配应该是均匀的。

不均匀的数据分布可能是由 OSD 和放置组之间的比率以外的因素造成的。由于CRUSH没有考虑到物体的大小, 一些非常大的物体可能造成不平衡。100万4K 对象共计4GB 均匀地分布在1000安置小组在 10 OSD。他们将使用 4GB/10 = 400MB 在每个 OSD。如果将一个400MB 对象添加到池中, 则支持在其中放置对象的位置组的三 OSD 将用 400MB + 400MB = 800MB 填充, 而其余七个则只保留400MB


内存、处理器和网络使用情况

 各个归置组、 OSD 和监视器都一直需要内存、网络、处理器,在恢复期间需求更大。为消除过载而把对象聚集成簇是归置组存在的主要原因。
最小化归置组数量可节省不少资源。

 

 确定归置组数量

 

如果你有超过50的 osd, 我们建议每 osd 约50-100 放置组, 以平衡资源的使用, 数据的耐久性和分布。如果你有少于50的 OSD, 在预选中进行拣选是最好的。对于单个对象池, 可以使用以下公式获取基线:

             (OSDs * 100)
Total PGs =  ------------
              pool size

 

其中, 池大小是复制池的副本数, 也可以是用于擦除编码池的 K + M 总和 (由 ceph osd 擦除码配置文件返回)。

然后, 您应该检查该结果是否与您设计的 Ceph 群集的方式有意义, 以最大限度地提高数据的耐久性、对象分布和最大限度地减少资源使用。

其结果汇总后应该接近 2 的幂。汇总并非强制的,如果你想确保所有归置组内的对象数大致相等,最好检查下。

比如,一个配置了 200 个 OSD 且副本数为 3 的集群,你可以这样估算归置组数量:

 

(200 * 100)
----------- = 6667. Nearest power of 2: 8192
     3

 

当用了多个数据存储池来存储数据时,你得确保均衡每个存储池的归置组数量、且归置组数量分摊到每个 OSD ,这样才能达到较合理的归置组总量,并因此使得每个 OSD 无需耗费过多系统资源或拖慢连接进程就能实现较小变迁。

 

 

例如, 在一个有10个池的集群中,10个 osd  组有512个放置组, 总共有5120个放置组。它不会使用太多的资源。但是, 如果创建了1000池, 每组有512个放置小组, 则 OSD 将处理5万个放置组, 并且需要大量的资源和时间来进行对等操作。

 

设置归置组数量

要设置某存储池的归置组数量,你必须在创建它时就指定好,详情见创建存储池。一存储池的归置组数量设置好之后,还可以增加(但不可以减少),下列命令可增加归置组数量:

ceph osd pool set {pool-name} pg_num {pg_num}

 

你增加归置组数量后、还必须增加用于归置的归置组( pgp_num )数量,这样才会开始重均衡。 pgp_num 数值才是 CRUSH 算法采用的用于归置的归置组数量。虽然 pg_num 的增加引起了归置组的分割,但是只有当用于归置的归置组(即 pgp_num )增加以后,数据才会被迁移到新归置组里。 pgp_num 的数值应等于 pg_num 。可用下列命令增加用于归置的归置组数量:

ceph osd pool set {pool-name} pgp_num {pgp_num}

 

获取归置组数量

要获取一个存储池的归置组数量,执行命令:

 

ceph osd pool get {pool-name} pg_num

 

获取归置组统计信息

要获取集群里归置组的统计信息,执行命令:

ceph pg dump [--format {format}]

可用格式有纯文本 plain (默认)和 json

 

获取卡住的归置组统计信息

要获取所有卡在某状态的归置组统计信息,执行命令:

ceph pg dump_stuck inactive|unclean|stale|undersized|degraded [--format <format>] [-t|--threshold <seconds>]

 

Inactive (不活跃)归置组不能处理读写,因为它们在等待一个有最新数据的 OSD 复活且进入集群。

Unclean (不干净)归置组含有复制数未达到期望数量的对象,它们应该在恢复中。

Stale (不新鲜)归置组处于未知状态:存储它们的 OSD 有段时间没向监视器报告了(由 mon_osd_report_timeout 配置)。

可用格式有 plain (默认)和 json 。阀值定义的是,归置组被认为卡住前等待的最小时间(默认 300 秒)。

 

获取一归置组运行图

 

要获取一个具体归置组的归置组图,执行命令:

ceph pg map {pg-id}

 

例如:

 

ceph pg map 1.6c

Ceph 将返回归置组图、归置组、和 OSD 状态:

osdmap e13 pg 1.6c (1.6c) -> up [1,0] acting [1,0]

 

获取一 PG 的统计信息

 

要查看一个具体归置组的统计信息,执行命令:

ceph pg {pg-id} query

 

洗刷归置组

要洗刷一个归置组,执行命令:

 

ceph pg scrub {pg-id}

 

Ceph 检查原始的和任何复制节点,生成归置组里所有对象的目录,然后再对比,确保没有对象丢失或不匹配,并且它们的内容一致。

 

 

恢复丢失的

如果集群丢了一或多个对象,而且必须放弃搜索这些数据,你就要把未找到的对象标记为丢失( lost )。

如果所有可能的位置都查询过了,而仍找不到这些对象,你也许得放弃它们了。这可能是罕见的失败组合导致的,集群在写入完成前,未能得知写入是否已执行。

当前只支持 revert 选项,它使得回滚到对象的前一个版本(如果它是新对象)或完全忽略它。要把 unfound 对象标记为 lost ,执行命令:

ceph pg {pg-id} mark_unfound_lost revert|delete

 

注意:要谨慎使用,它可能迷惑那些期望对象存在的应用程序。

 

 

归置组状态

检查集群状态时(如运行 ceph -sceph -w ), Ceph 会报告归置组状态。一个归置组有一到多种状态,其最优状态为 active+clean

Creating:Ceph 仍在创建归置组。
Active:Ceph 可处理到归置组的请求。
Clean:Ceph 把归置组内的对象复制了规定次数。
Down:包含必备数据的副本挂了,所以归置组离线。
Replay:某 OSD 崩溃后,归置组在等待客户端重放操作。
Splitting:Ceph 正在把一归置组分割为多个。(实现了?) Scrubbing:Ceph 正在检查归置组的一致性。 Degraded:归置组内的对象还没复制到规定次数。 Inconsistent:Ceph 检测到了归置组内一或多个副本间不一致(如各对象大小不一、恢复后对象还没复制到副本那里、等等)。 Peering:归置组正在互联。

Repair:Ceph 正在检查归置组、并试图修复发现的不一致(如果可能的话)。 Recovering:Ceph 正在迁移
/同步对象及其副本。 Backfill :Ceph 正在扫描并同步整个归置组的内容,而不是根据日志推算哪些最新操作需要同步。 Backfill 是恢复的一种特殊情况。 Wait-backfill:归置组正在排队,等候回填。 Backfill-toofull:回填操作在等待,因为目标 OSD 使用率超过了占满率。


Incomplete:Ceph 探测到某一归置组可能丢失了写入信息,或者没有健康的副本。如果你看到了这个状态,试着启动一下有可能包含所需信息的失败 OSD 、或者临时调整一下 min_size 以完成恢复。 Stale:归置组处于一种未知状态——从归置组运行图变更起就没再收到它的更新。 Remapped:归置组被临时映射到了另外一组 OSD ,它们不是 CRUSH 算法指定的。 Undersized:此归置组的副本数小于配置的存储池副本水平。 Peered:此归置组已互联,但是不能向客户端提供服务,因为其副本数没达到本存储池的配置值( min_size 参数)。在此状态下可以进行恢复,所以此归置组最终能达到 min_size 。

 

归置组术语解释

当你执行诸如 ceph -wceph osd dump 、及其他和归置组相关的命令时, Ceph 会返回下列术语及其值:

Peering:(建立互联) 是一种过程,它使得存储着同一归置组的所有 OSD 对归置组内的所有对象及其元数据统一意见。需要注意的是,达成一致不意味着它们都有最新内容。
Acting Set:(在任集合) 一列有序 OSD ,它们为某一特定归置组(或其中一些元版本)负责。
Up Set:The ordered list of OSDs responsible for a particular placement group for a particular epoch according to CRUSH. 
    Normally this is the same as the Acting Set, except when the Acting Set has been explicitly overridden via pg_temp in the OSD Map. [译者:此处原文没看懂……瞎译如下] (当选集合) 一列有序 OSD ,它们依据 CRUSH 算法为某一归置组的特定元版本负责。它通常和 Acting Set 相同,
    除非 Acting Set 被 OSD 运行图里的 pg_temp 显式地覆盖掉了。
Current Interval 或 Past Interval: 某一特定归置组所在 Acting Set 和 Up Set 未更改时的一系列 OSD 运行图元版本。 Primary: (主 OSD ) Acting Set 的成员(按惯例第一个),它负责协调互联,并且是归置组内惟一接受客户端初始写入的 OSD 。 Replica:(副本 OSD ) 一归置组的 Acting Set 内不是主 OSD 的其它 OSD ,它们被同等对待、并由主 OSD 激活。 Stray:(彷徨 OSD ) 某一 OSD ,它不再是当前 Acting Set 的成员,但还没被告知它可以删除那个归置组副本。 Recovery:(恢复) 确保 Acting Set 内、一归置组中的所有对象的副本都存在于所有 OSD 上。一旦互联完成,主 OSD 就以接受写操作,且恢复进程可在后台进行。
PG Info:Basic metadata about the placement group’s creation epoch, the version
for the most recent write to the placement group, last epoch started, last epoch clean, and the beginning of the current interval. Any inter-OSD communication about placement groups includes the PG Info, such that any OSD that knows a placement group exists (or once existed) also has a lower bound on last epoch clean or last epoch started.   (归置组信息) [译者:此处原文没看透……瞎译如下] 基本元数据,
    关于归置组创建元版本、向归置组的最新写版本、最近的开始元版本( last epoch started )、最近的干净元版本( last epoch clean )、
    和当前间隔( current interval )的起点。 OSD 间关于归置组的任何通讯都包含 PG Info ,
    这样任何知道一归置组存在(或曾经存在)的 OSD 也必定有 last epoch clean 或 last epoch started 的下限。
PG Log:(归置组日志) 一归置组内对象的一系列最近更新。注意,这些日志在 Acting Set 内的所有 OSD 确认更新到某点后可以删除。 Missing Set:(缺失集合) 各 OSD 都记录更新日志,而且如果它们包含对象内容的更新,会把那个对象加入一个待更新列表,
    这个列表叫做那个
<OSD,PG> 的 Missing Set 。
Authoritative History:(权威历史) 一个完整、完全有序的操作集合,如果再次执行,可把一 OSD 上的归置组副本还原到最新。
Epoch:(元版本) 单递增 OSD 运行图版本号。 Last Epoch Start:(最新起始元版本) 一最新元版本,在这点上,一归置组所对应 Acting Set 内的所有节点都对权威历史达成了一致、并且互联被认为成功了。
up_thru:(领导拍板) 主 OSD 要想成功完成互联,它必须通过当前 OSD 图元版本通知一个监视器,让此监视器在 osd 图中设置其 up_thru 。这会使互联进程忽略之前的 Acting Set ,因为它经历特定顺序的失败后一直不能互联,比如像下面的第二周期: acting
set = [A,B] acting set = [A] acting set = [] 之后很短时间(例如同时失败、但探测是交叉的) acting set = [B] ( B 重启了、但 A 没有) Last Epoch Clean:(最新干净元版本) 最近的 Epoch ,这时某一特定归置组所在 Acting Set 内的所有节点都全部更新了(包括归置组日志和对象内容)。在这点上,恢复被认为已完成。

 

以上是关于Ceph 存储集群5-数据归置的主要内容,如果未能解决你的问题,请参考以下文章

004 ceph存储池

ceph 高级运维

ceph pg degraded#yyds干货盘点#

ceph pg分配状态#yyds干货盘点#

ceph-rbd kvm 删除数据后集群空间不释放

云原生之存储实战部署Ceph分布式存储集群