通过jerasure plugin,当erasure coded的object存储在多个OSD中时,恢复丢失的1个OSD数据需要从所有其他OSD读取数据并修复。例如,如果jerasure配置为k = 8和m = 4,则丢失1个OSD需要从其他11个OSD读取并修复。
lrc erasure code plugin创建本地奇偶校验chunks,以便能够使用较少的OSD恢复。例如,如果lrc配置为k = 8,m = 4和l = 4,则会为每4个OSD创建一个附加奇偶校验chunk。当1个OSD丢失时,只需要使用4个OSD而不是11个来恢复。
ERASURE CODE PROFILE EXAMPLES
REDUCE RECOVERY BANDWIDTH BETWEEN HOSTS
当所有主机连接到相同的交换机时,实际上可以观察到减少的带宽。
1 | $ ceph osd erasure-code-profile set LRCprofile \ |
REDUCE RECOVERY BANDWIDTH BETWEEN RACKS
在Firefly中,只有当primary OSD与丢失chunk在同一个rack中时,才会观察到减少的带宽。
1 | $ ceph osd erasure-code-profile set LRCprofile \ |
CREATE AN LRC PROFILE
创建新的lrc erasure code profile:
1 | ceph osd erasure-code-profile set {name} \ |
其中:
k={data chunks}
1 | Description: 每个object都分为多个data-chunks parts,每个part存储在不同的OSD上。 |
m={coding-chunks}
1 | Description: 计算每个object的coding chunks并将它们存储在不同的OSD上。coding chunks的数量也是在不丢失数据的情况下,允许损失OSD的数量。 |
l={locality}
1 | Description: 将coding和data chunks分组为指定size locality的sets。例如,对于k = 4和m = 2,当locality = 3时,创建2个groups,每个group中3个。每个set都可以在不读取另一set中chunks的情况下恢复。 |
crush-root={root}
1 | Description: crush bucket名字用于CRUSH rule的first step。"take"为step的默认值。 |
crush-locality={bucket-type}
1 | Description: crush bucket的type,其中由l定义的每个chunks集合将被存储。例如,如果它被设置为rack,则每个l chunks将被放置在不同的rack中。它用于创建CRUSH rule step,如step选择rack。如果没有设置,则不会进行这样的分组。 |
crush-failure-domain={bucket-type}
1 | Description: 确保不要有两个chunks位于相同故障域的bucket中。例如,如果故障域是host,则不会在同一主机上存储两个chunks。它用于创建CRUSH rule step,比如step chooseleaf host。 |
crush-device-class={device-class}
1 | Description: 使用CRUSH map中的crush device class名称,限定存储到特定class devices(例如SSD或HDD)。 |
directory={directory}
1 | Description: 设置加载erasure code plugin的目录名。 |
–force
1 | Description: 用相同的名称覆盖已有的profile。 |
LOW LEVEL PLUGIN CONFIGURATION
k和m的和必须是l parameter的倍数。low level configuration parameters不会施加这样的限制,并且为了特定目的而使用它可能更加方便。例如可以定义两个groups,一个group有4个chunks,另一个group有3个chunks。还可以递归地定义locality sets,例如datacenters和racks到datacenters。通过生成low level configuration来实现k/m/l。
lrc erasure code plugin递归地应用erasure code技术,以便在大多数情况下从某些chunks的丢失中仅恢复需要的可用chunks的子集。例如,three coding steps被描述为:
1 | chunk nr 01234567 |
其中c是从data chunks D计算出的coding chunks,丢失的chunk 7,可以用后4个chunks恢复。丢失的chunk 2的chunk可以用前4个chunks恢复。
ERASURE CODE PROFILE EXAMPLES USING LOW LEVEL CONFIGURATION
MINIMAL TESTING
它严格等同于使用默认的erasure code profile。DD意味着K = 2,c意味着M = 1,并且使用默认的jerasure plugin。
1 | $ ceph osd erasure-code-profile set LRCprofile \ |
REDUCE RECOVERY BANDWIDTH BETWEEN HOSTS
当所有主机连接到同一个交换机时,可以观察到减少的带宽使用情况。它相当于k = 4,m = 2和l = 3,尽管chunks的layout不同:
1 | $ ceph osd erasure-code-profile set LRCprofile \ |
REDUCE RECOVERY BANDWIDTH BETWEEN RACKS
在Firefly中,只有当primary OSD与丢失chunk在同一个rack中时,才会观察到减少的带宽。
1 | $ ceph osd erasure-code-profile set LRCprofile \ |
TESTING WITH DIFFERENT ERASURE CODE BACKENDS
LRC现在使用jerasure作为默认的EC backend。可以使用low level configuration在每个layer基础上指定EC backend/algorithm。layers=’[ [ “DDc”, “” ] ]’ 的第二个参数实际上是用于此level的erasure code profile。下面的例子指定了在lrcpool中使用cauchy technique的ISA backend。
1 | $ ceph osd erasure-code-profile set LRCprofile \ |
您还可以为每个layer使用不同的erasure code profile。
1 | $ ceph osd erasure-code-profile set LRCprofile \ |
ERASURE CODING AND DECODING ALGORITHM
在layers中找到的steps描述:
1 | chunk nr 01234567 |
按顺序应用。例如,如果一个4K的object被encoded,它将首先通过step 1并被分成4个1K的chunk(4个大写D)。它们按顺序存储在chunk 2,3,6和7中。由此计算出两个coding chunks(两个小写字母c)。coding chunks分别存储在chunk 1和5中。
step 2以类似的方式重新使用由step 1创建的内容,并在位置0处存储单个coding chunk c。为了便于阅读,最后四个标记有下划线(_)的chunks将被忽略。
step 3在位置4存储单个coding chunk c。由step 1创建的3个chunks被用于计算该coding chunk,即来自step 1的coding chunk在step 3中变为data chunk。
如果chunk 2丢失:
1 | chunk nr 01234567 |
decoding将尝试通过以相反的顺序来执行steps恢复它:step 3然后是step 2,最后是step 1。
step 3对chunk 2(即它是下划线)一无所知并被跳过。
存储在chunk 0中来自step 2的coding chunk允许其恢复chunk 2的内容。没有更多的chunks要恢复,过程停止,不考虑step 1。
恢复chunk 2需要读取chunks 0,1,3,并写回chunk 2。
如果chunk 2,3,6丢失:
1 | chunk nr 01234567 |
step 3可以恢复chunk 6的内容:
1 | chunk nr 01234567 |
step 2无法恢复并被跳过,因为缺少两个chunks(2,3),并且它只能从一个缺失的chunk中恢复。
存储在chunk 1,5中的来自step 1的coding chunk允许它恢复chunk 2,3的内容:
1 | chunk nr 01234567 |
CONTROLLING CRUSH PLACEMENT
默认的CRUSH rule提供位于不同hosts上隔离OSD。 例如:
1 | chunk nr 01234567 |
需要8个OSD,每个chunk需要一个OSD。如果hosts位于两个相邻的racks中,则前4个chunks可以放在第一个rack中,最后4个放在第二个rack中。因此,从丢失的单个OSD中恢复并不需要在两个racks之间使用带宽。
例如:
1 | crush-steps='[ [ "choose", "rack", 2 ], [ "chooseleaf", "host", 4 ] ]' |
将创建一个rule,将选择两个类型rack的crush buckets,为它们每个选择4个OSD,它们中的每一个都位于类型host的不同buckets中。
CRUSH rule也可以手动制作以实现更精细的控制。