在互聯(lián)網(wǎng)中大型項(xiàng)目中,讀寫分離應(yīng)該是我們小伙伴經(jīng)常聽說的,這個(gè)主要解決大流量請(qǐng)求時(shí),提高系統(tǒng)的吞吐量。因?yàn)榻^大部分互聯(lián)網(wǎng)產(chǎn)品都是讀多寫少,大部分都是讀請(qǐng)求,很小部分是寫請(qǐng)求。
上圖:
1.一個(gè)主庫(kù)負(fù)責(zé)寫請(qǐng)求,更新數(shù)據(jù)
2.兩個(gè)從庫(kù)負(fù)責(zé)讀請(qǐng)求,可以提高系統(tǒng)吞吐量
3.主庫(kù)和從庫(kù)之間同步數(shù)據(jù)
上圖中業(yè)務(wù)流程
1.寫請(qǐng)求A進(jìn)行數(shù)據(jù)更新,但寫庫(kù)還沒有來得及把更新的數(shù)據(jù)更新到讀庫(kù)
2.讀請(qǐng)求B進(jìn)行數(shù)據(jù)查詢,請(qǐng)求B是訪問的讀庫(kù),獲取的是舊值
3.因?yàn)閷憥?kù)和讀庫(kù)之間存在同步延遲,導(dǎo)致數(shù)據(jù)在不同庫(kù)中不一致
這個(gè)問題我們?nèi)绾谓鉀Q?
我們一般用的數(shù)據(jù)庫(kù)是mysql和oracle,mysql是我們互聯(lián)網(wǎng)項(xiàng)目都會(huì)用到的,oracle一般大公司用的比較多(很貴啊)。
我們分析一下問題,原因就是在主庫(kù)(寫庫(kù))與從庫(kù)(讀庫(kù))之間數(shù)據(jù)同步延遲導(dǎo)致,mysql中有全同步復(fù)制機(jī)制、半同步復(fù)制、異步復(fù)制三種復(fù)制方案(小伙伴可以自行去了解)。
mysql全同步復(fù)制
全同步復(fù)制,當(dāng)A提交更新請(qǐng)求主庫(kù)事務(wù)之后,不是立即返回,而是等到所有的從庫(kù)節(jié)點(diǎn)必須收到、APPLY并且提交這些事務(wù),主庫(kù)線程才返回請(qǐng)求A結(jié)果,才能做后續(xù)操作。這樣就解決了數(shù)據(jù)同步延遲的問題。
問題:但這個(gè)同步方案嚴(yán)重的問題就是寫請(qǐng)求耗時(shí)會(huì)很長(zhǎng),而且會(huì)隨者從庫(kù)數(shù)量增加,耗時(shí)也會(huì)增加。(不推薦)
oracle共享存儲(chǔ)
上圖采用了oracle RAC方案,DB服務(wù)其實(shí)就代表一個(gè)應(yīng)用服務(wù),所有的數(shù)據(jù)存儲(chǔ)在同一個(gè)地方,所有就不存在數(shù)據(jù)同步這個(gè)問題。當(dāng)然這個(gè)部署方案不是我們嚴(yán)格意義上面的讀寫分離,存儲(chǔ)是獨(dú)立的。
問題:oracle成本很高,對(duì)存儲(chǔ)硬件要求很高。
我們?cè)O(shè)計(jì)任何架構(gòu)方案,都要圍繞著業(yè)務(wù),如果業(yè)務(wù)能夠接受可以不解決;其實(shí)很多互聯(lián)網(wǎng)產(chǎn)品都有短時(shí)間的數(shù)據(jù)不一致問題。如:58同城,美團(tuán),貼吧等。
但有些場(chǎng)景是不允許的。如:
上圖中:
1.用戶寫了一篇文章,點(diǎn)擊保存按鈕
2.系統(tǒng)執(zhí)行保存方法,提示用戶保存成功
3.保存成功后一般系統(tǒng)就會(huì)立即跳轉(zhuǎn)到文章列表,按照時(shí)間倒序,最新的文章排在第一個(gè),這個(gè)業(yè)務(wù)是很正常的,讓用戶可以看到自己的文章列表(我們的頭條號(hào)就是這樣的)
4.這樣就是調(diào)用獲取文章列表的方法getArticleList,但這個(gè)方法是讀請(qǐng)求,走的是從庫(kù)。
5.如果出現(xiàn)主庫(kù)和從庫(kù)同步延遲,就出現(xiàn)了不一致。
這樣用戶就看不到他剛剛提交保存的文章,這個(gè)用戶是接受不了的。那我們?cè)趺唇鉀Q?
這個(gè)方案是從一個(gè)朋友公司用到的,老顧沒有采用過。一些業(yè)務(wù)的操作是有前端頁(yè)面的,不管是網(wǎng)頁(yè)或App等。此方案的思路就是把之前保存的文章緩存到客戶端,在用戶到文章列表時(shí),數(shù)據(jù)的組成就是(客戶端緩存文章 + 后端讀庫(kù)返回的文章數(shù)據(jù))。客戶端要做的就是緩存要設(shè)置一個(gè)時(shí)間(這個(gè)緩存時(shí)間,可以預(yù)估主庫(kù)同步到從庫(kù)的時(shí)間延遲);以及要做文章去重,防止讀庫(kù)已經(jīng)同步完成,客戶端緩存沒有過期。
問題:客戶端邏輯復(fù)雜;客戶端有緩存數(shù)據(jù)大小的限制,不能保存大數(shù)據(jù)。列表分頁(yè)處理復(fù)雜。
上圖流程:
1.A發(fā)起寫請(qǐng)求,更新了主庫(kù),但在緩存中設(shè)置一個(gè)標(biāo)記,代表此數(shù)據(jù)已經(jīng)更新,標(biāo)記格式(業(yè)務(wù)代號(hào):數(shù)據(jù)庫(kù):表:主鍵ID)根據(jù)自己業(yè)務(wù)場(chǎng)景。
2.設(shè)置此標(biāo)記,要加上過期時(shí)間,可以為預(yù)估的主庫(kù)和從庫(kù)同步延遲的時(shí)間.
3.B發(fā)起讀請(qǐng)求的時(shí)候,先判斷此請(qǐng)求的業(yè)務(wù)在緩存中有沒有更新標(biāo)記
4.如果存在標(biāo)記,走主庫(kù);如果沒有走從庫(kù)。
這個(gè)方案就有效了解決了數(shù)據(jù)不一致的問題。
但這個(gè)方案會(huì)有個(gè)嚴(yán)重的問題,也就是每次的讀請(qǐng)求都要到緩存中去判斷是否存在緩存標(biāo)記,如果是單機(jī)部署用的是jvm緩存,對(duì)性能還好;但如果是集群部署緩存肯定用redis,每次讀都要和redis進(jìn)行交互,這樣肯定會(huì)影響系統(tǒng)吞吐量。
那怎么辦?怎么辦?繼續(xù)往下看
上圖流程:
1.用戶A發(fā)起寫請(qǐng)求,更新了主庫(kù),并在客戶端設(shè)置標(biāo)記,過期時(shí)間,如:cookies
2.用戶A再發(fā)起讀請(qǐng)求時(shí),帶上這個(gè)本地標(biāo)記在后端
3.后端在處理請(qǐng)求時(shí),獲取請(qǐng)求傳過來的數(shù)據(jù),看有沒有這個(gè)標(biāo)記(如:cookies)
4.有這個(gè)業(yè)務(wù)標(biāo)記,走主庫(kù);沒有走從庫(kù)。
這個(gè)方案就保證了用戶A的讀請(qǐng)求肯定是數(shù)據(jù)一致的,而且沒有性能問題,因?yàn)闃?biāo)記是本地客戶端傳過去的。
但有寫小伙伴就會(huì)問那其他用戶在本地客戶端是沒有這個(gè)標(biāo)記的,他們走的就是從庫(kù)了。那其他用戶不就看不到這個(gè)數(shù)據(jù)了嗎?說的對(duì),其他用戶是看不到,但看不到的時(shí)間很短,過個(gè)1~10秒就能夠看到。
但這個(gè)方案解決了當(dāng)前用戶的數(shù)據(jù)一致性的問題,如上面舉的例子,寫文章,然后到文章列表,本用戶是能夠看到的。其他用戶暫時(shí)看不到是沒有關(guān)系的。還是那句話,脫離業(yè)務(wù)的方案是耍流氓。(推薦)
總結(jié):大家應(yīng)該按照自己不同的業(yè)務(wù)場(chǎng)景,選擇不同的方案;方案各有千秋,具體看業(yè)務(wù)場(chǎng)景
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。
當(dāng)前標(biāo)題:你知道怎么解決DB讀寫分離,導(dǎo)致數(shù)據(jù)不一致問題嗎?-創(chuàng)新互聯(lián)
轉(zhuǎn)載來源:http://chinadenli.net/article46/ehghg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、網(wǎng)站維護(hù)、做網(wǎng)站、靜態(tài)網(wǎng)站、全網(wǎng)營(yíng)銷推廣、響應(yīng)式網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容