摘要:其中,在業(yè)務(wù)中主動(dòng)調(diào)用所有參與分布式事務(wù)的從服務(wù)的接口,并匯報(bào)給執(zhí)行情況,由根據(jù)階段的結(jié)果完成后續(xù)的執(zhí)行或回滾操作,同時(shí)記錄分布式事務(wù)狀態(tài)傳遞以及各個(gè)從服務(wù)的執(zhí)行階段等信息,便于追蹤。
數(shù)據(jù)庫(kù)與緩存雙寫(xiě)問(wèn)題
計(jì)算機(jī)領(lǐng)域任何一個(gè)問(wèn)題都可以通過(guò)增加一個(gè)抽象“層”來(lái)解決。
業(yè)務(wù)中為了減少熱點(diǎn)數(shù)據(jù)不必要的db查詢,往往會(huì)增加一層緩存來(lái)解決I/O性能??墒荌/O多了一層也就多了一層的更新維護(hù)與容錯(cuò)保障,當(dāng)修改db中某些數(shù)據(jù)時(shí),往往會(huì)面臨緩存更新的問(wèn)題,在這里簡(jiǎn)單介紹 數(shù)據(jù)庫(kù)與緩存雙寫(xiě)問(wèn)題以及在業(yè)務(wù)場(chǎng)景如何使用雙寫(xiě)策略。
緩存更新時(shí)機(jī)緩存在以下情況下需要更新:
不存在緩存,回源至db后添加緩存
緩存超時(shí),重復(fù)上個(gè)步驟
修改db,更新緩存
緩存更新策略
若不存在緩存或者緩存超時(shí):
查詢db
設(shè)置緩存
若緩存存在,且需要更新db,則有多種緩存更新策略:
先更新db,然后更新緩存
先刪除緩存,然后更新db
先更新db,在刪除緩存
本節(jié)主要討論更新db時(shí)如何更新緩存的問(wèn)題,且暫時(shí)不考慮緩存操作失敗的情況(如網(wǎng)絡(luò)原因、redis服務(wù)不可用等)。
如果業(yè)務(wù)場(chǎng)景中不會(huì)出現(xiàn)修改相同數(shù)據(jù)字段競(jìng)爭(zhēng)的問(wèn)題,那么這三種更新策略毫無(wú)疑問(wèn)都可以使用。如果出現(xiàn)緩存競(jìng)爭(zhēng)態(tài)的情況,那么第一種策略是最先排除的:
](https://si.geilicdn.com/viewm...
上圖所示,如果A、B先后修改db,會(huì)出現(xiàn)最終緩存與db不一致的現(xiàn)象,導(dǎo)致隨后至緩存超時(shí)或下次更新的時(shí)間段內(nèi)使用臟數(shù)據(jù)的現(xiàn)象。
而且業(yè)務(wù)方需要考慮的是,是否每次更新db,都需要立即刷新緩存。如果在“寫(xiě)頻繁,而讀頻率遠(yuǎn)小于寫(xiě)的情況下,頻繁的刷新緩存是否有必要?”
第二種策略,先刪除緩存再更新數(shù)據(jù)庫(kù)旨在犧牲性能下盡可能降低使用臟緩存的情況,可是此種情況下仍有可能出現(xiàn)臟緩存的情況:
](https://si.geilicdn.com/viewm...
如上圖,A先刪除緩存,同時(shí)開(kāi)始更新db;與此同時(shí)B查詢緩存為空,進(jìn)而查詢db,由于db的讀性能高于寫(xiě)且數(shù)據(jù)庫(kù)隔離級(jí)別默認(rèn)為提交讀,因此B查詢db的數(shù)據(jù)往往為舊數(shù)據(jù),此后B查詢完畢更新緩存,導(dǎo)致緩存在超時(shí)時(shí)間或者下次修改db的范圍內(nèi)為臟數(shù)據(jù)。
如果db底層做了讀寫(xiě)分離的情況下,這種現(xiàn)象更容易出現(xiàn),B查詢db是讀庫(kù),而A修改主庫(kù)后需要一定時(shí)間的同步才能保障從庫(kù)的數(shù)據(jù)最新,因此在此種情況下,緩存肯定仍是臟數(shù)據(jù)。
為了避免這種情況,A可以在更新db后延時(shí)一定間隔(往往是查詢db時(shí)間+設(shè)置緩存的時(shí)間)刪除緩存,盡量縮短臟緩存的時(shí)段,新的請(qǐng)求回源db并設(shè)置新的緩存數(shù)據(jù)。如下圖所示。
](https://si.geilicdn.com/viewm...
第三種策略先更新數(shù)據(jù)庫(kù)再刪除緩存,此種策略較為安全,幾乎不會(huì)出現(xiàn)臟緩存的情況,就算出現(xiàn)也是會(huì)在極不合理的情況下導(dǎo)致臟緩存:
](https://si.geilicdn.com/viewm...
如上圖,緩存出現(xiàn)臟數(shù)據(jù)的前提是第2步驟耗時(shí)大于第3、4步驟,即讀耗時(shí)大于寫(xiě)耗時(shí),這幾乎不可能發(fā)生。就算發(fā)生,也可以通過(guò)A再次延遲刪除緩存(兩次刪除)解決。
在上一節(jié)中提到的所有緩存更新策略都是在暫時(shí)不考慮緩存操作失敗的情況(如網(wǎng)絡(luò)原因、redis服務(wù)不可用等)前提下討論的,如果緩存操作失敗,則必須通過(guò)業(yè)務(wù)代碼重試、消息隊(duì)列或者設(shè)置緩存超時(shí)解決。
業(yè)務(wù)代碼重試,設(shè)置合理的重試次數(shù)與間隔,如果超時(shí)后緩存仍然無(wú)法操作則需要等待緩存超時(shí)或者人為介入;
消息隊(duì)列則在緩存操作失敗后投遞對(duì)應(yīng)消息,在非業(yè)務(wù)代碼中進(jìn)行重試;
緩存超時(shí)則是兜底方案,這是允許最長(zhǎng)的緩存不一致的時(shí)間。
分布式事務(wù)比較遺憾的是,在node領(lǐng)域還沒(méi)有類似JAVA的JTA規(guī)范及其實(shí)現(xiàn),JTA規(guī)范中的核心“事務(wù)管理器TM”大都由容器來(lái)實(shí)現(xiàn),如常見(jiàn)的jboss和websphere;TM接收業(yè)務(wù)層的事務(wù)請(qǐng)求,同時(shí)協(xié)同參與事務(wù)的各個(gè)資源管理器RM如dbms、mq等,實(shí)現(xiàn)分布式事務(wù)的提交與回滾;同時(shí)也提供分布式事務(wù)在不同自治系統(tǒng)的傳遞。
分布式事務(wù)的集中解決方案有如下幾種:
1. 兩階段提交 2. 三階段提交 3. 異步確保 4. TCC
在JAVA和其他生態(tài)已經(jīng)證明了,兩階段提交的低效以及無(wú)法抗住高并發(fā)且存在單點(diǎn)的問(wèn)題;三階段提交雖然解決了兩階段的單點(diǎn)和減少協(xié)調(diào)者阻塞等待參與者的問(wèn)題,但仍存在數(shù)據(jù)不一致的情況,因此這兩種理論上的模型其實(shí)并不符合實(shí)際業(yè)務(wù)中的場(chǎng)景,在工程領(lǐng)域需要追求的是最優(yōu)化,可見(jiàn)理論與現(xiàn)實(shí)仍然有不少差距。
那么在node場(chǎng)景中,處理分布式事務(wù)的方式也就只剩下兩種工程上的解決方案。
node中使用異步確保模型可以使用相比較簡(jiǎn)單的基于消息隊(duì)列的異步確保模型(也可基于本地?cái)?shù)據(jù)庫(kù)表)。將分布式長(zhǎng)事務(wù)切分為多個(gè)本地事務(wù),通過(guò)保障本地事務(wù)的可靠性實(shí)現(xiàn)分布式長(zhǎng)事務(wù)的最終提交。如果參與分布式事務(wù)的某個(gè)本地事務(wù)執(zhí)行出錯(cuò)進(jìn)行回滾,則通過(guò)消息隊(duì)列實(shí)現(xiàn)業(yè)務(wù)主動(dòng)方的補(bǔ)償,實(shí)現(xiàn)最終的數(shù)據(jù)一致性。
如下圖:
TCC模型相比較異步確保而言則比較重,需要開(kāi)發(fā)一個(gè)TCC的TM協(xié)調(diào)各個(gè)服務(wù)參與方,同時(shí)對(duì)參與事務(wù)的各個(gè)從服務(wù)侵入性比較大,必須提供try、confirm和cancel三個(gè)接口。其中try接口預(yù)留相關(guān)資源,并確保數(shù)據(jù)一致性,confirm接口和cancel接口保證冪等性,執(zhí)行或回滾try階段預(yù)留的資源。其中,在業(yè)務(wù)中主動(dòng)調(diào)用所有參與分布式事務(wù)的從服務(wù)的try接口,并匯報(bào)給TM執(zhí)行情況,由TM根據(jù)try階段的結(jié)果完成后續(xù)的執(zhí)行或回滾操作,同時(shí)記錄分布式事務(wù)狀態(tài)傳遞以及各個(gè)從服務(wù)的執(zhí)行階段等信息,便于追蹤。
因此用node實(shí)現(xiàn)分布式事務(wù)時(shí),在沒(méi)有自研TCC中間件的前提下,可根據(jù)業(yè)務(wù)特性自行擴(kuò)展異步確保型方案。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/100097.html
摘要:來(lái)自作者沈劍更多技術(shù)分享,盡在微信公眾號(hào)技術(shù)雜談前言本文將以好友中心為例,介紹多對(duì)多類業(yè)務(wù),隨著數(shù)據(jù)量的逐步增大,數(shù)據(jù)庫(kù)性能顯著降低,數(shù)據(jù)庫(kù)水平切分相關(guān)的架構(gòu)實(shí)踐。 來(lái)自 GitChat 作者:沈劍更多IT技術(shù)分享,盡在微信公眾號(hào):GitChat技術(shù)雜談 前言 本文將以好友中心為例,介紹多對(duì)多類業(yè)務(wù),隨著數(shù)據(jù)量的逐步增大,數(shù)據(jù)庫(kù)性能顯著降低,數(shù)據(jù)庫(kù)水平切分相關(guān)的架構(gòu)實(shí)踐。 一、什么是多...
摘要:來(lái)自作者沈劍更多技術(shù)分享,盡在微信公眾號(hào)技術(shù)雜談前言本文將以好友中心為例,介紹多對(duì)多類業(yè)務(wù),隨著數(shù)據(jù)量的逐步增大,數(shù)據(jù)庫(kù)性能顯著降低,數(shù)據(jù)庫(kù)水平切分相關(guān)的架構(gòu)實(shí)踐。 來(lái)自 GitChat 作者:沈劍更多IT技術(shù)分享,盡在微信公眾號(hào):GitChat技術(shù)雜談 前言 本文將以好友中心為例,介紹多對(duì)多類業(yè)務(wù),隨著數(shù)據(jù)量的逐步增大,數(shù)據(jù)庫(kù)性能顯著降低,數(shù)據(jù)庫(kù)水平切分相關(guān)的架構(gòu)實(shí)踐。 一、什么是多...
閱讀 1307·2021-10-08 10:04
閱讀 1940·2021-09-04 16:40
閱讀 2550·2019-08-30 13:21
閱讀 2292·2019-08-29 15:10
閱讀 2862·2019-08-29 12:35
閱讀 1201·2019-08-26 17:41
閱讀 3072·2019-08-26 17:03
閱讀 1154·2019-08-26 12:01