- 积分
- 16843
在线时间 小时
最后登录1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?开始注册
x
一、纠删码原理, P' ]" t9 }3 t6 ?4 Y
纠删码(Erasure Coding,EC)是一种编码容错技术,最早是在通信行业解决部分数据在传输中的损耗问题。其基本原理就是把传输的信号分段,加入一定的校验再让各段间发生相互关联,即使在传输过程中丢失部分信号,接收端仍然能通过算法将完整的信息计算出来。在数据存储中,纠删码将数据分割成片段,把冗余数据块扩展和编码,并将其存储在不同的位置,比如磁盘、存储节点或者其他地理位置。如果需要严格区分,实际上按照误码控制的不同功能,可分为检错、纠错和纠删3种类型。9 [+ L& Z/ h3 r {7 l! I
·检错码仅具备识别错码功能而无纠正错码功能。" E5 B8 n/ Y( |" E. d/ }0 A
·纠错码不仅具备识别错码功能,同时具备纠正错码功能。 r6 Y$ n$ M1 b3 u
·纠删码则不仅具备识别错码和纠正错码的功能,而且当错码超过纠正范围时,还可把无法纠错的信息删除。0 x, ~" Q4 x4 E$ P
从纠删码基本的形态看,它是k个数据块+m个校验块的结构,其中k和m值可以按照一定的规则设定,可以用公式:n=k+m来表示。变量k代表原始数据或符号的值。变量m代表故障后添加的提供保护的额外或冗余符号的值。变量n代表纠删码过程后创建的符号的总值。当小于m个存储块(数据块或校验块)损坏的情况下,整体数据块可以通过计算剩余存储块上的数据得到,整体数据不会丢失。
8 r* z9 Y) A0 k( B下面以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上面,完成对这个对象的存储操作。如图所示。& e) q/ r* G0 c2 I3 Q# q
下面再看一下如何使用纠删码读取数据,同样还是以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),最终将该结果返回给客户端。整个过程如图所示。& ^9 I* b$ F7 L% {4 Y7 z9 E4 L
虽然纠删码能够提供和副本相近的数据可靠性,并降低冗余数据的开销,整体上能提高存储设备的可用空间。但是,纠删码所带来的额外开销主要是大量计算和网络高负载,优点同时伴随缺点。特别是在一个硬盘出现故障的情况下,重建数据非常耗费CPU资源,而且计算一个数据块时需要读出大量数据并通过网络传输。相比副本数据恢复,纠删码数据恢复时给网络带来巨大的负担。因此,使用纠删码对硬件的设备性能是一个较大的考验,这点需要注意。另外,需要注意的是,使用纠删码所建立的存储资源池无法新建RBD块设备。' N3 `9 g) h9 n+ d W, O) L
Ceph安装后默认有Default Rule,这个Rule默认是在Host层级进行三副本读写。副本技术带来的优点是高可靠性、优异的读写性能和快速的副本恢复。然而,副本技术带来的成本压力是较高的,特别是三副本数据情景下,每TB数据的成本是硬盘裸容量3倍以上(包括节点CPU和内存均摊开销)。纠删码具备与副本相近的高可用特性,而且降低了冗余数据的开销,同时带来了大量计算和网络高负载。3 Y0 u3 a% Y8 G) `
9 I2 \' M- q- N0 }7 V9 Y; C2 i& n9 S9 l# s( P
二、纠删码实践( I; v# ^% ?0 h9 \7 C
纠删码是通过创建erasure类型的Ceph池实现的。这些池是基于一个纠删码配置文件进行创建的,在这个配置文件中定义了纠删码的特征值。现在我们将创建一个纠删码配置文件,并根据这个配置文件创建纠删码池。下面的命令将创建一个名为Ecprofile的纠删码配置文件,它定义的特征值是:k=3和m=2,两者分别表示数据块和校验块的数量。所以,每一个存储在纠删码池中的对象都将分为3(即k)个数据块,和2(即m)个额外添加的校验块,一共有5个块(k+m)。最后,这5(即k+m)个块将分布在不同故障区域中的OSD上。5 i# `" P# {7 C
1、创建纠删码配置文件:3 g: Y& u( ^# W, e3 n1 f
# ceph osd erasure-code-profile set Ecprofilecrush-failure-domain=osd k=3 m=2' ~- @* L+ ^) ^* s8 C4 E' Y
2、查看配置文件$ `; V \ M' v# b
# ceph osd erasure-code-profile ls
9 K" U1 |: ^5 q; M8 ]! s3 W+ `; r: [Ecprofile
6 t( z4 m, X% Z3 l: U$ |7 rdefault2 ~3 ^% k2 |, z8 p! K- }0 Q: S
# ceph osd erasure-code-profile get Ecprofile. w2 G& R% Y# X$ m \( o: z$ s+ Q8 G
crush-device-class=, ]% M; d. B3 i. s! s% L- w0 R J
crush-failure-domain=osd" \- i( N8 r/ W' V# @
crush-root=default
( X6 A; j0 L$ ?2 H; }8 ^jerasure-per-chunk-alignment=false
9 P5 C2 {2 c( P" I ok=3% i4 k9 L c- r% l' T
m=26 g/ E+ {: ~+ g# q9 J, [3 B+ P0 B
plugin=jerasure
% j. O+ x! M" ]( Ktechnique=reed_sol_van
! `) d' r8 O/ s* b2 Uw=80 }: {: T! Z+ h' E) o- ]7 j
我们顺便也看Ceph默认的配置文件3 b' v9 a" |2 I' K( |
# ceph osd erasure-code-profile get default" x! n1 S6 D* O& T6 z9 e
k=2
0 F, w4 p3 o3 a, f/ G7 M) ^m=1
% {& T8 n+ W1 J) z0 U4 bplugin=jerasure& }: q- l' b6 o5 B6 ~* E$ Y% W- i
technique=reed_sol_van9 v+ e& |0 Q) p' X
3、基于上一步生成的纠删码配置文件新建一个erasure类型的Ceph池:4 S! e; b! A1 I. L! f) \# s
# ceph osd pool create testcpool 16 16 erasureEcprofile% F$ }: T+ M/ D: N: K9 N
pool 'testcpool' created
' o5 L1 V. k9 m: g4、检查新创建的池的状态,你会发现池的大小是5(k+m),也就是说,erasure大小是5。因此,数据将被写入五个不同的OSD中:9 |( Z& {4 d; A# b' D o1 ^1 q
# ceph osd dump | grep testcpool8 x0 y: _- Z% L; Z, B
pool 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 12288
4 U% n) U7 q7 P' }+ `5、现在我们创建个文件放到纠删码池中。9 j; S( r$ u) S+ m: n q | V
# echo test > test
& B [+ n* u) a) K% n# ceph osd pool ls
# E' g- a0 Y' w# t# e3 C& Etestcpool3 ~' K6 I/ I$ D) O
# rados put -p testcpool object1 test( ]: @* p( \) x+ H" W9 P
# rados -p testcpool ls1 }% F9 O6 Z* r( @8 b4 h7 B; K& E% W
object1; T5 g. z3 \4 B' B6 T+ D: z
6、检查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。
! l* k5 H) j# j- Q/ {# ceph osd map testcpool object1- \# \1 }8 t8 U0 S- Q' y% [7 L
osdmap 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)
! X D5 {6 B8 o
- x0 D+ O3 T% j三、纠删码测试
7 N" I" p; ^3 {# l1、我们先来关闭一个osd
" w* X3 f4 x, q* `+ V- J# systemctl stop ceph-osd@3
' g/ s+ \' v* [& w9 N停止osd.3,检查testcpool池和object1的OSDmap。你应该注意,这里的osd.3变成NONE了,这意味着osd.3在这个池是不可用的:
, U) C- r- g; h# l8 F' L4 k& Q5 @# ceph osd map testcpool object1
" V$ s# y0 y& p) vosdmap 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)
$ `/ G7 O9 e+ E2 Z: N2、我们再来关闭一个osd
6 s5 z8 S4 w3 e+ P9 E6 t# systemctl stop ceph-osd@55 a5 U2 [7 Y9 [; f$ c' I6 }
停止osd.5,检查testcpool池和object1的OSDmap。你应该注意,这里的osd.5变成NONE了,这意味着osd.5在这个池是不可用的:7 U' u# l( t( ?; K. _+ y
# ceph osd map testcpool object1+ G D B- r7 c) j/ ^
osdmap 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)/ s. t% {; ^1 |/ E
3、我们从纠删码池中下载文件
0 Z9 s! h: \4 l4 y9 w% D- d2 r## rados get -p testcpool object1 /tmp/devops3 K& i$ o# B& u! _- l# Y
9 m0 z1 e" R' ^ }0 U3 q! W
. b0 P% r4 k( f. X# ^9 W0 g7 u6 n7 _7 K0 [
|
|