Ceph ERASURE CODE(纠错码)


一个 Ceph 池与一种类型相关联,以维持 OSD 的丢失(即一个磁盘,因为大多数时候每个磁盘都有一个 OSD)。创建池时的默认选择是已复制,这意味着每个对象都复制到多个磁盘上。可以改用纠删码池类型来节省空间。

创建示例纠删码池

最简单的纠删码池相当于RAID5,至少需要三台主机:

$ ceph osd pool create ecpool erasure
pool 'ecpool' created
$ echo ABCDEFGHI | rados --pool ecpool put NYAN -
$ rados --pool ecpool get NYAN -
ABCDEFGHI

纠删码配置文件

默认纠删码配置文件支持丢失两个 OSD。它相当于一个大小为 3 的复制池,但需要 2TB 而不是 3TB 来存储 1TB 数据。默认配置文件可以显示为:

$ ceph osd erasure-code-profile get default
k=2
m=2
plugin=jerasure
crush-failure-domain=host
technique=reed_sol_van

选择正确的配置文件很重要,因为在创建池后无法对其进行修改:需要创建具有不同配置文件的新池,并将前一个池中的所有对象移至新池。

配置文件中最重要的参数是K、M和 crush-failure-domain,因为它们定义了存储开销和数据持久性。例如,如果所需的架构必须承受损失两个机架,存储开销为 67%,则可以定义以下配置文件:

$ ceph osd erasure-code-profile set myprofile \
   k=3 \
   m=2 \
   crush-failure-domain=rack
$ ceph osd pool create ecpool erasure myprofile
$ echo ABCDEFGHI | rados --pool ecpool put NYAN -
$ rados --pool ecpool get NYAN -
ABCDEFGHI

NYAN对象将被分成三部分(K=3 ),并且将创建两个额外的块( M=2)。M的值定义了可以同时丢失多少个 OSD 而不会丢失任何数据。crush-failure-domain=rack将创建一个 CRUSH 规则,确保没有两个块存储在同一个机架中。

更多信息可以在纠删码配置文件文档中找到。

带覆盖的纠删码

默认情况下,纠删码池仅适用于执行完整对象写入和追加的 RGW 之类的用途。

由于 Luminous,纠删码池的部分写入可以通过每个池设置启用。这让 RBD 和 CephFS 将它们的数据存储在纠删码池中:

ceph osd pool set ec_pool allow_ec_overwrites true

这只能在驻留在 bluestore OSD 上的池上启用,因为 bluestore 的校验和用于在深度清理期间检测 bitrot 或其他损坏。除了不安全之外,与 bluestore 相比,使用具有 ec 覆盖的文件存储会产生较低的性能。

纠删码池不支持 omap,因此要将它们与 RBD 和 CephFS 一起使用,您必须指示它们将数据存储在 ec 池中,并将其元数据存储在复制池中。对于 RBD,这意味着--data-pool在镜像创建期间使用纠删码池:

rbd create --size 1G --data-pool ec_pool replicated_pool/image_name

对于 CephFS,可以在文件系统创建期间或通过文件布局将纠删码池设置为默认数据池。

纠删码池和缓存分层

纠删码池比复制池需要更多资源,并且缺少一些功能,例如 omap。 为了克服这些限制,可以在纠删码池之前设置一个缓存层。

例如,如果池热存储由快速存储组成:

$ ceph osd tier add ecpool hot-storage
$ ceph osd tier cache-mode hot-storage writeback
$ ceph osd tier set-overlay ecpool hot-storage

将热存储池作为ecpool的层以回写模式放置,以便对ecpool的每次写入和读取实际上都在使用热存储,并从其灵活性和速度中受益。

更多信息可以在缓存分层文档中找到。

纠删码池恢复

如果纠删码池丢失了一些分片,它必须从其他分片中恢复它们。这通常涉及从剩余的分片中读取数据、重构数据并将其写入新的对等方。在 Octopus 中,只要有至少K个可用分片,纠删码池就可以恢复。(如果分片少于K,您实际上已经丢失了数据!)

在 Octopus 之前,纠删码池至少需要min_size分片可用,即使min_size大于K也是如此。(我们通常建议 min_size 为K+2或更大,以防止写入和数据丢失。)这个保守的决定是在设计新的池模式时非常谨慎而做出的,但也意味着无法使用 OSD 丢失但没有数据丢失的池无需人工干预即可恢复并激活以更改min_size。

词汇表

  • chunk

当调用编码函数时,它返回相同大小的块。可以连接以重建原始对象的数据块和可用于重建丢失的块的编码块。

  • K

数据块的数量,即原始对象被划分的块的数量。例如,如果K=2,一个 10KB 的对象将被分成K个每个 5KB 的对象。

  • M

编码块的数量,即由编码函数计算的附加块的数量。如果有 2 个编码块,则意味着 2 个 OSD 可以 out 而不会丢失数据。