自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

網(wǎng)絡(luò)分區(qū)帶給分布式數(shù)據(jù)庫的難題如何解決?

系統(tǒng) 分布式
在OpenStack中,數(shù)據(jù)庫是主要系統(tǒng)“狀態(tài)”的主要來源。數(shù)據(jù)庫給OpenStack提供了狀態(tài)組件并把狀態(tài)的“共享”問題交給了數(shù)據(jù)庫,因此解決OpenStack的擴(kuò)展問題實(shí)際上就是解決使用的數(shù)據(jù)庫本身的擴(kuò)展問題。本文會分析”網(wǎng)絡(luò)分區(qū)“給數(shù)據(jù)庫擴(kuò)展帶來的問題,同時(shí)在OpenStack組件中如何規(guī)避和解決。

在OpenStack中,數(shù)據(jù)庫是主要系統(tǒng)“狀態(tài)”的主要來源。大部分Core Projects都使用傳統(tǒng)關(guān)系型數(shù)據(jù)庫作為系統(tǒng)數(shù)據(jù)和狀態(tài)的存儲,另外如Ceilometer使用了MongoDB,還有其他Incubator Projects使用了Redis作為隊(duì)列或者狀態(tài)存儲。數(shù)據(jù)庫給OpenStack提供了狀態(tài)組件并把狀態(tài)的“共享”問題交給了數(shù)據(jù)庫,因此解決OpenStack的擴(kuò)展問題實(shí)際上就是解決使用的數(shù)據(jù)庫本身的擴(kuò)展問題。比如OpenStack HA Solution最令人頭疼的就是傳統(tǒng)關(guān)系數(shù)據(jù)庫或者其他數(shù)據(jù)存儲的擴(kuò)展問題,數(shù)據(jù)庫擴(kuò)展問題的根源是其本身不支持分布式和良好的擴(kuò)展性,而這個(gè)根源又會衍生出分布式系統(tǒng)最大的噩夢–“網(wǎng)絡(luò)分區(qū)”。

下面會分析”網(wǎng)絡(luò)分區(qū)“給數(shù)據(jù)庫擴(kuò)展帶來的問題,同時(shí)在OpenStack組件中如何規(guī)避和解決。

一致性

現(xiàn)代軟件系統(tǒng)由一系列“組件”通過異步、不可靠的網(wǎng)絡(luò)相互溝通構(gòu)建。理解一個(gè)可信賴的分布式系統(tǒng)需要對網(wǎng)絡(luò)本身的分析,而“狀態(tài)”共享就是一個(gè)最重要的問題。

舉一個(gè)例子,當(dāng)你發(fā)表一篇博文后,你可能想知道在你點(diǎn)擊“發(fā)布”操作之后:

1. 從現(xiàn)在開始會對所有人可見;

2. 從現(xiàn)在開始會對你的連接可見,其他人會延遲;

3. 你也可能暫時(shí)不可見,但是未來會可見;

4. 現(xiàn)在可見或者不可見:發(fā)生錯(cuò)誤

5. …… etc

不同的分布式系統(tǒng)會有對一致性和持久性相互影響的權(quán)衡和決定,比如Dynamo類系統(tǒng)通過NRW來指定一致性,如果N=3, W=2,R=1,你將會得到:

1. 可能不會馬上看到更新

2. 更新數(shù)據(jù)會在一個(gè)節(jié)點(diǎn)失敗后存活

如果你像Zookeeper來寫入,那會得到一個(gè)強(qiáng)一致性保證:寫操作會對所有人可見,比如這個(gè)寫操作在一半以下的節(jié)點(diǎn)失敗后仍然能夠保證。如果你像MySQL寫入,取決于你的事物一致性級別,你的寫操作一致性會對所有人、你可見或者最終一致性。

網(wǎng)絡(luò)分區(qū)

