下面再看一下如何使用糾刪碼讀取數(shù)據(jù),同樣還是以cat.jpg為例??蛻舳嗽诎l(fā)起讀取cat.jpg請求以后,這個對象所在PG的主OSD會向其他關(guān)聯(lián)的OSD發(fā)起讀取請求,比如主OSD是圖中的OSD1,當(dāng)請求發(fā)送到了OSD2和OSD3,此時剛好OSD2出現(xiàn)故障無法回應(yīng)請求,導(dǎo)致最終只能獲取到OSD1(內(nèi)容為ABCD)和OSD3(WXYZ)的條帶分片,此時OSD1作為主OSD會對OSD1和OSD3的數(shù)據(jù)分片做糾刪碼解碼操作,計算出OSD2上面的分片內(nèi)容(即EFGH),之后重新組合出新的cat.jpg內(nèi)容(ABCDEFGH),最終將該結(jié)果返回給客戶端。整個過程如圖所示。
雖然糾刪碼能夠提供和副本相近的數(shù)據(jù)可靠性,并降低冗余數(shù)據(jù)的開銷,整體上能提高存儲設(shè)備的可用空間。但是,糾刪碼所帶來的額外開銷主要是大量計算和網(wǎng)絡(luò)高負(fù)載,優(yōu)點同時伴隨缺點。特別是在一個硬盤出現(xiàn)故障的情況下,重建數(shù)據(jù)非常耗費CPU資源,而且計算一個數(shù)據(jù)塊時需要讀出大量數(shù)據(jù)并通過網(wǎng)絡(luò)傳輸。相比副本數(shù)據(jù)恢復(fù),糾刪碼數(shù)據(jù)恢復(fù)時給網(wǎng)絡(luò)帶來巨大的負(fù)擔(dān)。因此,使用糾刪碼對硬件的設(shè)備性能是一個較大的考驗,這點需要注意。另外,需要注意的是,使用糾刪碼所建立的存儲資源池?zé)o法新建RBD塊設(shè)備。
Ceph安裝后默認(rèn)有Default Rule,這個Rule默認(rèn)是在Host層級進(jìn)行三副本讀寫。副本技術(shù)帶來的優(yōu)點是高可靠性、優(yōu)異的讀寫性能和快速的副本恢復(fù)。然而,副本技術(shù)帶來的成本壓力是較高的,特別是三副本數(shù)據(jù)情景下,每TB數(shù)據(jù)的成本是硬盤裸容量3倍以上(包括節(jié)點CPU和內(nèi)存均攤開銷)。糾刪碼具備與副本相近的高可用特性,而且降低了冗余數(shù)據(jù)的開銷,同時帶來了大量計算和網(wǎng)絡(luò)高負(fù)載。
二、糾刪碼實踐
糾刪碼是通過創(chuàng)建erasure類型的Ceph池實現(xiàn)的。這些池是基于一個糾刪碼配置文件進(jìn)行創(chuàng)建的,在這個配置文件中定義了糾刪碼的特征值?,F(xiàn)在我們將創(chuàng)建一個糾刪碼配置文件,并根據(jù)這個配置文件創(chuàng)建糾刪碼池。下面的命令將創(chuàng)建一個名為Ecprofile的糾刪碼配置文件,它定義的特征值是:k=3和m=2,兩者分別表示數(shù)據(jù)塊和校驗塊的數(shù)量。所以,每一個存儲在糾刪碼池中的對象都將分為3(即k)個數(shù)據(jù)塊,和2(即m)個額外添加的校驗塊,一共有5個塊(k+m)。最后,這5(即k+m)個塊將分布在不同故障區(qū)域中的OSD上。
1、創(chuàng)建糾刪碼配置文件:
# ceph?osd erasure-code-profile? set Ecprofilecrush-failure-domain=osd k=3 m=2
2、查看配置文件
# ceph osd erasure-code-profile ls
Ecprofile
default
# ceph osd erasure-code-profile get? Ecprofile
crush-device-class=
crush-failure-domain=osd
crush-root=default
jerasure-per-chunk-alignment=false
k=3
m=2
plugin=jerasure
technique=reed_sol_van
w=8
我們順便也看Ceph默認(rèn)的配置文件
# ceph osd erasure-code-profile get default
k=2
m=1
plugin=jerasure
technique=reed_sol_van
3、基于上一步生成的糾刪碼配置文件新建一個erasure類型的Ceph池:
# ceph osd pool create Ecpool 16 16 erasureEcprofile
pool ‘Ecpool’ created
4、檢查新創(chuàng)建的池的狀態(tài),你會發(fā)現(xiàn)池的大小是5(k+m),也就是說,erasure大小是5。因此,數(shù)據(jù)將被寫入五個不同的OSD中:
# ceph osd dump | grep Ecpool
pool 8 ‘Ecpool’ erasure size 5 min_size 4crush_rule 3 object_hash rjenkins pg_num 16 pgp_num 16 last_change 231 flagshashpspool stripe_width 12288
5、現(xiàn)在我們創(chuàng)建個文件放到糾刪碼池中。
# echo test > test
# ceph osd pool ls
Ecpool
# rados put -p Ecpool object1 test
# rados?-p? Ecpool ls
object1
6、檢查EC池中和object1的OSDmap。命令的輸出將清晰地顯示對象的每個塊所在的OSDID。正如步驟1)中說明的那樣,object1被分為3(m)個數(shù)據(jù)塊和2(k)個額外的校驗塊,因此,5個塊分別存儲在Ceph集群完全不同的OSD上。在這個演示中,object1一直存儲在這5個OSD中,它們是osd.5、osd.1、osd.3、osd.2、osd.4。
# ceph osd?map Ecpool object1
osdmap e233 pool ‘Ecpool’ (8) object’object1′ -> pg 8.bac5debc (8.c) -> up ([5,1,3,2,4], p5) acting([5,1,3,2,4], p5)
三、糾刪碼測試
1、我們先來關(guān)閉一個osd
# systemctl stop ceph-osd@3
停止osd.3,檢查EC池和object1的OSDmap。你應(yīng)該注意,這里的osd.3變成NONE了,這意味著osd.3在這個池是不可用的:
# ceph osd?map Ecpool object1
osdmap e235 pool ‘Ecpool’ (8) object’object1′ -> pg 8.bac5debc (8.c) -> up ([5,1,NONE,2,4], p5) acting ([5,1,NONE,2,4],p5)
2、我們再來關(guān)閉一個osd
# systemctl stop ceph-osd@5
停止osd.5,檢查EC池和object1的OSDmap。你應(yīng)該注意,這里的osd.5變成NONE了,這意味著osd.5在這個池是不可用的:
# ceph osd?map Ecpool object1
osdmap e237 pool ‘Ecpool’ (8) object’object1′ -> pg 8.bac5debc (8.c) -> up ([NONE,1,NONE,2,4], p1) acting([NONE,1,NONE,2,4], p1)
3、我們從糾刪碼池中下載文件
## rados get? -p Ecpool object1 /tmp/wyl