冗余表數(shù)據(jù)一致性

【轉(zhuǎn)自https://www.w3cschool.cn/architectroad/architectroad-redundant-table.html

本文主要討論四個(gè)問題:
(1)為什么會(huì)有冗余表的需求
(2)如何實(shí)現(xiàn)冗余表
(3)正反冗余表誰先執(zhí)行
(4)冗余表如何保證數(shù)據(jù)的一致性

一肠仪、需求緣起


互聯(lián)網(wǎng)很多業(yè)務(wù)場(chǎng)景的數(shù)據(jù)量很大,此時(shí)數(shù)據(jù)庫架構(gòu)要進(jìn)行水平切分,水平切分會(huì)有一個(gè)patition key处嫌,通過patition key的查詢能夠直接定位到庫点寥,但是非patition key上的查詢可能就需要掃描多個(gè)庫了。

例如訂單表,業(yè)務(wù)上對(duì)用戶和商家都有訂單查詢需求:
Order(oid, info_detail)
T(buyer_id, seller_id, oid)

如果用buyer_id來分庫朱沃,seller_id的查詢就需要掃描多庫榄攀。
如果用seller_id來分庫嗜傅,buyer_id的查詢就需要掃描多庫。

這類需求檩赢,為了做到高吞吐量低延時(shí)的查詢吕嘀,往往使用“數(shù)據(jù)冗余”的方式來實(shí)現(xiàn),就是文章標(biāo)題里說的“冗余表”

T1(buyer_id, seller_id, oid)
T2(seller_id, buyer_id, oid)

同一個(gè)數(shù)據(jù)贞瞒,冗余兩份偶房,一份以buyer_id來分庫,滿足買家的查詢需求军浆;
一份以seller_id來分庫棕洋,滿足賣家的查詢需求。

二乒融、冗余表的實(shí)現(xiàn)方案


【方法一:服務(wù)同步寫】

服務(wù)層同步寫冗余數(shù)據(jù)

顧名思義掰盘,由服務(wù)層同步寫冗余數(shù)據(jù),如上圖1-4流程:

(1)業(yè)務(wù)方調(diào)用服務(wù)赞季,新增數(shù)據(jù)
(2)服務(wù)先插入T1數(shù)據(jù)
(3)服務(wù)再插入T2數(shù)據(jù)
(4)服務(wù)返回業(yè)務(wù)方新增數(shù)據(jù)成功

優(yōu)點(diǎn)
(1)不復(fù)雜愧捕,服務(wù)層由單次寫,變兩次寫
(2)數(shù)據(jù)一致性相對(duì)較高(因?yàn)殡p寫成功才返回)

缺點(diǎn)
(1)請(qǐng)求的處理時(shí)間增加(要插入次申钩,時(shí)間加倍)
(2)數(shù)據(jù)仍可能不一致次绘,例如第二步寫入T1完成后服務(wù)重啟,則數(shù)據(jù)不會(huì)寫入T2
(3)涉及分布式事務(wù),比較復(fù)雜

如果系統(tǒng)對(duì)處理時(shí)間比較敏感邮偎,引出常用的第二種方案

【方法二:服務(wù)異步寫】

服務(wù)層異步寫

數(shù)據(jù)的雙寫并不再由服務(wù)來完成管跺,服務(wù)層異步發(fā)出一個(gè)消息,通過消息總線發(fā)送給一個(gè)專門的數(shù)據(jù)復(fù)制服務(wù)來寫入冗余數(shù)據(jù)钢猛,如上圖1-6流程:

(1)業(yè)務(wù)方調(diào)用服務(wù)伙菜,新增數(shù)據(jù)
(2)服務(wù)先插入T1數(shù)據(jù)
(3)服務(wù)向消息總線發(fā)送一個(gè)異步消息(發(fā)出即可,不用等返回命迈,通常很快就能完成)
(4)服務(wù)返回業(yè)務(wù)方新增數(shù)據(jù)成功
(5)消息總線將消息投遞給數(shù)據(jù)同步中心
(6)數(shù)據(jù)同步中心插入T2數(shù)據(jù)

優(yōu)點(diǎn)
(1)請(qǐng)求處理時(shí)間短(只插入1次)

缺點(diǎn)
(1)系統(tǒng)的復(fù)雜性增加了贩绕,多引入了一個(gè)組件(消息總線)和一個(gè)服務(wù)(專用的數(shù)據(jù)復(fù)制服務(wù))
(2)因?yàn)榉祷貥I(yè)務(wù)線數(shù)據(jù)插入成功時(shí),數(shù)據(jù)還不一定插入到T2中壶愤,因此數(shù)據(jù)有一個(gè)不一致時(shí)間窗口(這個(gè)窗口很短淑倾,最終是一致的)
(3)在消息總線丟失消息時(shí),冗余表數(shù)據(jù)會(huì)不一致
如果想解除“數(shù)據(jù)冗余”對(duì)系統(tǒng)的耦合征椒,引出常用的第三種方案