分布式通常假設(shè)網(wǎng)絡(luò)是異步的,意味著網(wǎng)絡(luò)可能會導(dǎo)致任意的重復(fù)、丟失、延遲或者亂序的節(jié)點(diǎn)間消息傳遞。在實(shí)際中,TCP狀態(tài)機(jī)會保證節(jié)點(diǎn)間消息傳遞的不丟失、不重復(fù)、時(shí)序。但是,在Socket級別上,節(jié)點(diǎn)接發(fā)消息會阻塞,超時(shí)等等。

檢測到網(wǎng)絡(luò)失敗是困難,因?yàn)槲覀兾ㄒ荒芨玫狡渌?jié)點(diǎn)狀態(tài)的信息就是通過網(wǎng)絡(luò)來得到,延遲跟網(wǎng)絡(luò)失敗也無從區(qū)分。這里就會產(chǎn)生一個(gè)基本的網(wǎng)絡(luò)分區(qū)問題:高延遲可以考慮作為失敗。當(dāng)分區(qū)產(chǎn)生后,我們沒有渠道去了解到其他節(jié)點(diǎn)到底發(fā)生了什么事: 它們是否還存活?或者已經(jīng)crash?是否有收到消息?是否正在嘗試回應(yīng)。當(dāng)網(wǎng)絡(luò)最終恢復(fù)后,我們需要重新建立連接然后嘗試解決在不一致狀態(tài)時(shí)的不一致。

很多系統(tǒng)在解決分區(qū)時(shí)會進(jìn)入一個(gè)特殊的降級操作模式。CAP理論也告訴我們妖么得到一致性要么高可用性,但是很少有數(shù)據(jù)庫系統(tǒng)能夠達(dá)到CAP理論的極限,多數(shù)只是丟失數(shù)據(jù)。

接下來的內(nèi)容會介紹一些分布式系統(tǒng)是如何在網(wǎng)絡(luò)失敗后進(jìn)行相關(guān)行為。

傳統(tǒng)數(shù)據(jù)庫與2PC

傳統(tǒng)的SQL數(shù)據(jù)庫如MySQL、Postgresql都提供一系列不同的一致性級別,然后通常都只能向一個(gè)primary寫入,我們可以把這些數(shù)據(jù)庫認(rèn)為是CP系統(tǒng)(CAP理論),如果分區(qū)發(fā)生,整個(gè)系統(tǒng)會不可用(因?yàn)锳CID)。

那么傳統(tǒng)數(shù)據(jù)庫是不是真的是強(qiáng)一致性?它們都是使用2PC策略來提交請求:

1. 客戶端commit

2. 服務(wù)器端寫操作然后回應(yīng)

3. 客戶端收到回應(yīng)完成提交

png;base649362479ed5433924

在這三個(gè)步驟中,可能發(fā)生不一致的情況在于2與3之間,當(dāng)服務(wù)器寫操作完成但是回應(yīng)沒有被客戶端收到,無論是超時(shí)或者網(wǎng)絡(luò)故障,客戶端這時(shí)會認(rèn)為這次操作沒有完成,而事實(shí)上數(shù)據(jù)庫已經(jīng)寫入。這時(shí)就會產(chǎn)生不一致的行為。也就是客戶端得到的錯(cuò)誤并不能解釋到底服務(wù)器端有沒有寫入。

2PC不僅在傳統(tǒng)SQL數(shù)據(jù)庫被廣泛使用,也有大量用戶實(shí)現(xiàn)2PC在MongoDB之上來完成多鍵值事務(wù)操作。

那么如何解決這個(gè)問題?首先必須接受這個(gè)問題,因?yàn)榫W(wǎng)絡(luò)失敗地概率比較低,并且正好在服務(wù)器寫操作完成與客戶端得到回應(yīng)之間失敗。這使得受到影響的操作非常稀有,在大部分業(yè)務(wù)中,這個(gè)失敗是可接受到。相對的,如果你必須要強(qiáng)一致性的實(shí)施,那么應(yīng)該在業(yè)務(wù)中付諸行動,比如所有的事務(wù)寫操作都是冪等的,是可重入的。這樣當(dāng)遇到網(wǎng)絡(luò)問題時(shí),retry即可而不管到底寫操作有沒有完成。最后,一些數(shù)據(jù)庫可以得到事務(wù)ID,通過track事務(wù)ID你可以在網(wǎng)絡(luò)故障后重新評估事務(wù)是否完成,通過數(shù)據(jù)庫在網(wǎng)絡(luò)恢復(fù)后檢查其記錄的事物ID然后回滾相應(yīng)事務(wù)。

