存储池


pool-->namespace,pool-->pg,pg和namespace没有隶属关系,pg(Placement Group)规置组。

关于存储池:

        RADOS存储集群提供的基础存储服务需要由“存储池(pool)”分割为逻辑存储区域,此类的逻辑区域亦是对象数据的名称空间。

        实践中,管理员可以为特定应用程序存储不同类型数据的需求分别创建专用的存储池,例如rbd存储池、rgw存储池等,也可以为某个项目或某个用户创建专有的存储池。

        存储池还可以再进一步细分为一至多个名称空间(namespace)。

        客户端(包括rbd和rgw等)存取数据时,需要事先指定存储池名称、用户名和密钥等信息完成认证,而后将一直维持与其指定的存储池的连接,于是也可以把存储池看作是客户端的IO接口。

存储池类型:

        副本池(replicated):把每个对象在集群中存储为多个副本,其中存储于主OSD的为主副本,副本数量在创建存储池时由管理员指定;此为默认的存储池类型;(可快速读取)

        纠删码池(erasurecode):把各对象存储为N=K+M个块,其中,K为数据块数量,M为编码块数量,因此存储池的尺寸为K+M;(更高的磁盘利用率,读取需要CPU资源)

        rbd必须为副本型的纠删码池,radosgw可以使用纠删码池。


归置组PG的计算:

        归置组的数量由管理员在创建存储池时指定,而后由CRUSH负责创建和使用通常,PG的数量应该是数据的合理粒度的子集。

        例如,一个包含256个PG的存储池意味着每个PG包含大约1/256的存储池数据当需要将PG从一个OSD移动到另一个OSD时,PG的数量会对性能产生影响。

        PG数量过少,Ceph将不得不同时移动相当数量的数据,其产生的网络负载将对集群的正常性能输出产生负面影响。

        而在过多的PG数量场景中在移动极少量的数据时,Ceph将会占用过多的CPU和RAM,从而对集群的计算资源产生负面影响。

        PG数量在群集分发数据和重新平衡时扮演着重要作用。

        在所有OSD之间进行数据持久存储及完成数据分布会需要较多的归置组,但是它们的数量应该减少到最大性能所需的最小数量值,以节省CPU和内存资源。

        一般说来,对于有着超过50个OSD的RADOS集群,建议每个OSD大约有50-100个PG以平衡资源使用,取得更好的数据持久性和数据分布,更大规模的集群中,每个OSD大约可持有100-200个PG。

        至于应该使用多少个PG,可通过下面的公式计算后,将其值以类似于四舍五入到最近的2的N次幂

        ( TotalOSDs * PGPerOSD ) / Replicationfactor => TotalPGs

        一个RADOS集群上可能会存在多个存储池,因此管理员还需要考虑所有存储池上的PG分布后每个OSD需要映射的PG数量。


( 总osd数 X 每个osd的pg数 ) / 副本数 => 总pg数。

总pg数 / pool数量 = 每个pool的pg数(再取一个最接近这个数的2的N方)


PG状态


Degraded:

        在某OSD标记为” down“时, 所有映射到此OSD的PG即转入“降级( degraded)” 状态此OSD重新启动并完成Peering操作后, PG将重新转回clean一旦OSD标记为down的时间超过5分钟, 它将被标记出集群, 而后Ceph将对降级状态的PG启动恢复操作, 直到所有因此而降级的PG重回clean状态在其内部OSD上某对象不可用或悄然崩溃时, PG也会被标记为降级状态, 直至对象从某个权威副本上正确恢复。

Stale:

        每个OSD都要周期性地向RADOS集群中的监视器报告其作为主OSD所持有的所有PG的最新统计数据, 因任何原因导致某个主OSD无法正常向监视器发送此类报告, 或者由其它OSD报告某个OSD已经down掉, 则所有以此OSD为主OSD的PG将立即被标记为stale状态。

Undersized:

        PG中的副本数少于其存储池定义的个数时即转入undersized状态, 恢复和回填操作在随后会启动以修复其副本数为期望值归置组状态。

Scrubbing:

        各OSD还需要周期性地检查其所持有的数据对象的完整性, 以确保所有对等OSD上的数据一致;处于此类检查过程中的PG便会被标记为scrubbing状态, 这也通常被称作light scrubs、 shallow scrubs或者simply scrubs;另外, PG还偶尔需要进行deep scrubs检查以确保同一对象在相关的各OSD上能按位匹配, 此时PG将处于scrubbing+deep状态。