【方法三:線下異步寫】

線下異步寫

數(shù)據(jù)的雙寫不再由服務(wù)層來完成娇哆,而是由線下的一個(gè)服務(wù)或者任務(wù)來完成,如上圖1-6流程:

(1)業(yè)務(wù)方調(diào)用服務(wù)勃救,新增數(shù)據(jù)
(2)服務(wù)先插入T1數(shù)據(jù)
(3)服務(wù)返回業(yè)務(wù)方新增數(shù)據(jù)成功
(4)數(shù)據(jù)會(huì)被寫入到數(shù)據(jù)庫的log中
(5)線下服務(wù)或者任務(wù)讀取數(shù)據(jù)庫的log
(6)線下服務(wù)或者任務(wù)插入T2數(shù)據(jù)

優(yōu)點(diǎn)
(1)數(shù)據(jù)雙寫與業(yè)務(wù)完全解耦
(2)請(qǐng)求處理時(shí)間短(只插入1次)

缺點(diǎn)
(1)返回業(yè)務(wù)線數(shù)據(jù)插入成功時(shí)碍讨,數(shù)據(jù)還不一定插入到T2中,因此數(shù)據(jù)有一個(gè)不一致時(shí)間窗口(這個(gè)窗口很短蒙秒,最終是一致的)
(2)數(shù)據(jù)的一致性依賴于線下服務(wù)或者任務(wù)的可靠性

上述三種方案各有優(yōu)缺點(diǎn)勃黍,但不管哪種方案,都會(huì)面臨“究竟先寫T1還是先寫T2”的問題晕讲?這該怎么辦呢覆获?

筆者在工作過程中主要用的是第三種方法

三、究竟先寫正表還是反表


對(duì)于一個(gè)不能保證事務(wù)性的操作瓢省,一定涉及“哪個(gè)任務(wù)先做弄息,哪個(gè)任務(wù)后做”的問題,解決這個(gè)問題的方向是:

【如果出現(xiàn)不一致】勤婚,誰先做對(duì)業(yè)務(wù)的影響較小摹量,就誰先執(zhí)行。

以上文的訂單生成業(yè)務(wù)為例蛔六,buyer和seller冗余表都需要插入數(shù)據(jù):
T1(buyer_id, seller_id, oid)
T2(seller_id, buyer_id, oid)

用戶下單時(shí)荆永,如果“先插入buyer表T1,再插入seller冗余表T2”国章,當(dāng)?shù)谝徊匠晒咴俊⒌诙绞r(shí),出現(xiàn)的業(yè)務(wù)影響是“買家能看到自己的訂單液兽,賣家看不到推送的訂單”

相反骂删,如果“先插入seller表T2掌动,再插入buyer冗余表T1”,當(dāng)?shù)谝徊匠晒δ怠⒌诙绞r(shí)粗恢,出現(xiàn)的業(yè)務(wù)影響是“賣家能看到推送的訂單,賣家看不到自己的訂單”

由于這個(gè)生成訂單的動(dòng)作是買家發(fā)起的欧瘪,買家如果看不到訂單眷射,會(huì)覺得非常奇怪,并且無法支付以推動(dòng)訂單狀態(tài)的流轉(zhuǎn)佛掖,此時(shí)即使賣家看到有人下單也是沒有意義的妖碉。

因此,在此例中芥被,應(yīng)該先插入buyer表T1欧宜,再插入seller表T2。
however拴魄,記住結(jié)論:【如果出現(xiàn)不一致】冗茸,誰先做對(duì)業(yè)務(wù)的影響較小,就誰先執(zhí)行匹中。

四夏漱、如何保證數(shù)據(jù)的一致性


從二節(jié)和第三節(jié)的討論可以看到,不管哪種方案顶捷,因?yàn)閮刹讲僮鞑荒鼙WC原子性麻蹋,總有出現(xiàn)數(shù)據(jù)不一致的可能,那如何解決呢焊切?

【方法一:線下掃面正反冗余表全部數(shù)據(jù)】

線下掃面正反冗余表全部數(shù)據(jù)

如上圖所示,線下啟動(dòng)一個(gè)離線的掃描工具芳室,不停的比對(duì)正表T1和反表T2专肪,如果發(fā)現(xiàn)數(shù)據(jù)不一致,就進(jìn)行補(bǔ)償修復(fù)堪侯。

優(yōu)點(diǎn)
(1)比較簡(jiǎn)單嚎尤,開發(fā)代價(jià)小
(2)線上服務(wù)無需修改,修復(fù)工具與線上服務(wù)解耦
缺點(diǎn)
(1)掃描效率低伍宦,會(huì)掃描大量的“已經(jīng)能夠保證一致”的數(shù)據(jù)
(2)由于掃描的數(shù)據(jù)量大芽死,掃描一輪的時(shí)間比較長(zhǎng),即數(shù)據(jù)如果不一致次洼,不一致的時(shí)間窗口比較長(zhǎng)