我們在OpenStack的選擇就很有限,目前各個(gè)項(xiàng)目中并不是所有寫操作都是冪等的,不過幸運(yùn)的是,OpenStack的數(shù)據(jù)在罕見的2PC協(xié)議特例中損失是能接受的。

Redis

Redis通常被視為一個(gè)共享的heap,因?yàn)樗菀桌斫獾囊恢滦阅P?,很多用戶把Redis作為消息隊(duì)列、鎖服務(wù)或者主要數(shù)據(jù)庫。Redis在一個(gè)server上運(yùn)行實(shí)例視為CP系統(tǒng)(CAP理論),因此一致性是它的主要目的。

png;base64f63e2b67b8a23c15

Redis集群通常是主備,primary node負(fù)責(zé)寫入和讀取,而slave node只是用來備份。當(dāng)primary node失敗時(shí),slave node有機(jī)會被提升為primary node。但是因?yàn)閜rimary node和slave node之間是異步傳輸,因此slave node被提升為primary node后會導(dǎo)致0~N秒的數(shù)據(jù)丟失。此時(shí)Redis的一致性已經(jīng)被打破,Redis這個(gè)模式的集群不是一個(gè)CP系統(tǒng)!

Redis有一個(gè)官方組件叫Sentinel(參考Redis Sentinel,它是通過類似Quorum的方式來連接Sentinel instance,然后檢測Redis集群的狀態(tài),對故障的primary節(jié)點(diǎn)試用slave節(jié)點(diǎn)替換。Redis官方號稱這個(gè)是HA solution,通過Redis Sentinel來構(gòu)建一個(gè)CP系統(tǒng)。

png;base64945bcfcf5952aaec

考慮Redis Sentinel在網(wǎng)絡(luò)分區(qū)時(shí)候的情況,這時(shí)Redis集群被網(wǎng)絡(luò)分成兩部分,Redis Sentinel在的大區(qū)域可能會提升Slave node作為primary node。如果這時(shí)候一直client在連接原來的primary node,這時(shí)會出現(xiàn)兩個(gè)primary node(split-brain problem,腦裂問題)!也就是說,Redis Sentinel并沒有阻止client連接Old primary node。在此時(shí),已經(jīng)連接到old primary node的client會寫入old primary node,新的client會寫入到new primary node。此時(shí),CP系統(tǒng)已經(jīng)完全癱瘓。雖然Redis集群一直是保持運(yùn)行的,但是因?yàn)橐蕾囉赒uorum來提升slave節(jié)點(diǎn),因此它也不會是AP系統(tǒng)。

png;base649b4412151ec52f63

如果使用Redis作為Lock service,那么這個(gè)問題會成為致命問題。這會導(dǎo)致分區(qū)后同時(shí)可以有兩個(gè)client獲取同一個(gè)鎖并成功,lock service必須是嚴(yán)格的CP系統(tǒng),像Zookeeper。

如果使用Redis作為queue,那么你需要接受一個(gè)item可能會被分發(fā)零次、一次或者兩次等等,大部分的分布式隊(duì)列都保證最多只分發(fā)一次或者最少分發(fā)一次,CP系統(tǒng)會提確切一次的分發(fā)然后帶來較高的延遲。你需要明確使用Redis作為隊(duì)列服務(wù)的話必須要接受網(wǎng)絡(luò)分區(qū)后隊(duì)列服務(wù)可能導(dǎo)致的不穩(wěn)定。

如果使用Redis作為database,那么可想而知,利用Redis Sentinel建立的database是不能稱為database的。

最后,以目前的Redis來說,使用官方提供的組件它只能成為Cache。構(gòu)建一個(gè)分布式的Redis前往WheatRedis。

MongoDB

