2.8. Ceph 纠删代码
Ceph 可以加载许多纠删代码算法之一。最早且最常用的是 Reed-Solomon
算法。纠删代码实际上是一个转发错误修正(FEC)代码。FEC 代码会将 K
块的消息转换为较长的消息,称为"代码字"的 N
块,以便 Ceph 可以从 N
块的子集恢复原始消息。
更具体地说,N = K+M
,其中变量 K
是原始数据块的数量。变量 M
代表额外的或者冗余区块,它添加了纠删代码算法,以提供防故障的保护。变量 N
是纠删代码池进程后创建的区块总数。M
的值是 N-K
,这意味着算法计算来自 K
原始数据块的 N-K
冗余块。此方法可确保 Ceph 可以访问所有原始数据。系统可应对任意 N-K
失败。例如,在 10 K
中是 16 N
配置,或者纠删代码 10/16
,纠删代码算法向 10 个基本区块 K
增加了六个额外的区块。例如,在 M = K-N
或 16-10 = 6
配置中,Ceph 会将 16 个块 N
分布到 16 个 OSD 中。即使有 6 个 OSD 无法丢失数据,也可以从 10 个验证的 N
块重新创建原始文件,从而确保非常高的容错能力。
与复制池一样,在纠删代码池中,设置中的 Primary OSD 会接收所有写入操作。在复制池中,Ceph 在集合的次要 OSD 上的 PG 中对 PG 中的各个对象进行深度副本。对于纠删代码,进程略有不同。纠删代码池将每个对象存储为 K+M
块。它被分为 K
数据区块和 M
编码区块。该池配置为具有 K+M
大小,以便 Ceph 将每个块存储到操作集的 OSD 中。Ceph 将块的排名存储为对象的属性。Primary OSD 负责将载荷编码到 K+M
区块,并将它们发送到其他 OSD。Primary OSD 还负责维护 PG 日志的权威版本。
例如,在典型的配置中,系统管理员会创建一个纠删代码池以使用六个 OSD 并保持丢失两个 OSD。也就是说,(K+M = 6
), (M = 2
)。
当 Ceph 将包含 ABCDEFGHIJKL
的对象 NYAN 写入池时,通过简单地将内容划分为四个部分,即 ABC
、DEF
、GHI
和 JKL
。如果内容长度不是 K
的倍数,则该算法会对内容进行 pad 处理。此函数还会创建两个编码块:第五个带有 YXY
,以及第六个带有 QGC
的编码块。Ceph 将 OSD 上的各个块存储在执行集合中,其中将区块存储到具有相同名称 NYAN 但驻留于不同的 OSD 的对象中。除了其名称外,该算法还必须保留创建块作为对象 shard_t
的属性的顺序。例如,Chunk 1 包含 ABC
和 Ceph 存储在 OSD5 上,而块 5 包含 YXY
,Ceph 则存储在 OSD4 上。
在恢复场景中,客户端尝试通过读取块 1 到 6 的块从纠删代码池中读取对象 NYAN。OSD 告知算法缺少块 2 和 6。这些缺少的块被称为 'erasures'。例如,由于 OSD6 不足而无法读取块 6,因此 OSD6 无法读取块 2,因为 OSD2 是最慢的,并且其块没有考虑。但是,当算法有四个块时,它会读取四个块:块 1,包含 ABC
、块 3 包含 GHI
、块 4 包含 JKL
,以及包含 YXY
的块 5。然后,它会重建对象 ABCDEFGHIJKL
的原始内容,以及包含 QGC
的块 6 的原始内容。
将数据分割为块独立于对象放置。CRUSH 规则集和纠删代码池配置文件决定了 OSD 上的区块放置。例如,在纠删代码配置集中使用 Locally Repairable Code(lrc
)插件会创建额外的块,需要较少的 OSD 从中恢复。例如,在 lrc
配置集配置 K=4 M=2 L=3
中,该算法会创建六个块(K+M
),就像 jerasure
插件一样,但本地的特性值(L=3
)要求算法在本地创建 2 个块。该算法会创建额外的块,例如 (K+M)/L
。如果包含块 0 的 OSD 失败,可以使用块 1、2 和第一个本地块来恢复此块。在这种情况下,算法只需要 3 个块而不是 5 个就能恢复。
使用纠删代码的池禁用 Object Map。
其它资源
- 有关 CRUSH、纠删代码 profile 和插件的更多信息,请参见 Red Hat Ceph Storage 5 的存储策略指南。
- 如需有关 Object Map 的更多信息,请参阅 Ceph 客户端对象映射部分。