Shopify 是如何解決數(shù)據(jù)庫復(fù)制延遲問題的(翻譯)

原文地址 Read Consistency with Database Replicas

數(shù)據(jù)庫副本中的讀一致性

Shopify, 我們一直使用數(shù)據(jù)圖復(fù)制進(jìn)行冗余及回復(fù),但是最近我們開始使用數(shù)據(jù)庫副本作為只讀庫(讀寫分離)∽喾颍可以緩解主庫對時間敏感性的讀寫操作的壓力月匣。

這會有一個不可避免的問題:復(fù)制延遲。簡單來說就是應(yīng)用讀取從庫的數(shù)據(jù)時有可能會讀到幾秒鐘或者幾分鐘之前的老數(shù)據(jù)脓鹃。根據(jù)英勇的需要這可能并不一定是一個問題逸尖。使用從庫的應(yīng)用必須要接收讀取到過期數(shù)據(jù)的可能性。這只是程度上的問題瘸右。當(dāng)這是原子性操作時娇跟,這就會變成一個問題。

有一種情況是太颤,當(dāng)一個查詢的數(shù)據(jù)是需要多個查詢結(jié)果合并而成的苞俘,這時多個查詢會路由到具有不同延遲程度的從庫副本中,這時查詢出來的數(shù)據(jù)是不可預(yù)測的龄章。

Reading from replicas with varying replication lag produces unpredictable results

舉例來說吃谣,一個初始查詢可以查到的數(shù)據(jù)在第二次查詢中可能會查不到,因?yàn)槁酚傻搅艘粋€延遲更大的副本中做裙。很明顯這種情況對用戶體驗(yàn)非常不友好岗憋,如果這種查詢數(shù)據(jù)還會應(yīng)用到未來的寫入操作中,會是個很大的問題锚贱。這篇文章講述了Shopify 的數(shù)據(jù)連接管理團(tuán)隊(duì)是如何解決不同延遲引發(fā)的問題的仔戈。

緊湊一致性(Tight Consistency (類似 Strick consistency))

一種處理不同延遲問題的方法是執(zhí)行緊湊一致性,所有副本保證已經(jīng)與主庫同步才可以允許其他操作拧廊。這種方案代價很高而且使得使用副本的性能優(yōu)勢無效监徘。即使仍然可以降低主庫的負(fù)載,但是等待復(fù)制會影響性能卦绣。

因果一致性(Causal Consistency

還有一種考慮到的方式就是使用GTID(global transaction identifier)的因果一致性方案(已經(jīng)開始實(shí)現(xiàn))耐量。主庫中的每個業(yè)務(wù)都會有一個GTID,這個GTID也會被保存到數(shù)據(jù)副本中滤港。這可以使每個請求根據(jù)GTID路由到各個從庫副本中廊蜒,這樣我們就可以確定從庫相對主庫的延遲程度趴拧,理論上這并不是緊湊一致性,但是實(shí)踐時可以達(dá)到同樣的效果山叮。

這種方式的主要弊端是在各個副本中必須有上報GTID給數(shù)據(jù)庫代理的應(yīng)用功能著榴,這樣數(shù)據(jù)庫代理才可以根據(jù)GTID 來路由到指定從庫副本中。最終我們決定不采用這種方式屁倔,因?yàn)槲覀儾恍枰@個級別的一致性保證及這種復(fù)雜度也是沒必要的脑又。

我們的一致性解決方案(Monotonic read Consistency

其他一致性模型必然涉及某種妥協(xié),而我們選擇了單調(diào)讀一致性(monotonic read consistency)方案锐借,連續(xù)的讀請求即使不需要讀到最新的數(shù)據(jù)问麸,但也會沿著一個固定的時間線。最直接的方式就是一系列相關(guān)的讀請求都路由到相同的副本數(shù)據(jù)庫钞翔,這樣連續(xù)的請求數(shù)據(jù)與上一個請求相比都是距離主庫相同或更晚的數(shù)據(jù)严卖。

Reading repeatedly from a single replica produces a coherent data timeline

為了簡單的實(shí)現(xiàn)及避免沒必要的開銷,通史也希望避免應(yīng)用必須了解數(shù)據(jù)庫拓?fù)洳⑶夜芾砀北静冀巍砜匆幌挛覀兪窃趺醋龅南剩紫任覀兿瓤匆幌抡麄€流程。

首相應(yīng)用接入MySQL數(shù)據(jù)庫是通過ProxySQL的代理層使用的一種hostgroups概念:對于應(yīng)用來說就是一個單一的數(shù)據(jù)源汰扭,內(nèi)部是一個個變換服務(wù)器池稠肘。

A modified illustration from the ProxySQL website shows its place in our architecture

當(dāng)一個客戶端應(yīng)用連接并獲得身份認(rèn)證后,代理會路由這一個單獨(dú)請求到在hostgroup中隨機(jī)的一個服務(wù)器中萝毛。(這一部分簡化了內(nèi)部的負(fù)載均衡等的一些算法项阴,為了更好的討論本文的主題)。為了提供讀一致性珊泳,我們修改了ProxySQL源碼中的這個服務(wù)選擇算法部分鲁冯。