MongoDB采用類似于Redis的集群方式,primary node作為單點(diǎn)寫操作服務(wù)然后異步寫入replication nodes。但是MongoDB內(nèi)建了primary選舉和復(fù)制狀態(tài)機(jī),這使得primary node失敗后,整個(gè)MongoDB會進(jìn)行交流然后選擇一個(gè)合適的slave node。然后MongoDB支持指定primary node可以確認(rèn)slave node已經(jīng)把寫操作寫入log或者真正寫入,也就是通過一定的性能損耗來換取更強(qiáng)的一致性當(dāng)primary node失敗后。

那么MongoDB是否可以認(rèn)定為是一個(gè)嚴(yán)格的CP系統(tǒng)?還是與Redis類似的問題,在網(wǎng)絡(luò)分區(qū)后,當(dāng)primary node在小的分區(qū)里,大的分區(qū)里的node會選舉產(chǎn)生一個(gè)新的primary node,而此時(shí)在分區(qū)的時(shí)候,這兩個(gè)node是會同時(shí)存在的(這個(gè)沒有問題),然后當(dāng)分區(qū)恢復(fù)后,小分區(qū)里的old primarynode會把在腦裂期間的操作發(fā)送到new primary node,這時(shí)候可能會產(chǎn)生沖突!

png;base641c859b729c1ee13

那么如何面對這個(gè)問題?接受它,首先這個(gè)沖突的概念像2PC一樣可以在client端解決,同時(shí)MongoDB目前有WriteConnern可以解決這個(gè)問題,但會造成巨大的性能影響。

Dynamo

Dynamo是在傳統(tǒng)的primary-slave模式遇到問題時(shí)候出現(xiàn)的紅寶書,借鑒Dynamo的產(chǎn)品在一段時(shí)間內(nèi)出現(xiàn)的非常多。

之前提到的系統(tǒng)都是面向CP的,起碼是面向CP設(shè)計(jì)的。Amazon設(shè)計(jì)的Dynamo鮮明地面向AP。在Dynamo,它是天然地分區(qū)友好型,每一個(gè)node都是平等的,通過NWR來指定不同地一致性級別和可用性。這里不會詳細(xì)闡述Dynaomo的原理(Dynamo,每一個(gè)試圖了解分布式系統(tǒng)的人都應(yīng)該對Dynamo這篇論文非常熟悉,即使它面臨很多問題,但是論文中出現(xiàn)的對Dynamo設(shè)計(jì)的思考和變遷是寶貴的。

那么當(dāng)分區(qū)發(fā)生時(shí),Dynamo發(fā)生了什么?首先根據(jù)NWR的推薦設(shè)定(W+R>N),小區(qū)是不能得到新的寫操作,新的對象會寫在大區(qū)。然后在分區(qū)恢復(fù)后,小區(qū)的對象會滯后并與新的對象發(fā)生沖突。這里的沖突解決策略非常多,如Cassandra使用的client timestamps,Riak的Vector clock,如果無法解決,沖突可能會硬性覆蓋或者推到業(yè)務(wù)代碼。

然后Dynamo本身沒有任何方法來判斷一個(gè)節(jié)點(diǎn)是否數(shù)據(jù)同步,也無法判斷,只能通過完全的數(shù)據(jù)比較,而這個(gè)過程是代價(jià)昂貴并且不靈活的。因此Dynamo提到說(W+R>N)可以達(dá)到強(qiáng)一致性是不可能的,故障節(jié)點(diǎn)只會是最終一致性。

因此,解決Dynamo的問題像前面一樣,接受它。首先你的數(shù)據(jù)可以設(shè)計(jì)成immutable,然后你的數(shù)據(jù)決定可以在罕見情況下丟棄或者變舊,再或者使用CRDTs來設(shè)計(jì)你的數(shù)據(jù)結(jié)構(gòu)。無論如何,Dynamo始終是一個(gè)good idea并且它推動了分布式設(shè)計(jì)的發(fā)展。

BigTable

上面提到的系統(tǒng)都是面向分布式的,要么AP要么CP。那么Bigtable是AC系統(tǒng),雖然我們介紹的一直是分區(qū)問題,但是我們也需要考慮在中心化設(shè)計(jì)的Bigtable。無論是HBase還是HDFS都是這類設(shè)計(jì),它們回避了分區(qū)問題并且在單IDC下達(dá)到非常好的效果。這里不會詳細(xì)討論中心化設(shè)計(jì),因?yàn)樗揪蜎]有考慮分區(qū)問題。

