注意

本文档适用于 Ceph 的开发版本。

本地可修复纠删码插件

使用 isa 插件时,当一个纠删码对象存储在多个 OSD 上时,从一个 OSD 丢失中恢复需要从另外 k 个 OSD 中读取数据。例如,如果 isa 配置为 k=8m=4,那么从一个 OSD 丢失中恢复需要从八个 OSD 中读取数据。

lrc 纠删码插件创建本地奇偶校验块,以使用更少的幸存 OSD 来实现恢复。例如,如果 lrc 配置为 k=8m=4l=4,它将为每四个 OSD 创建一个额外的奇偶校验块。当单个 OSD 丢失时,它只需要四个 OSD 而不是八个即可恢复。

纠删码配置文件示例

减少主机之间的恢复带宽

尽管当所有主机连接到同一个交换机时,这可能不是一个有趣的用例,但实际上可以观察到带宽使用减少。

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

减少机架之间的恢复带宽

在 Firefly 中,只有当主 OSD 与丢失的块位于同一机架时,才能观察到带宽减少。

ceph osd erasure-code-profile set LRCprofile \
   plugin=lrc \
   k=4 m=2 l=3 \
   crush-locality=rack \
   crush-failure-domain=host
ceph osd pool create lrcpool erasure LRCprofile

创建一个 lrc 配置文件

要创建一个新的 lrc 纠删码配置文件

ceph osd erasure-code-profile set {name} \
    plugin=lrc \
    k={data-chunks} \
    m={coding-chunks} \
    l={locality} \
    [crush-root={root}] \
    [crush-locality={bucket-type}] \
    [crush-failure-domain={bucket-type}] \
    [crush-device-class={device-class}] \
    [directory={directory}] \
    [--force]

其中

k={data chunks}

描述:

每个对象被分成 data-chunks 份,每份存储在一个不同的 OSD 上。

类型:

整数

必需:

是。

示例:

4

m={coding-chunks}

描述:

计算每个对象的 coding chunks 并将它们存储在不同的 OSD 上。编码块的数量也是在不丢失数据的情况下可以停止运行的 OSD 数量。

类型:

整数

必需:

是。

示例:

2

l={locality}

描述:

将编码块和数据块分组,每组大小为 locality。例如,对于 k=4m=2,当 locality=3 时,将创建两组三块。每组都可以在不读取其他组中的块的情况下恢复。

类型:

整数

必需:

是。

示例:

3

crush-root={root}

描述:

用于 CRUSH 规则第一步的 crush 桶的名称。例如 step take default

类型:

String

必需:

否。

默认值:

default

crush-locality={bucket-type}

描述:

l 定义的每组块将存储在其中的 CRUSH bucket 的类型。例如,如果设置为 rack,每组 l 个块将放置在不同的机架中。它用于创建 CRUSH 规则步骤,例如 step choose rack。如果未设置,则不进行此类分组。

类型:

String

必需:

否。

crush-failure-domain={bucket-type}

描述:

确保没有两个块位于具有相同故障域的桶中。例如,如果故障域是 host,则不会有两个块存储在同一主机上。它用于创建 CRUSH 规则步骤,例如 step chooseleaf host

类型:

String

必需:

否。

默认值:

host

crush-device-class={device-class}

描述:

使用 CRUSH 映射中的 crush 设备类名称将放置限制为特定类的设备(例如,ssdhdd)。

类型:

String

必需:

否。

默认值:

directory={directory}

描述:

设置从中加载纠删码插件的 directory 名称。

类型:

String

必需:

否。

默认值:

/usr/lib/ceph/erasure-code

--force

描述:

覆盖具有相同名称的现有配置文件。

类型:

String

必需:

否。

低级插件配置

km 的总和必须是 l 参数的倍数。然而,低级配置参数不强制执行此限制,并且使用它们可能对特定目的有益。例如,可以定义两组,一组有 4 个块,另一组有 3 个块。还可以递归地定义本地性集,例如数据中心内的数据中心和机架。k/m/l 是通过生成低级配置来实现的。

lrc 纠删码插件递归地应用纠删码技术,以便从某些块丢失中恢复只需要可用块的一个子集,在大多数情况下。

例如,当三个编码步骤描述为

chunk nr    01234567
step 1      _cDD_cDD
step 2      cDDD____
step 3      ____cDDD

其中 c 是从数据块 D 计算出的编码块,块 7 的丢失可以通过最后四个块恢复。块 2 的丢失可以通过前四个块恢复。

使用低级配置的纠删码配置文件示例

最小测试

它与使用 K=2 M=1 纠删码配置文件完全等效。DD 表示 K=2c 表示 M=1,并且默认使用 isa 插件。

ceph osd erasure-code-profile set LRCprofile \
   plugin=lrc \
   mapping=DD_ \
   layers='[ [ "DDc", "" ] ]'
ceph osd pool create lrcpool erasure LRCprofile

减少主机之间的恢复带宽

尽管当所有主机连接到同一个交换机时,这可能不是一个有趣的用例,但实际上可以观察到带宽使用减少。它等效于 k=4m=2l=3,尽管块的布局不同。警告:提示是可选的