Recovering:

        添加一个新的OSD至存储集群中或某OSD宕掉时, PG则有可能会被CRUSH重新映射进而将持有与此不同的OSD集, 而这些处于内部数据同步过程中的PG则被标记为recovering状态。

Backfilling:

        新OSD加入存储集群后, Ceph则会进入数据重新均衡的状态,即一些数据对象会在进程后台从现有OSD移到新的OSD之上, 此操作过程即为backfill。


CRUSH


        把对象直接映射到OSD之上会导致二者之间的紧密耦合关系,在OSD设备变动时不可避免地对整个集群产生扰动。于是,Ceph将一个对象映射进RADOS集群的过程分为两步:

        1、首先是以一致性哈希算法将对象名称映射到PG。

        2、而后是将PG ID基于CRUSH算法映射到OSD。

        此两个过程都以“实时计算”的方式完成,而非传统的查表方式,从而有效规避了任何组件被“中心化”的可能性,使得集群规模扩展不再受限。

        这个实时计算操作用到的算法就是CRUSH:Controlled Replication Under Scalable Hashing,它是一种数据分布式算法,类似于一致性哈希算法,用于为RADOS存储集群控制数据分布。

        存取对象时,客户端从Ceph监视器检索出集群运行图,绑定到指定的存储池,并对存储池上PG内的对象执行IO操作。

        存储池的CRUSH规则集和PG的数量是决定Ceph如何放置数据的关键性因素。

        基于最新版本的集群运行图,客户端能够了解到集群中的所有监视器和OSD以及它们各自的当前状态。

        不过,客户端对目标对象的位置却一无所知。

        执行对象的存取操作时,客户端需要输入的是对象标识和存储池名称,客户端需要在存储池中存储命名对象时,它将对象名称、对象名称的哈希码、存储池中的PG数量和存储池名称作为输入,而后由CRUSH计算出PG的ID及此PG的主OSD。


        存取对象时,客户端从Ceph监视器检索出集群运行图,绑定到指定的存储池,并对存储池上PG内的对象执行IO操作。

        存储池的CRUSH规则集和PG的数量是决定Ceph如何放置数据的关键性因素。

        基于最新版本的集群运行图,客户端能够了解到集群中的所有监视器和OSD以及它们各自的当前状态。

        不过,客户端对目标对象的位置却一无所知。

执行对象的存取操作时,客户端需要输入的是对象标识和存储池名称。

        通过将对象标识进行一致性哈希运算得到的哈希值与PG位图掩码进行”与“运算得到目标PG,从而得出目标PG的ID(pg_id),完成由Object至PG的映射。

        而后,CRUSH算法便将以此pg_id、CRUSH运行图和归置规则(PlacementRules)为输入参数再次进行计算,并输出一个确定且有序的目标存储向量列表(OSD列表),从而完成从PG至OSD的映射。

Ceph客户端使用以下步骤来计算PG ID:

        客户端输入存储池名称及对象名称,例如,pool=pool1以及object-id=obj1

        获取对象名称并通过一致性哈希算法对其进行哈希运算,即hash(o),其中o为对象名称。

        将计算出的对象标识哈希码与PG位图掩码进行“与”运算获得目标PG的标识符,即PG ID,例如1701

        计算公式为pgid=func(hash(o)&m,r),其中,变量o是对象标识符,变量m是当前存储池中PG的位图掩码,变量r是指复制因子,用于确定目标PG中OSD数量。

        CRUSH根据集群运行图计算出与目标PG对应的有序的OSD集合,并确定出其主OSD。

        客户端获取到存储池名称对应的数字标识,例如,存储池“pool1”的数字标识11。

        客户端将存储池的ID添加到PGID,例如,11.1701

        客户端通过直接与PG映射到的主OSD通信来执行诸如写入、读取或删除之类的对象操作。


存储池操作


创建存储池:

副本型存储池创建命令:

ceph osd pool create <pool-name> <pg-num> [pgp-num] [replicated] [crush-rule-name] [expected-num-objects]

纠删码池创建命令:

ceph osd pool create <pool-name> <pg-num> <pgp-num> erasure [erasure-code-profile] [crush-rule-name] [expected-num-objects]

