14 | 高性能數(shù)據(jù)庫集群:讀寫分離

“從 0 開始學架構(gòu)”專欄已經(jīng)更新了 13 期唉铜,從各個方面闡述了架構(gòu)設(shè)計相關(guān)的理論和流程,包括架構(gòu)設(shè)計起源菠红、架構(gòu)設(shè)計的目的第岖、常見架構(gòu)復雜度分析、架構(gòu)設(shè)計原則试溯、架構(gòu)設(shè)計流程等蔑滓,掌握這些知識是做好架構(gòu)設(shè)計的基礎(chǔ)。

在具體的實踐過程中遇绞,為了更快键袱、更好地設(shè)計出優(yōu)秀的架構(gòu),除了掌握這些基礎(chǔ)知識外摹闽,還需要掌握業(yè)界已經(jīng)成熟的各種架構(gòu)模式蹄咖。大部分情況下,我們做架構(gòu)設(shè)計主要都是基于已有的成熟模式付鹿,結(jié)合業(yè)務(wù)和團隊的具體情況澜汤,進行一定的優(yōu)化或者調(diào)整;即使少部分情況我們需要進行較大的創(chuàng)新舵匾,前提也是需要對已有的各種架構(gòu)模式和技術(shù)非常熟悉俊抵。

接下來,我將逐一介紹最常見的“高性能架構(gòu)模式”“高可用架構(gòu)模式”“可擴展架構(gòu)模式”坐梯,這些模式可能你之前大概了解過徽诲,但其實每個方案里面都有很多細節(jié),只有深入的理解這些細節(jié)才能理解常見的架構(gòu)模式吵血,進而設(shè)計出優(yōu)秀的架構(gòu)谎替。

雖然近十年來各種存儲技術(shù)飛速發(fā)展,但關(guān)系數(shù)據(jù)庫由于其 ACID 的特性和功能強大的 SQL 查詢蹋辅,目前還是各種業(yè)務(wù)系統(tǒng)中關(guān)鍵和核心的存儲系統(tǒng)院喜,很多場景下高性能的設(shè)計最核心的部分就是關(guān)系數(shù)據(jù)庫的設(shè)計。

不管是為了滿足業(yè)務(wù)發(fā)展的需要晕翠,還是為了提升自己的競爭力喷舀,關(guān)系數(shù)據(jù)庫廠商(Oracle、DB2淋肾、MySQL 等)在優(yōu)化和提升單個數(shù)據(jù)庫服務(wù)器的性能方面也做了非常多的技術(shù)優(yōu)化和改進硫麻。但業(yè)務(wù)發(fā)展速度和數(shù)據(jù)增長速度,遠遠超出數(shù)據(jù)庫廠商的優(yōu)化速度樊卓,尤其是互聯(lián)網(wǎng)業(yè)務(wù)興起之后拿愧,海量用戶加上海量數(shù)據(jù)的特點,單個數(shù)據(jù)庫服務(wù)器已經(jīng)難以滿足業(yè)務(wù)需要碌尔,必須考慮數(shù)據(jù)庫集群的方式來提升性能浇辜。

從今天開始券敌,我會分幾期來介紹高性能數(shù)據(jù)庫集群。高性能數(shù)據(jù)庫集群的第一種方式是“讀寫分離”柳洋,其本質(zhì)是將訪問壓力分散到集群中的多個節(jié)點待诅,但是沒有分散存儲壓力;第二種方式是“分庫分表”熊镣,既可以分散訪問壓力卑雁,又可以分散存儲壓力。先來看看“讀寫分離”绪囱,下一期我再介紹“分庫分表”测蹲。

讀寫分離原理

讀寫分離的基本原理是將數(shù)據(jù)庫讀寫操作分散到不同的節(jié)點上,下面是其基本架構(gòu)圖鬼吵。

讀寫分離的基本實現(xiàn)是:

數(shù)據(jù)庫服務(wù)器搭建主從集群扣甲,一主一從、一主多從都可以齿椅。