$ ceph osd erasure-code-profile set LRCprofile \
     plugin=lrc \
     mapping=__DD__DD \
     layers='[
               [ "_cDD_cDD", "" ],
               [ "cDDD____", "" ],
               [ "____cDDD", "" ],
             ]'
$ ceph osd pool create lrcpool erasure LRCprofile

减少机架之间的恢复带宽

在 Firefly 中,只有当主 OSD 与丢失的块位于同一机架时,才能观察到带宽减少。警告:提示是可选的

$ ceph osd erasure-code-profile set LRCprofile \
    plugin=lrc \
    mapping=__DD__DD \
    layers='[
              [ "_cDD_cDD", "" ],
              [ "cDDD____", "" ],
              [ "____cDDD", "" ],
            ]' \
    crush-steps='[
                    [ "choose", "rack", 2 ],
                    [ "chooseleaf", "host", 4 ],
                   ]'

$ ceph osd pool create lrcpool erasure LRCprofile

使用不同纠删码后端进行测试

LRC 现在使用 ISA 作为默认的 EC 后端。可以使用低级配置按层指定 EC 后端/算法。layers='[ [ "DDc", "" ] ]' 中的第二个参数实际上是用于此级别的纠删码配置文件。下面的示例指定在 lrcpool 中使用 Jerasure 后端和 cauchy 技术。

ceph osd erasure-code-profile set LRCprofile \
   plugin=lrc \
   mapping=DD_ \
   layers='[ [ "DDc", "plugin=jerasure technique=cauchy" ] ]'
ceph osd pool create lrcpool erasure LRCprofile

您还可以为每一层使用不同的纠删码配置文件。警告:提示是可选的

$ ceph osd erasure-code-profile set LRCprofile \
     plugin=lrc \
     mapping=__DD__DD \
     layers='[
               [ "_cDD_cDD", "plugin=isa technique=cauchy" ],
               [ "cDDD____", "plugin=isa" ],
               [ "____cDDD", "plugin=jerasure" ],
             ]'
$ ceph osd pool create lrcpool erasure LRCprofile

纠删码编码和解码算法

layers 描述中找到的步骤

chunk nr    01234567

step 1      _cDD_cDD
step 2      cDDD____
step 3      ____cDDD

按顺序应用。例如,如果编码一个 4K 对象,它将首先经过 step 1 并被分成四个 1K 块(四个大写字母 D)。它们依次存储在块 2、3、6 和 7 中。从这些块中计算出两个编码块(两个小写字母 c)。编码块分别存储在块 1 和 5 中。

step 2 以类似的方式重用 step 1 创建的内容,并在位置 0 存储单个编码块 c。最后四个块(为便于阅读用下划线(_)标记)被忽略。

step 3 在位置 4 存储单个编码块 c。使用 step 1 创建的三个块来计算此编码块,即来自 step 1 的编码块在 step 3 中成为数据块。

如果块 2 丢失

chunk nr    01234567

step 1      _c D_cDD
step 2      cD D____
step 3      __ _cDDD

解码将尝试通过按相反顺序遍历步骤来恢复它:step 3 然后 step 2,最后 step 1

step 3 对块 2 一无所知(即它是一个下划线)并被跳过。

来自 step 2 的编码块(存储在块 0 中)允许它恢复块 2 的内容。没有更多要恢复的块,进程停止,不考虑 step 1

恢复块 2 需要读取块 0, 1, 3 并写回块 2

如果块 2, 3, 6 丢失

chunk nr    01234567

step 1      _c  _c D
step 2      cD  __ _
step 3      __  cD D

step 3 可以恢复块 6 的内容

chunk nr    01234567

step 1      _c  _cDD
step 2      cD  ____
step 3      __  cDDD

step 2 恢复失败并被跳过,因为它丢失了两个块(2, 3),而它只能从一个丢失的块中恢复。

来自 step 1 的编码块(存储在块 1, 5 中)允许它恢复块 2, 3 的内容

chunk nr    01234567

step 1      _cDD_cDD
step 2      cDDD____
step 3      ____cDDD

控制 CRUSH 放置

默认 CRUSH 规则提供位于不同主机上的 OSD。例如

chunk nr    01234567

step 1      _cDD_cDD
step 2      cDDD____
step 3      ____cDDD

精确需要 8 个 OSD,每个块一个。如果主机位于两个相邻的机架中,前四个块可以放置在第一个机架中,后四个块可以放置在第二个机架中。这样,从单个 OSD 丢失中恢复不需要使用两个机架之间的带宽。

例如

crush-steps='[ [ "choose", "rack", 2 ], [ "chooseleaf", "host", 4 ] ]'

将创建一个规则,选择两个类型为 rack 的 crush bucket,并为它们中的每一个选择四个 OSD,每个 OSD位于不同类型为 host 的 bucket 中。

CRUSH 规则也可以手动制作以进行更精细的控制。

由 Ceph 基金会为您呈现

Ceph 文档是由非营利性 Ceph 基金会 资助和托管的社区资源。如果您希望支持这项工作和我们的其他努力,请考虑 立即加入