命令格式中常用的参数:

        pool-name:存储池名称,在一个RADOS存储集群上必须具有唯一性。

        pg-num:当前存储池中的PG数量,合理的PG数量对于存储池的数据分布及性能表现来说至关重要。

        pgp-num:用于归置的PG数量,其值应该等于PG的数量。

        replicated|erasure:存储池类型副本存储池需更多原始存储空间,但已实现Ceph支持的所有操作,而纠删码存储池所需原始存储空间较少,但目前仅实现了Ceph的部分操作。

        crush-ruleset-name:此存储池所用的CRUSH规则集的名称,不过,引用的规则集必须事先存在。

创建pool:

ceph osd pool create mypool 32 32 # 两个32分别是PG和PGS

获取存储池的相关信息:

列出存储池:

ceph osd pool ls detail
ceph osd pool ls [detail]

获取存储池的统计数据:

ceph osd pool stats [pool-name]

显示存储池的用量信息:

rados df

重命名存储池:

ceph osd pool rename old-name new-name

删除存储池:

        意外删除存储池会导致数据丢失,因此Ceph实施了两个机制来防止删除存储池,要删除存储池,必须先禁用这两个机制。

一、第一个机制是NODELETE标志,其值需要为false,默认也是false

查看命令:

ceph osd pool get pool-name nodelete

修改命令:

ceph osd pool set pool-name nodelete false

二、第二个机制是集群范围的配置参数 mon allow pool delete,其默认值为“false”,这表示默认不能删除存储池,临时设定的方法如下:

ceph tell mon.* injectargs --mon-allow-pool-delete={true|false}

建议删除之前将其值设置为true,删除完成后再改为false

删除命令:

]$ ceph osd pool rm mypool mypool --yes-i-really-really-mean-it
pool 'mypool' removed


设置存储池配额


        Ceph支持为存储池设置可存储对象的最大数量( max_objects) 和可占用的最大空间(max_bytes)两个纬度的配额。

ceph osd pool set-quota <pool-name> max_objects|max_bytes <val>

例:

]$ ceph osd pool set-quota rbdpool max_objects 10000
set-quota max_objects = 10000 for pool rbdpool

获取存储池配额的相关信息:

ceph osd pool get-quota <pool-name>

例:

]$ ceph osd pool get-quota rbdpool
quotas for pool 'rbdpool':
  max objects: N/A
  max bytes  : N/A

配置存储池参数:

存储池的诸多配置属性保存于配置参数中

获取配置:

ceph osd pool get <pool-name>

设定配置:

ceph osd pool set <pool-name> <key> <value>


常用的可配置参数:

        size:存储池中的对象副本数;

        min_size:I/O所需要的最小副本数;

        pg_num:存储池的PG数量;

        pgp_num:计算数据归置时要使用的PG的有效数量;

        crush_ruleset:用于在集群中映射对象归置的规则组;

        nodelete:控制是否可删除存储池;

        nopgchange:控制是否可更改存储池的pg_num和pgp_num;

        nosizechange:控制是否可更改存储池的大小;

        noscrub和nodeep-scrub:控制是否可整理或深层整理存储池以解决临时高I/O负载的问题。

        scrub_min_interval:集群负载较低时整理存储池的最小时间间隔; 默认值为0, 表示其取值来自于配置文件中的osd_scrub_min_interval参数;

        scrub_max_interval:整理存储池的最大时间间隔; 默认值为0, 表示其取值来自于配置文件中的osd_scrub_max_interval参数;

        deep_scrub_interval:深层整理存储池的间隔; 默认值为0, 表示其取值来自于配置文件中的osd_deep_scrub参数;


存储池快照


关于存储池快照:

        存储池快照是指整个存储池的状态快照,通过存储池快照,可以保留存储池状态的历史,创建存储池快照可能需要大量存储空间,具体取决于存储池的大小。

创建存储池快照

ceph osd pool mksnap <pool-name> <snap-name>

rados -p <pool-name> mksnap <snap-name>

列出存储池的快照:

rados -p <pool-name> lssnap

回滚存储池至指定的快照:

rados -p <pool-name> rollback <snap-name>

删除存储池快照:

ceph osd pool rmsnap <pool-name> <snap-name>

rados -p <pool-name> rmsnap <snap-name>


数据压缩


BlueStore存储引擎提供即时数据压缩,以节省磁盘空间。

启用压缩:

ceph osd pool set <pool-name> compression_algorithm snappy

压缩算法有none、zlib、lz4、zstd和snappy等几种,默认为snappy;

        zstd有较好的压缩比,但比较消耗CPU;

        lz4和snappy对CPU占用比例较低;

        不建议使用zlib;