數(shù)據(jù)庫主機負責讀寫操作琉挖,從機只負責讀操作。

數(shù)據(jù)庫主機通過復制將數(shù)據(jù)同步到從機媒咳,每臺數(shù)據(jù)庫服務(wù)器都存儲了所有的業(yè)務(wù)數(shù)據(jù)粹排。

業(yè)務(wù)服務(wù)器將寫操作發(fā)給數(shù)據(jù)庫主機种远,將讀操作發(fā)給數(shù)據(jù)庫從機涩澡。

需要注意的是,這里用的是“主從集群”坠敷,而不是“主備集群”妙同。“從機”的“從”可以理解為“仆從”膝迎,仆從是要幫主人干活的粥帚,“從機”是需要提供讀數(shù)據(jù)的功能的;而“備機”一般被認為僅僅提供備份功能限次,不提供訪問功能芒涡。所以使用“主從”還是“主備”,是要看場景的卖漫,這兩個詞并不是完全等同的费尽。

讀寫分離的實現(xiàn)邏輯并不復雜,但有兩個細節(jié)點將引入設(shè)計復雜度:主從復制延遲分配機制羊始。

復制延遲

以 MySQL 為例旱幼,主從復制延遲可能達到 1 秒,如果有大量數(shù)據(jù)同步突委,延遲 1 分鐘也是有可能的柏卤。主從復制延遲會帶來一個問題:如果業(yè)務(wù)服務(wù)器將數(shù)據(jù)寫入到數(shù)據(jù)庫主服務(wù)器后立刻(1 秒內(nèi))進行讀取冬三,此時讀操作訪問的是從機,主機還沒有將數(shù)據(jù)復制過來缘缚,到從機讀取數(shù)據(jù)是讀不到最新數(shù)據(jù)的勾笆,業(yè)務(wù)上就可能出現(xiàn)問題。例如忙灼,用戶剛注冊完后立刻登錄匠襟,業(yè)務(wù)服務(wù)器會提示他“你還沒有注冊”,而用戶明明剛才已經(jīng)注冊成功了该园。

解決主從復制延遲有幾種常見的方法:

1. 寫操作后的讀操作指定發(fā)給數(shù)據(jù)庫主服務(wù)器

例如酸舍,注冊賬號完成后,登錄時讀取賬號的讀操作也發(fā)給數(shù)據(jù)庫主服務(wù)器里初。這種方式和業(yè)務(wù)強綁定远剩,對業(yè)務(wù)的侵入和影響較大,如果哪個新來的程序員不知道這樣寫代碼虾标,就會導致一個 bug蔓腐。

2. 讀從機失敗后再讀一次主機

這就是通常所說的“二次讀取”,二次讀取和業(yè)務(wù)無綁定刁品,只需要對底層數(shù)據(jù)庫訪問的 API 進行封裝即可泣特,實現(xiàn)代價較小,不足之處在于如果有很多二次讀取挑随,將大大增加主機的讀操作壓力状您。例如,黑客暴力破解賬號兜挨,會導致大量的二次讀取操作膏孟,主機可能頂不住讀操作的壓力從而崩潰。

3. 關(guān)鍵業(yè)務(wù)讀寫操作全部指向主機拌汇,非關(guān)鍵業(yè)務(wù)采用讀寫分離

例如柒桑,對于一個用戶管理系統(tǒng)來說,注冊 + 登錄的業(yè)務(wù)讀寫操作全部訪問主機噪舀,用戶的介紹魁淳、愛好、等級等業(yè)務(wù)与倡,可以采用讀寫分離界逛,因為即使用戶改了自己的自我介紹,在查詢時卻看到了自我介紹還是舊的蒸走,業(yè)務(wù)影響與不能登錄相比就小很多仇奶,還可以忍受。

分配機制

將讀寫操作區(qū)分開來,然后訪問不同的數(shù)據(jù)庫服務(wù)器该溯,一般有兩種方式:程序代碼封裝中間件封裝岛抄。

1. 程序代碼封裝