任何應(yīng)用必須提供一個 UID(unique identifier),以鍵值對方式拼接在所有SQL 的最前面

/* consistent_read_id:<some unique ID> */ SELECT <fields> FROM <table>

首先色查,需要對這個UID進(jìn)行HASH算法得到一個integer值薯演。我們通過計算這個integer的模來獲得可用服務(wù)器中的一個。為了讓應(yīng)用在連續(xù)的請求中獲得相同的服務(wù)器秧了,它們必須傳遞相同的UID跨扮。這個解釋簡化了ProxySQL在權(quán)重方面的配置,以下是包含權(quán)重的這個算法的流程验毡。

遇到的一些坑

我已經(jīng)講了這個算法衡创,但是要想達(dá)到完美還需要解決一些問題。

第一個問題是在代碼審查期間出現(xiàn)的晶通,涉及到服務(wù)器在連續(xù)一致的讀請求之間變得不可用的情況璃氢。如果不可用的服務(wù)器是之前選中的服務(wù)器(因此可能會再次選中),則可能出現(xiàn)數(shù)據(jù)不一致——這是我們的方法的內(nèi)置限制狮辽。然而一也,即使不可用的服務(wù)器不是應(yīng)該被選擇的服務(wù)器巢寡,直接對可用服務(wù)器列表應(yīng)用選擇算法(就像ProxySQL對隨機(jī)服務(wù)器選擇所做的那樣)也可能導(dǎo)致不一致,但在這種情況下是不必要的椰苟。為了解決這個問題抑月,我們首先對主機(jī)組中已配置服務(wù)器的整個列表進(jìn)行索引,然后取消所選服務(wù)器的資格舆蝴,并在必要時重新選擇谦絮。這樣,僅當(dāng)所選服務(wù)器關(guān)閉時才會影響結(jié)果洁仗,而不會影響列表中其他服務(wù)器的索引层皱。關(guān)于這個問題在不同情況下的討論可以在 ebrary.net 上找到。

Indexing into configured servers rather than available servers provides a better chance of consistency in case of server failures

第二個問題是在極少數(shù)情況會出現(xiàn)的一致性bug中發(fā)現(xiàn)的京痢。ProxySQL會在初始服務(wù)器選擇后在進(jìn)行一次額外的負(fù)載均衡選擇奶甘。舉個例子,我們的目標(biāo)權(quán)重是 1:1 但是實(shí)際的鏈接分布會偏移到 3:1祭椰,任何請求都會被強(qiáng)制重新路由到權(quán)重不足的服務(wù)器,我們重寫了服務(wù)選擇方法并去掉了額外的負(fù)載均衡方法疲陕。

目前方淤,我們正在評估將靈活使用復(fù)制滯后測量作為可調(diào)因素的策略,我們可以使用它來修改讀取一致性的方法蹄殃。希望這個特性將繼續(xù)吸引我們的應(yīng)用程序開發(fā)人員携茂,并為每個人提高數(shù)據(jù)庫性能。

我們的解決方案的有點(diǎn)事簡單并且低開銷诅岩。它的主要缺點(diǎn)是服務(wù)停機(jī)()所產(chǎn)生的一致性問題難以檢測讳苦。If your application is tolerant of occasional failures in read consistency,這個解決方案應(yīng)該非常適合你吩谦。如果你需要更嚴(yán)格的一致性方案鸳谜,GTID 因果一致性方案應(yīng)該值得去探索。更詳細(xì)的內(nèi)容可以在這里查看 Adaptive query routing based on GTID tracking式廷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咐扭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子滑废,更是在濱河造成了極大的恐慌蝗肪,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蠕趁,死亡現(xiàn)場離奇詭異薛闪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)俺陋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門豁延,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怀各,“玉大人,你說我怎么就攤上這事术浪∑岸裕” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵胰苏,是天一觀的道長硕蛹。 經(jīng)常有香客問我,道長硕并,這世上最難降的妖魔是什么法焰? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮倔毙,結(jié)果婚禮上埃仪,老公的妹妹穿的比我還像新娘。我一直安慰自己陕赃,他們只是感情好卵蛉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著么库,像睡著了一般傻丝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诉儒,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天葡缰,我揣著相機(jī)與錄音,去河邊找鬼忱反。 笑死泛释,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的温算。 我是一名探鬼主播怜校,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼米者!你這毒婦竟也來了韭畸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蔓搞,失蹤者是張志新(化名)和其女友劉穎胰丁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喂分,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锦庸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蒲祈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甘萧。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡萝嘁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出扬卷,到底是詐尸還是另有隱情牙言,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布怪得,位于F島的核電站咱枉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏徒恋。R本人自食惡果不足惜蚕断,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望入挣。 院中可真熱鬧亿乳,春花似錦、人聲如沸径筏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匠璧。三九已至桐款,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間夷恍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工媳维, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酿雪,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓侄刽,卻偏偏與公主長得像指黎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子州丹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容