ceph osd pool set <pool-name> compression_mode aggressive

压缩模式:none、aggressive、passive和force,默认值为none;

        none:不压缩

        passive:若提示COMPRESSIBLE,则压缩

        aggressive:除非提示INCOMPRESSIBLE,否则就压缩;

        force:始终压缩数据压缩

其它可用的压缩参数:

compression_required_ratio:指定压缩比,取值格式为双精度浮点型,其值为SIZE_COMPRESSED/SIZE_ORIGINAL,即压缩后的大小与原始内容大小的比值,默认为.875;

compression_max_blob_size:压缩对象的最大体积,无符号整数型数值,默认为0;

compression_min_blob_size:压缩对象的最小体积,无符号整数型数值,默认为0;


全局压缩选项:

可在ceph配置文件中设置压缩属性,它将对所有的存储池生效

可设置的相关参数如下:

        bluestore_compression_algorithm

        bluestore_compression_mode

        bluestore_compression_required_ratio

        bluestore_compression_min_blob_size

        bluestore_compression_max_blob_size

        bluestore_compression_min_blob_size_ssd

        bluestore_compression_max_blob_size_ssd

        bluestore_compression_min_blob_size_hdd

        bluestore_compression_max_blob_size_hdd


纠删码存储池


空间利用率高:K/N,K为数据块量,N为加上编码块量的总块数;

创建纠删码池:

ceph osd pool create <pool-name> <pg-num> <pgp-num> erasure [erasure-code-profile][crush-rule-name][expected-num-objects]

        未指定要使用的纠删编码配置文件时,创建命令会为其自动创建一个,并在创建相关的CRUSH规则集时使用到它。

        默认配置文件自动定义k=2和m=1,这意味着Ceph将通过三个OSD扩展对象数据,并且可以丢失,其中一个OSD而不会丢失数据,因此,在冗余效果上,它相当于一个大小为2的副本池,不过,其存储空间有效利用率为2/3而非1/2。

纠删码配置文件:

列出纠删码配置文件:

ceph osd erasure-code-profile ls

获取指定的配置文件的相关内容

ceph osd erasure-code-profile get default

自定义纠删码配置文件:

ceph osd erasure-code-profile set <name> [<directory=directory>] [<plugin=plugin>] [<crush-device-class>] [<crush-failure-domain>] [<key=value>...] [--force]

-directory:加载纠删码插件的目录路径,默认为/usr/lib/ceph/erasure-code;

-plugin:用于生成及恢复纠删码块的插件名称,默认为jerasure;

-crush-device-class:设备类别,例如hdd或ssd,默认为none,即无视类别;

-crush-failure-domain:故障域,默认为host,支持使用的包括osd、host、rack、row和room等;

---force:强制覆盖现有的同名配置文件;

例如,如果所需的体系结构必须承受两个OSD的丢失,并且存储开销为m/(m+k)

ceph osd erasure-code-profile set myprofile k=4 m=2 crush-failure-domain=osd

纠删码插件:

        Ceph支持以插件方式加载使用的纠删编码插件,存储管理员可根据存储场景的需要优化选择合用的插件。目前,Ceph支持的插件包括如下三个:

        jerasure:最为通用的和灵活的纠删编码插件,它也是纠删码池默认使用的插件;不过,任何一个OSD成员的丢失,都需要余下的所有成员OSD参与恢复过程;另外,使用此类插件时,管理员还可以通过technique选项指定要使用的编码技术:

        reed_sol_van:最灵活的编码技术,管理员仅需提供k和m参数即可;

        cauchy_good:更快的编码技术,但需要小心设置PACKETSIZE参数;

        reed_sol_r6_op、liberation、blaum_roth或liber8tion:仅支持使用m=2的编码技术,功能特性类同于RAID6;

        lrc:全称为LocallyRepairableErasureCode,即本地修复纠删码,除了默认的m个编码块之外,它会额外在本地创建指定数量(l)的奇偶校验块,从而在一个OSD丢失时,可以仅通过l个奇偶校验块完成恢复。

        isa:仅支持运行在intelCPU之上的纠删编码插件,它支持reed_sol_van和cauchy两种技术。

例如,下面的命令创建了一个使用lrc插件的配置文件LRCprofile,其本地奇偶校验块为3,故障域为osd

ceph osd erasure-code-profile set LRCprofile plugin=lrc k=4 m=2 l=3 crush-failure-domain=osd