程序代碼封裝指在代碼中抽象一個數(shù)據(jù)訪問層(所以有的文章也稱這種方式為“中間層封裝”),實現(xiàn)讀寫操作分離和數(shù)據(jù)庫服務(wù)器連接的管理狈茉。例如夫椭,基于 Hibernate 進行簡單封裝,就可以實現(xiàn)讀寫分離氯庆,基本架構(gòu)是:

程序代碼封裝的方式具備幾個特點:

實現(xiàn)簡單蹭秋,而且可以根據(jù)業(yè)務(wù)做較多定制化的功能。

每個編程語言都需要自己實現(xiàn)一次堤撵,無法通用仁讨,如果一個業(yè)務(wù)包含多個編程語言寫的多個子系統(tǒng),則重復開發(fā)的工作量比較大实昨。

故障情況下洞豁,如果主從發(fā)生切換,則可能需要所有系統(tǒng)都修改配置并重啟荒给。

目前開源的實現(xiàn)方案中丈挟,淘寶的 TDDL(Taobao Distributed Data Layer,外號: 頭都大了)是比較有名的志电。它是一個通用數(shù)據(jù)訪問層曙咽,所有功能封裝在 jar 包中提供給業(yè)務(wù)代碼調(diào)用。其基本原理是一個基于集中式配置的 jdbc datasource 實現(xiàn)挑辆,具有主備例朱、讀寫分離、動態(tài)數(shù)據(jù)庫配置等功能之拨,基本架構(gòu)是:

http://1.im.guokr.com/0Y5YjfjQ8eGOzeskpen2mlNIYA_b7DBLbGT0YHyUiLFZAgAAgwEAAFBO.png

2. 中間件封裝

中間件封裝指的是獨立一套系統(tǒng)出來茉继,實現(xiàn)讀寫操作分離和數(shù)據(jù)庫服務(wù)器連接的管理咧叭。中間件對業(yè)務(wù)服務(wù)器提供 SQL 兼容的協(xié)議蚀乔,業(yè)務(wù)服務(wù)器無須自己進行讀寫分離。對于業(yè)務(wù)服務(wù)器來說菲茬,訪問中間件和訪問數(shù)據(jù)庫沒有區(qū)別吉挣,事實上在業(yè)務(wù)服務(wù)器看來,中間件就是一個數(shù)據(jù)庫服務(wù)器婉弹。其基本架構(gòu)是:

數(shù)據(jù)庫中間件的方式具備的特點是:

能夠支持多種編程語言睬魂,因為數(shù)據(jù)庫中間件對業(yè)務(wù)服務(wù)器提供的是標準 SQL 接口。

數(shù)據(jù)庫中間件要支持完整的 SQL 語法和數(shù)據(jù)庫服務(wù)器的協(xié)議(例如镀赌,MySQL 客戶端和服務(wù)器的連接協(xié)議)氯哮,實現(xiàn)比較復雜,細節(jié)特別多商佛,很容易出現(xiàn) bug喉钢,需要較長的時間才能穩(wěn)定姆打。

數(shù)據(jù)庫中間件自己不執(zhí)行真正的讀寫操作,但所有的數(shù)據(jù)庫操作請求都要經(jīng)過中間件肠虽,中間件的性能要求也很高幔戏。

數(shù)據(jù)庫主從切換對業(yè)務(wù)服務(wù)器無感知,數(shù)據(jù)庫中間件可以探測數(shù)據(jù)庫服務(wù)器的主從狀態(tài)税课。例如闲延,向某個測試表寫入一條數(shù)據(jù),成功的就是主機韩玩,失敗的就是從機垒玲。

由于數(shù)據(jù)庫中間件的復雜度要比程序代碼封裝高出一個數(shù)量級,一般情況下建議采用程序語言封裝的方式找颓,或者使用成熟的開源數(shù)據(jù)庫中間件侍匙。如果是大公司,可以投入人力去實現(xiàn)數(shù)據(jù)庫中間件叮雳,因為這個系統(tǒng)一旦做好想暗,接入的業(yè)務(wù)系統(tǒng)越多,節(jié)省的程序開發(fā)投入就越多帘不,價值也越大说莫。

