關(guān)于分布式系統(tǒng)的數(shù)據(jù)一致性問題(一)
現(xiàn)在先拋出問題,假設(shè)有一個(gè)主數(shù)據(jù)中心在北京M,然后有成都A,上海B兩個(gè)地方數(shù)據(jù)中心,現(xiàn)在的問題是,假設(shè)成都上海各自的數(shù)據(jù)中心有記錄變更,需要先同步到主數(shù)據(jù)中心,主數(shù)據(jù)中心更新完成之后,在把最新的數(shù)據(jù)分發(fā)到上海,成都的地方數(shù)據(jù)中心A,地方數(shù)據(jù)中心更新數(shù)據(jù),保持和主數(shù)據(jù)中心一致性(數(shù)據(jù)庫結(jié)構(gòu)完全一致)。數(shù)據(jù)更新的消息是通過一臺(tái)中心的MQ進(jìn)行轉(zhuǎn)發(fā)。
先把問題簡單化處理,假設(shè)A增加一條記錄Message_A,發(fā)送到M,B增加一條記錄 MESSAGE_B發(fā)送到M,都是通過MQ服務(wù)器進(jìn)行轉(zhuǎn)發(fā),那么M系統(tǒng)接收到條消息,增加兩條數(shù)據(jù),那么M在把增加的消息群發(fā)給A,B,A和B找到自己缺失的數(shù)據(jù),更新數(shù)據(jù)庫。這樣就完成了一個(gè)數(shù)據(jù)的同步。
從正常情況下來看,都沒有問題,邏輯完全合理,但是請考慮以下三個(gè)問題
1 如何保證A->M的消息,M一定接收到了,同樣,如何保證M->A的消息,M一定接收到了
2 如果數(shù)據(jù)需要一致性更新,比如A發(fā)送了三條消息給M,M要么全部保存,要么全部不保存,不能夠只保存其中的幾條記錄。我們假設(shè)更新的數(shù)據(jù)是一條條發(fā)送的。
3 假設(shè)同時(shí)A發(fā)送了多條更新請求,如何保證順序性要求?
這兩個(gè)問題就是分布式環(huán)境下數(shù)據(jù)一致性的問題
對(duì)于第一個(gè)問題,比較好解決,我們先看看一個(gè)tcp/ip協(xié)議鏈接建立的過程
我們的思路可以從這個(gè)上面出發(fā),在簡化一下,就一個(gè)請求,一個(gè)應(yīng)答。
簡單的通信模型是這樣的
A->M : 你收到我的一條消息沒有,消息的ID是12345
M->A: 我收到了你的一條消息數(shù)據(jù),消息數(shù)據(jù)是ID;12345
這樣就一個(gè)請求,一個(gè)應(yīng)答,就完成了一次可靠性的傳輸。如果A一致沒有收到M的應(yīng)答,就不斷的重試。這個(gè)時(shí)候M就必須保證冪等性。不能重復(fù)的處理消息。那么最極端的情況是,怎么也收不到M的應(yīng)答,這個(gè)時(shí)候是系統(tǒng)故障。自己檢查一下吧。
這么設(shè)計(jì)就要求,A在發(fā)送消息的時(shí)候持久化這個(gè)消息的數(shù)據(jù)內(nèi)容,然后不斷的重試,一旦接收到M的應(yīng)答,就刪除這條消息。同樣,M端也是一樣的。不要相信MQ的持久化機(jī)制,不是很靠譜的。
那么M給A發(fā)送消息也采取類似的原理就可以了。
下面在看看第二個(gè)問題,如何保持?jǐn)?shù)據(jù)的一致性更新,這個(gè)還是可以參考TCP/IP的協(xié)議。
首先A發(fā)送一條消息給M:我要發(fā)送一批消息數(shù)據(jù)給你,批次號(hào)是10000,數(shù)據(jù)是5條。
M發(fā)送一條消息給A:ok,我準(zhǔn)備好了,批次號(hào)是10000,發(fā)送方你A
接著A發(fā)送5條消息給M,消息ID分別為1,2,3,4,5 ,批次號(hào)是10000,
緊接著,A發(fā)送一個(gè)信息給M:我已經(jīng)完成5小消息的發(fā)送,你要提交數(shù)據(jù)更新了
接下來可能發(fā)送兩種情況
1 那么M發(fā)送消息給A:ok,我收到了5條消息,開始提交數(shù)據(jù)
2 那么M也可以發(fā)送給A:我收到了5條消息,但是還缺少,請你重新發(fā)送,那么A就繼續(xù)發(fā)送,直到A收到M成功的應(yīng)答。
整個(gè)過程相當(dāng)復(fù)雜。這個(gè)也就是數(shù)據(jù)一旦分布了,帶來最大的問題就是數(shù)據(jù)一致性的問題。這個(gè)成本非常高。
對(duì)于第三個(gè)問題,這個(gè)就比較復(fù)雜了
這個(gè)最核心的問題就是消息的順序性,我們只能在每個(gè)消息發(fā)一個(gè)消息的序列號(hào),但是還是沒有最好解決這個(gè)問題的辦法。因?yàn)橄⒔邮辗讲恢理樞颉R驗(yàn)榧词菇o他了序列號(hào),也沒有辦法告訴他,這個(gè)應(yīng)該何時(shí)處理。最好的辦法是在第二種方式的基礎(chǔ)作為一個(gè)批次來更新。
這個(gè)只是以最簡單的例子來說明一下分布式系統(tǒng)的要保證數(shù)據(jù)一致性是一件代價(jià)很大的事情。當(dāng)然有的博主會(huì)說,這個(gè)何必這么復(fù)雜,直接數(shù)據(jù)庫同步不就可以了。這個(gè)例子當(dāng)然是沒有問題的,萬一這個(gè)幾個(gè)庫的模型都不一樣,我發(fā)送消息要處理的事情不一樣的。怎么辦?
原文鏈接:http://www.cnblogs.com/aigongsi/archive/2012/09/21/2696773.html
【編輯推薦】