分布式數(shù)據(jù)庫系統(tǒng)的思考

通過上述的分析可以了解到構(gòu)建一個(gè)分布式數(shù)據(jù)庫集群的困難,無論是同步復(fù)制,異步復(fù)制,Quorum還是其他的,在網(wǎng)絡(luò)分區(qū)面前,任何掙扎都是無力的,網(wǎng)絡(luò)錯(cuò)誤意味著”I don’t know” not “I failed”。

構(gòu)建一個(gè)“正確的”分布式數(shù)據(jù)庫系統(tǒng)通常在幾個(gè)方面達(dá)成意見: 1. 接受罕見的問題 2. 使用開源的軟件,分布式系統(tǒng)會產(chǎn)生極大的“漩渦”在“理論正確的分布式算法”和“實(shí)際使用的系統(tǒng)“。一個(gè)有Bug的系統(tǒng)但是正確的算法比一個(gè)錯(cuò)誤的設(shè)計(jì)更能接受。 3. 利用問題進(jìn)行正確的設(shè)計(jì),如使用[CRDTs](http://pagesperso-systeme.lip6.fr/Marc.Shapiro/papers/RR-6956.pdf) 4. split-brain問題是分區(qū)的原罪,如何解決split-brain之后的遺產(chǎn)才是正確的解決方案

小結(jié)

如何在OpenStack上做到HA是OpenStack官方和其他發(fā)行版公司都在努力的方向,而其中關(guān)鍵就在于數(shù)據(jù)存儲的HA和一致性,在這個(gè)方向上,我們通過對”網(wǎng)絡(luò)分區(qū)“這一關(guān)鍵問題的分析并在不同類型的數(shù)據(jù)庫上進(jìn)行落地思考,可以得到如何在其上規(guī)避、解決和接受它。通過在OpenStack的產(chǎn)品上思考這些問題,我們可以在HA Solution上有更強(qiáng)健的基礎(chǔ)。

參考資料

 

責(zé)任編輯:黃丹 來源: 麥子邁
相關(guān)推薦

2018-05-21 14:31:44

分布式數(shù)據(jù)庫故障

2021-12-20 15:44:28

ShardingSph分布式數(shù)據(jù)庫開源

2023-12-05 07:30:40

KlustronBa數(shù)據(jù)庫

2023-07-31 08:27:55

分布式數(shù)據(jù)庫架構(gòu)

2023-07-28 07:56:45

分布式數(shù)據(jù)庫SQL

2023-11-14 08:24:59

性能Scylla系統(tǒng)架構(gòu)

2022-12-08 08:13:11

分布式數(shù)據(jù)庫CAP

2022-03-10 06:36:59

分布式數(shù)據(jù)庫排序

2020-06-23 09:35:13

分布式數(shù)據(jù)庫網(wǎng)絡(luò)

2023-03-07 09:49:04

分布式數(shù)據(jù)庫

2022-08-01 18:33:45

關(guān)系型數(shù)據(jù)庫大數(shù)據(jù)

2024-09-09 09:19:57

2022-06-09 10:19:10

分布式數(shù)據(jù)庫

2011-05-19 09:18:48

分布式數(shù)據(jù)庫

2015-10-16 18:03:25

Docker分布式CoreOS

2024-03-11 08:57:02

國產(chǎn)數(shù)據(jù)庫證券

2018-05-25 13:12:10

UCloud數(shù)據(jù)庫UDDB

2023-04-26 06:56:31

分布式數(shù)據(jù)庫偽需求

2012-09-29 13:18:23

分布式數(shù)據(jù)庫Google Span

2021-12-14 10:16:00

鴻蒙HarmonyOS應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號