目前的開源數(shù)據(jù)庫中間件方案中,MySQL 官方先是提供了 MySQL Proxy寞焙,但 MySQL Proxy 一直沒有正式 GA储狭,現(xiàn)在 MySQL 官方推薦 MySQL Router。MySQL Router 的主要功能有讀寫分離捣郊、故障自動切換辽狈、負載均衡、連接池等呛牲,其基本架構(gòu)如下:

https://dev.mysql.com/doc/mysql-router/2.1/en/images/mysql-router-positioning.png

奇虎 360 公司也開源了自己的數(shù)據(jù)庫中間件 Atlas刮萌,Atlas 是基于 MySQL Proxy 實現(xiàn)的,基本架構(gòu)如下:

https://camo.githubusercontent.com/42c01a1245183948ba8c61e5572d3aa9c3e8a08e/687474703a2f2f7777332e73696e61696d672e636e2f6c617267652f36653537303561356a7731656271353169336668716a32306a69306a6a7767392e6a7067

以下是官方介紹娘扩,更多內(nèi)容你可以參考這里着茸。

Atlas 是一個位于應用程序與 MySQL 之間中間件。在后端 DB 看來琐旁,Atlas 相當于連接它的客戶端涮阔,在前端應用看來,Atlas 相當于一個 DB灰殴。Atlas 作為服務(wù)端與應用程序通信敬特,它實現(xiàn)了 MySQL 的客戶端和服務(wù)端協(xié)議,同時作為客戶端與 MySQL 通信。它對應用程序屏蔽了 DB 的細節(jié)伟阔,同時為了降低 MySQL 負擔尸变,它還維護了連接池。

小結(jié)

今天我為你講了讀寫分離方式的原理减俏,以及兩個設(shè)計復雜度:復制延遲和分配機制召烂,希望對你有所幫助。

這就是今天的全部內(nèi)容娃承,留一道思考題給你吧奏夫,數(shù)據(jù)庫讀寫分離一般應用于什么場景?能支撐多大的業(yè)務(wù)規(guī)模历筝?

歡迎你把答案寫到留言區(qū)酗昼,和我一起討論。相信經(jīng)過深度思考的回答梳猪,也會讓你對知識的理解更加深刻麻削。(編輯亂入:精彩的留言有機會獲得豐厚福利哦!)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末春弥,一起剝皮案震驚了整個濱河市呛哟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匿沛,老刑警劉巖扫责,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異逃呼,居然都是意外死亡鳖孤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門抡笼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來苏揣,“玉大人,你說我怎么就攤上這事推姻∑叫伲” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵拾碌,是天一觀的道長吐葱。 經(jīng)常有香客問我街望,道長校翔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任灾前,我火速辦了婚禮防症,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己蔫敲,他們只是感情好饲嗽,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奈嘿,像睡著了一般貌虾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上裙犹,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天尽狠,我揣著相機與錄音,去河邊找鬼叶圃。 笑死袄膏,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的掺冠。 我是一名探鬼主播沉馆,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼德崭!你這毒婦竟也來了斥黑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤眉厨,失蹤者是張志新(化名)和其女友劉穎心赶,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缺猛,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡缨叫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了荔燎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耻姥。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖有咨,靈堂內(nèi)的尸體忽然破棺而出琐簇,到底是詐尸還是另有隱情,我是刑警寧澤座享,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布婉商,位于F島的核電站,受9級特大地震影響渣叛,放射性物質(zhì)發(fā)生泄漏丈秩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一淳衙、第九天 我趴在偏房一處隱蔽的房頂上張望蘑秽。 院中可真熱鬧饺著,春花似錦、人聲如沸肠牲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缀雳。三九已至渡嚣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肥印,已是汗流浹背严拒。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留竖独,地道東北人裤唠。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像莹痢,于是被迫代替她去往敵國和親种蘸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

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