淺談分布式存儲(chǔ)系統(tǒng)中的數(shù)據(jù)一致性要求
前言
分布式存儲(chǔ)是近幾年的熱門(mén)話題之一,它和傳統(tǒng)SAN/NAS存儲(chǔ)的區(qū)別是,分布式存儲(chǔ)使用標(biāo)準(zhǔn)硬件(比如x86服務(wù)器和10GbE網(wǎng)絡(luò)),而傳統(tǒng)SAN/NAS存儲(chǔ)使用的是專(zhuān)有硬件。使用標(biāo)準(zhǔn)硬件的好處是通用,不會(huì)受限于產(chǎn)商,而且成本上也更便宜,還可以做到按需擴(kuò)容。
存儲(chǔ)系統(tǒng)有一大鐵則,即非不可抗力情況下不能發(fā)生數(shù)據(jù)丟失,亦即要求數(shù)據(jù)可靠一致——這往往也被稱之為存儲(chǔ)系統(tǒng)的生命線或底線。分布式存儲(chǔ)因物理結(jié)構(gòu)跟傳統(tǒng)存儲(chǔ)的不同,會(huì)有不一樣的實(shí)現(xiàn)數(shù)據(jù)高可靠的方法。本文就這個(gè)話題做一些初步探討。
在進(jìn)一步之前,我們先來(lái)明確一下概念,本文中所說(shuō)的“分布式存儲(chǔ)”,是指采用標(biāo)準(zhǔn)x86服務(wù)器和網(wǎng)絡(luò)互聯(lián),并在其上運(yùn)行相關(guān)存儲(chǔ)軟件的系統(tǒng)。近幾年云計(jì)算是熱門(mén)之一,“云存儲(chǔ)”也是大家常見(jiàn)的名詞。在國(guó)內(nèi)云計(jì)算平臺(tái)常見(jiàn)的就是OpenStack,而云存儲(chǔ)往往是指結(jié)合OpenStack使用的分布式存儲(chǔ),如Ceph、GlusterFS或Sheepdog等。
除了“云計(jì)算”和“云存儲(chǔ)”之外,ServerSAN也是近幾年熱點(diǎn)之一,它和“云存儲(chǔ)”概念上比較接近,也是通過(guò)一組x86服務(wù)器互聯(lián),并對(duì)外提供傳統(tǒng)SAN-like的存儲(chǔ)接口。國(guó)內(nèi)幾個(gè)涉足ServerSAN的廠商,也是通過(guò)包裝Ceph等分布式存儲(chǔ)系統(tǒng)對(duì)外提供產(chǎn)品或服務(wù)的。
緣起
為了提供數(shù)據(jù)可靠性,分布式存儲(chǔ)系統(tǒng)一般通過(guò)數(shù)據(jù)存儲(chǔ)多個(gè)副本(一般是3個(gè)副本)或者EC(本質(zhì)上也是副本)來(lái)實(shí)現(xiàn)。比如用戶存儲(chǔ)一個(gè)txt文檔,在底層分布式存儲(chǔ)系統(tǒng)中,這份文檔會(huì)被存儲(chǔ)3個(gè)副本,并放置在不同故障域的不同硬盤(pán)上。這樣即使損壞一塊硬盤(pán),數(shù)據(jù)不會(huì)丟失。即使同時(shí)損壞不同故障域的兩塊硬盤(pán),數(shù)據(jù)仍然不會(huì)丟失。不過(guò)在硬盤(pán)損壞后,存儲(chǔ)系統(tǒng)一般會(huì)及時(shí)感知并補(bǔ)全丟失的副本。
多副本帶來(lái)了數(shù)據(jù)的可靠性,同時(shí)也帶來(lái)了一致性方面的問(wèn)題。比如給定數(shù)據(jù)A的三個(gè)副本A1、A2和A3,如何能保證它們的內(nèi)容是一致的。如果內(nèi)容不一致,往往代表出現(xiàn)了問(wèn)題。比如:
- A1內(nèi)容:hello world
- A2內(nèi)容:hello wor
- A3內(nèi)容:hello w
假設(shè)A1是用戶真正寫(xiě)入的數(shù)據(jù),如果A1突然損毀,此時(shí)即使有A2、A3兩個(gè)副本在,數(shù)據(jù)仍然發(fā)生了丟失。
“承諾”和“遵守”
那么如何保證副本間的數(shù)據(jù)一致性?
首先,先確定合法的數(shù)據(jù)。這里的關(guān)鍵詞是“承諾”。比如用戶要寫(xiě)入“hello world”,數(shù)據(jù)通過(guò)網(wǎng)絡(luò)發(fā)給存儲(chǔ)系統(tǒng),在存儲(chǔ)系統(tǒng)沒(méi)有反饋之前,用戶不能確定寫(xiě)入是否成功,更不能假設(shè)寫(xiě)入已經(jīng)成功。只有當(dāng)存儲(chǔ)系統(tǒng)反饋給用戶“你的hello world寫(xiě)入成功”之后 ,數(shù)據(jù)才算寫(xiě)入成功 —— 這里稱之為“承諾”,即底層分布式存儲(chǔ)系統(tǒng)承諾數(shù)據(jù)已經(jīng)寫(xiě)入,且由多副本機(jī)制保護(hù),不會(huì)出現(xiàn)錯(cuò)亂或丟失,用戶能夠讀到自己之前寫(xiě)入的數(shù)據(jù)。
其次,分布式存儲(chǔ)系統(tǒng)要遵守“承諾”。在反饋寫(xiě)入成功之后,即使發(fā)生部分副本硬件損壞,也不能發(fā)生數(shù)據(jù)丟失。如果出現(xiàn)上述例子中A1損壞,則就是數(shù)據(jù)丟失,因?yàn)橛嘞翧2、A3的數(shù)據(jù)都是跟“承諾”不一樣的。
如何做到“遵守”,是分布式存儲(chǔ)系統(tǒng)的核心之一。我們舉例說(shuō)明這個(gè)問(wèn)題,以Ceph為例,數(shù)據(jù)寫(xiě)入請(qǐng)求最終是要發(fā)送給三個(gè)副本,不過(guò)Ceph為這三個(gè)副本建立了一主兩從的主從關(guān)系,數(shù)據(jù)會(huì)單獨(dú)發(fā)送給主副本,再由主副本轉(zhuǎn)達(dá)給另外兩個(gè)從副本。另外數(shù)據(jù)在三個(gè)副本節(jié)點(diǎn)上寫(xiě)入的時(shí)候,都會(huì)先以直寫(xiě)方式寫(xiě)入本地Journal,然后再以非直寫(xiě)的方式寫(xiě)入數(shù)據(jù)盤(pán)。
這里有兩個(gè)疑問(wèn):
1. 為什么采用“一主兩從”這樣的主從模式?
2. 為什么要寫(xiě)Journal?
先討論***個(gè)問(wèn)題“為什么采用主從模式”。首先主副本作為一個(gè)結(jié)果收集點(diǎn)和用戶反饋人。三個(gè)副本寫(xiě)入的結(jié)果如何,需要有人統(tǒng)一匯總、處理并反饋給用戶。如果用戶自己來(lái)收集和處理,則相當(dāng)于副本機(jī)制侵入到了用戶的業(yè)務(wù)邏輯中,明顯不合理。如果另外使用一個(gè)專(zhuān)門(mén)的節(jié)點(diǎn)Cordinator作為中心協(xié)調(diào)人,三個(gè)副本寫(xiě)入的結(jié)果都先反饋給Cordinator,再由Cordinator處理和反饋給用戶,這樣缺點(diǎn)之一是IO路徑上多了Cordinator這一跳,則增加了每次IO的耗時(shí)。缺點(diǎn)之二是增加了物理資源投入。缺點(diǎn)之三是如果Cordinator故障后,三個(gè)副本群龍無(wú)首,且Cordinator的重新選取將面臨各種不便。
如果使用主從模式,三個(gè)副本一主兩從,首先避免了上面提到的缺點(diǎn)之一和缺點(diǎn)之二。對(duì)比上述缺點(diǎn)之三,主從模式下主副本故障之后,重新選主會(huì)更自然輕松。
再討論第二個(gè)問(wèn)題“為什么要寫(xiě)Journal”。Ceph中“臭名昭著”的double write現(xiàn)象,正是因?yàn)閷?xiě)Journal引起的。數(shù)據(jù)副本在寫(xiě)入時(shí),要求先以直寫(xiě)方式寫(xiě)入Journal,然后再以非直寫(xiě)方式寫(xiě)入文件。如此成本高昂,卻仍不得不為之,正體現(xiàn)了Ceph存儲(chǔ)系統(tǒng)對(duì)數(shù)據(jù)可靠這一生命線的尊重。因?yàn)镃eph Journal的主要作用類(lèi)似于數(shù)據(jù)庫(kù)中的WAL(Write Ahead Log),提供數(shù)據(jù)寫(xiě)入的原子性,避免故障時(shí)造成無(wú)法回溯的中間數(shù)據(jù)。
不過(guò),進(jìn)一步思考,會(huì)產(chǎn)生新的疑問(wèn)。Journal能避免故障時(shí)產(chǎn)生中間數(shù)據(jù),即使用Journal之后,數(shù)據(jù)寫(xiě)入要么完全成功,要么完全失敗,不會(huì)部分成功。但我們?nèi)匀徊荒芘卸ü收匣謴?fù)后,副本數(shù)據(jù)分別是處于“完全成功”還是“完全失敗”。Ceph是通過(guò)pglog來(lái)決定的,pglog由主副本生成并在副本間同步的,它包含了本次數(shù)據(jù)寫(xiě)入的版本號(hào),并也會(huì)被持久化到Journal中。因此故障后副本會(huì)比較數(shù)據(jù)中的版本信息和Journal中的版本信息,由此判定是“完全成功”還是“完全失敗”,為集群級(jí)別的故障恢復(fù)流程提供明確的輸入。
綜上所述,“遵守”“承諾”并非易事,從其中可見(jiàn)Journal至關(guān)重要,沒(méi)有Journal的分布式存儲(chǔ)系統(tǒng),其數(shù)據(jù)一致性都將存疑。
結(jié)語(yǔ)
本文嘗試從日常思維的角度,簡(jiǎn)述多副本機(jī)制的必要性和帶來(lái)的數(shù)據(jù)一致性挑戰(zhàn),并舉例Ceph如何應(yīng)對(duì)這個(gè)挑戰(zhàn)。不過(guò)說(shuō)來(lái)容易做來(lái)難,分布式存儲(chǔ)系統(tǒng)中,編程實(shí)踐也尤為重要。