- 积分
- 16843
在线时间 小时
最后登录1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?开始注册
x
一、纠删码原理
8 k7 Q9 c; ]. K+ j+ P1 e9 ]纠删码(Erasure Coding,EC)是一种编码容错技术,最早是在通信行业解决部分数据在传输中的损耗问题。其基本原理就是把传输的信号分段,加入一定的校验再让各段间发生相互关联,即使在传输过程中丢失部分信号,接收端仍然能通过算法将完整的信息计算出来。在数据存储中,纠删码将数据分割成片段,把冗余数据块扩展和编码,并将其存储在不同的位置,比如磁盘、存储节点或者其他地理位置。如果需要严格区分,实际上按照误码控制的不同功能,可分为检错、纠错和纠删3种类型。
0 |1 {1 M( k8 O5 c( [; d8 H# V·检错码仅具备识别错码功能而无纠正错码功能。
# D' a4 J: o4 Q& ~·纠错码不仅具备识别错码功能,同时具备纠正错码功能。( U/ }. c1 H2 b& X- t
·纠删码则不仅具备识别错码和纠正错码的功能,而且当错码超过纠正范围时,还可把无法纠错的信息删除。
1 h* |* O: |+ z4 J1 N: E4 D从纠删码基本的形态看,它是k个数据块+m个校验块的结构,其中k和m值可以按照一定的规则设定,可以用公式:n=k+m来表示。变量k代表原始数据或符号的值。变量m代表故障后添加的提供保护的额外或冗余符号的值。变量n代表纠删码过程后创建的符号的总值。当小于m个存储块(数据块或校验块)损坏的情况下,整体数据块可以通过计算剩余存储块上的数据得到,整体数据不会丢失。
j- z/ y; V. D" G1 k下面以k=2,m=1为例,介绍一下如何以纠删码的形式将一个名称为cat.jpg的对象存放在Ceph中,假定该对象的内容为ABCDEFGH。客户端在将cat.jpg上传到Ceph以后,会在主OSD中调用相应的纠删码算法对数据进行编码计算:将原来的ABCDEFGH拆分成两个分片,对应图11-2中的条带分片1(内容为ABCD)和条带分片2(内容为EFGH),之后再计算出另外一个校验条带分片3(内容为WXYZ)。按照crushmap所指定的规则,将这3个分片随机分布在3个不同的OSD上面,完成对这个对象的存储操作。如图所示。
% J2 O2 c4 G8 Y* k* @/ K下面再看一下如何使用纠删码读取数据,同样还是以cat.jpg为例。客户端在发起读取cat.jpg请求以后,这个对象所在PG的主OSD会向其他关联的OSD发起读取请求,比如主OSD是图中的OSD1,当请求发送到了OSD2和OSD3,此时刚好OSD2出现故障无法回应请求,导致最终只能获取到OSD1(内容为ABCD)和OSD3(WXYZ)的条带分片,此时OSD1作为主OSD会对OSD1和OSD3的数据分片做纠删码解码操作,计算出OSD2上面的分片内容(即EFGH),之后重新组合出新的cat.jpg内容(ABCDEFGH),最终将该结果返回给客户端。整个过程如图所示。) F6 F9 W2 @8 s3 I
虽然纠删码能够提供和副本相近的数据可靠性,并降低冗余数据的开销,整体上能提高存储设备的可用空间。但是,纠删码所带来的额外开销主要是大量计算和网络高负载,优点同时伴随缺点。特别是在一个硬盘出现故障的情况下,重建数据非常耗费CPU资源,而且计算一个数据块时需要读出大量数据并通过网络传输。相比副本数据恢复,纠删码数据恢复时给网络带来巨大的负担。因此,使用纠删码对硬件的设备性能是一个较大的考验,这点需要注意。另外,需要注意的是,使用纠删码所建立的存储资源池无法新建RBD块设备。
$ @5 [9 a9 g% NCeph安装后默认有Default Rule,这个Rule默认是在Host层级进行三副本读写。副本技术带来的优点是高可靠性、优异的读写性能和快速的副本恢复。然而,副本技术带来的成本压力是较高的,特别是三副本数据情景下,每TB数据的成本是硬盘裸容量3倍以上(包括节点CPU和内存均摊开销)。纠删码具备与副本相近的高可用特性,而且降低了冗余数据的开销,同时带来了大量计算和网络高负载。
$ V" s0 p! j3 T5 [# H
- N) O7 ~5 i% \5 P2 v
4 O ]/ C2 ?3 L) x/ v# b二、纠删码实践
. ^& S( |1 H: H& ]; M纠删码是通过创建erasure类型的Ceph池实现的。这些池是基于一个纠删码配置文件进行创建的,在这个配置文件中定义了纠删码的特征值。现在我们将创建一个纠删码配置文件,并根据这个配置文件创建纠删码池。下面的命令将创建一个名为Ecprofile的纠删码配置文件,它定义的特征值是:k=3和m=2,两者分别表示数据块和校验块的数量。所以,每一个存储在纠删码池中的对象都将分为3(即k)个数据块,和2(即m)个额外添加的校验块,一共有5个块(k+m)。最后,这5(即k+m)个块将分布在不同故障区域中的OSD上。& z l' P" g; |$ i6 b
1、创建纠删码配置文件:
S5 ~% c6 h( a& {+ Z8 F* H# ceph osd erasure-code-profile set Ecprofilecrush-failure-domain=osd k=3 m=2( [7 N+ R2 G4 I6 b5 ?
2、查看配置文件
! e2 S- W# J8 T6 T. A# ceph osd erasure-code-profile ls
# m3 u4 S5 P2 U, r1 g/ |/ cEcprofile
2 `) \# h. x! O8 t7 m+ l3 zdefault
i( p# v7 L1 P" F" F. \# ceph osd erasure-code-profile get Ecprofile! _' P! c+ b P/ k3 v
crush-device-class=: F; W/ e8 S6 F9 U2 |9 a2 i* }
crush-failure-domain=osd
0 Q3 K7 [$ C' y8 v, _crush-root=default
# V% @: w( E/ L2 e" k/ gjerasure-per-chunk-alignment=false
2 L- m! l& t$ C; o5 Zk=3$ P) r% F" c7 T9 P
m=2
) o3 U* q2 m$ t. Xplugin=jerasure
, n, ]0 ?) [: F* N! p6 `# Ttechnique=reed_sol_van. E6 T1 @8 ]* @1 Z1 o+ n' ^
w=8
. p/ s5 G2 l2 F8 C0 e7 n我们顺便也看Ceph默认的配置文件
+ {2 ~) A6 C) |# ceph osd erasure-code-profile get default( U6 l9 r& @9 `& ]/ l
k=25 R: B5 p2 q M9 W0 S0 r- {1 v
m=10 N' h- k# [+ u% z0 p# o9 a
plugin=jerasure2 p4 D$ k# e- ]5 [# A6 L% i
technique=reed_sol_van
' t0 [& N. |3 b/ Z" ~$ c3、基于上一步生成的纠删码配置文件新建一个erasure类型的Ceph池:
" V3 I, l7 b2 c5 o2 _! ?9 v# ceph osd pool create testcpool 16 16 erasureEcprofile8 f8 O& z) W6 c* K$ j, c
pool 'testcpool' created
! R: r4 d8 ?" F; F4、检查新创建的池的状态,你会发现池的大小是5(k+m),也就是说,erasure大小是5。因此,数据将被写入五个不同的OSD中:! U8 c. I+ p' [( I( Z% B7 _
# ceph osd dump | grep testcpool
4 ]# Y2 N$ U+ A6 hpool 8 'testcpool' erasure size 5 min_size 4crush_rule 3 object_hash rjenkins pg_num 16 pgp_num 16 last_change 231 flagshashpspool stripe_width 122882 j, [7 Z% ?6 E) n% X
5、现在我们创建个文件放到纠删码池中。
8 p- T( V( J8 V8 q1 f7 A v/ @# R, R# echo test > test
3 U T! [" t; b- l# ceph osd pool ls0 m a# y2 F9 d% \2 F9 Z
testcpool( H1 S% ]: b0 F6 U6 B
# rados put -p testcpool object1 test
+ n0 W, L' u5 n9 ~. T& \# rados -p testcpool ls
! Y' J# b( K! T9 `/ a: v: wobject1
$ ^# t/ ]8 d: ?. Y6、检查testcpool池中和object1的OSDmap。命令的输出将清晰地显示对象的每个块所在的OSDID。正如步骤1)中说明的那样,object1被分为3(m)个数据块和2(k)个额外的校验块,因此,5个块分别存储在Ceph集群完全不同的OSD上。在这个演示中,object1一直存储在这5个OSD中,它们是osd.5、osd.1、osd.3、osd.2、osd.4。
2 _ E& C- u" _7 J8 T' R# ceph osd map testcpool object1
: V. S& Q# Q, W" ? d& Josdmap e233 pool 'testcpool' (8) object'object1' -> pg 8.bac5debc (8.c) -> up ([5,1,3,2,4], p5) acting([5,1,3,2,4], p5)9 P: q! I1 l+ d. z, F
9 g+ |8 F; @% t+ j三、纠删码测试1 a+ t5 m- X- l$ l, `3 ~
1、我们先来关闭一个osd
# p8 w* l4 {7 `1 g- T4 i" {# systemctl stop ceph-osd@3. o) h, g k9 }
停止osd.3,检查testcpool池和object1的OSDmap。你应该注意,这里的osd.3变成NONE了,这意味着osd.3在这个池是不可用的:8 y1 M1 o* U: Q
# ceph osd map testcpool object1$ l! D, C+ W; H
osdmap e235 pool 'testcpool' (8) object'object1' -> pg 8.bac5debc (8.c) -> up ([5,1,NONE,2,4], p5) acting ([5,1,NONE,2,4],p5)7 P% x4 i/ y; z% {5 S; D* f) \
2、我们再来关闭一个osd2 W. k6 K' ]5 j9 s+ L# T5 ~
# systemctl stop ceph-osd@5$ D1 W2 u" P5 c/ k; N
停止osd.5,检查testcpool池和object1的OSDmap。你应该注意,这里的osd.5变成NONE了,这意味着osd.5在这个池是不可用的:3 z. t" E( `% R0 }0 h @
# ceph osd map testcpool object1
- F8 W* x0 `# F# q/ N9 P, n( ^4 Cosdmap e237 pool 'testcpool' (8) object'object1' -> pg 8.bac5debc (8.c) -> up ([NONE,1,NONE,2,4], p1) acting([NONE,1,NONE,2,4], p1)
" @ M6 r1 u6 [! \9 k3、我们从纠删码池中下载文件
0 X, g& c8 q: L## rados get -p testcpool object1 /tmp/devops1 F. ~9 F3 o0 @5 s' n8 {5 B
( V$ C b& E# C0 p5 P. A" U: j
! R4 `* L- G4 I+ ]) i
. p2 P, ]. o/ j* I% @7 W4 Z& O |
|