有沒有只掃描“可能存在不一致可能性”的數(shù)據(jù)关贵,而不是每次掃描全部數(shù)據(jù),以提高效率的優(yōu)化方法呢卖毁?

【方法二:線下掃描增量數(shù)據(jù)】

線下掃描增量數(shù)據(jù)

每次只掃描增量的日志數(shù)據(jù)揖曾,就能夠極大提高效率,縮短數(shù)據(jù)不一致的時(shí)間窗口,如上圖1-4流程所示:
(1)寫入正表T1
(2)第一步成功后炭剪,寫入日志log1
(3)寫入反表T2
(4)第二步成功后练链,寫入日志log2

當(dāng)然,我們還是需要一個(gè)離線的掃描工具奴拦,不停的比對(duì)日志log1和日志log2媒鼓,如果發(fā)現(xiàn)數(shù)據(jù)不一致,就進(jìn)行補(bǔ)償修復(fù)

優(yōu)點(diǎn)
(1)雖比方法一復(fù)雜错妖,但仍然是比較簡(jiǎn)單的
(2)數(shù)據(jù)掃描效率高绿鸣,只掃描增量數(shù)據(jù)
缺點(diǎn)
(1)線上服務(wù)略有修改(代價(jià)不高,多寫了2條日志)
(2)雖然比方法一更實(shí)時(shí)站玄,但時(shí)效性還是不高枚驻,不一致窗口取決于掃描的周期

有沒有實(shí)時(shí)檢測(cè)一致性并進(jìn)行修復(fù)的方法呢?

【方法三:實(shí)時(shí)線上“消息對(duì)”檢測(cè)】利用了對(duì)賬的思想

實(shí)時(shí)線上“消息對(duì)”檢測(cè)

這次不是寫日志了株旷,而是向消息總線發(fā)送消息再登,如上圖1-4流程所示:
(1)寫入正表T1
(2)第一步成功后,發(fā)送消息msg1
(3)寫入反表T2
(4)第二步成功后晾剖,發(fā)送消息msg2

這次不是需要一個(gè)周期掃描的離線工具了锉矢,而是一個(gè)實(shí)時(shí)訂閱消息的服務(wù)不停的收消息。

假設(shè)正常情況下齿尽,msg1和msg2的接收時(shí)間應(yīng)該在3s以內(nèi)沽损,如果檢測(cè)服務(wù)在收到msg1后沒有收到msg2,就嘗試檢測(cè)數(shù)據(jù)的一致性循头,不一致時(shí)進(jìn)行補(bǔ)償修復(fù)

優(yōu)點(diǎn)
(1)效率高
(2)實(shí)時(shí)性高

缺點(diǎn)
(1)方案比較復(fù)雜绵估,上線引入了消息總線這個(gè)組件
(2)線下多了一個(gè)訂閱總線的檢測(cè)服務(wù)
(3)消息總線的穩(wěn)定性也要考慮

however,技術(shù)方案本身就是一個(gè)投入產(chǎn)出比的折衷卡骂,可以根據(jù)業(yè)務(wù)對(duì)一致性的需求程度決定使用哪一種方法国裳。我這邊有過好友數(shù)據(jù)正反表的業(yè)務(wù),使用的就是方法二全跨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末缝左,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子浓若,更是在濱河造成了極大的恐慌渺杉,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挪钓,死亡現(xiàn)場(chǎng)離奇詭異是越,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)碌上,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門英妓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挽放,“玉大人,你說我怎么就攤上這事蔓纠〖瑁” “怎么了?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵腿倚,是天一觀的道長(zhǎng)纯出。 經(jīng)常有香客問我,道長(zhǎng)敷燎,這世上最難降的妖魔是什么暂筝? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮硬贯,結(jié)果婚禮上焕襟,老公的妹妹穿的比我還像新娘。我一直安慰自己饭豹,他們只是感情好鸵赖,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拄衰,像睡著了一般它褪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翘悉,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天茫打,我揣著相機(jī)與錄音,去河邊找鬼妖混。 笑死老赤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的制市。 我是一名探鬼主播诗越,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼息堂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起块促,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤荣堰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后竭翠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體振坚,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年斋扰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渡八。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片啃洋。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖屎鳍,靈堂內(nèi)的尸體忽然破棺而出宏娄,到底是詐尸還是另有隱情,我是刑警寧澤逮壁,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布孵坚,位于F島的核電站,受9級(jí)特大地震影響窥淆,放射性物質(zhì)發(fā)生泄漏卖宠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一忧饭、第九天 我趴在偏房一處隱蔽的房頂上張望扛伍。 院中可真熱鬧,春花似錦词裤、人聲如沸刺洒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽作媚。三九已至,卻和暖如春帅刊,著一層夾襖步出監(jiān)牢的瞬間纸泡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來泰國打工赖瞒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留女揭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓栏饮,卻偏偏與公主長(zhǎng)得像吧兔,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子袍嬉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359