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

高性能數(shù)據(jù)庫(kù)集群的第一種方式是“讀寫(xiě)分離”虱痕,其本質(zhì)是將訪問(wèn)壓力分散到集群中的多個(gè)節(jié)點(diǎn)惩阶,但是沒(méi)有分散存儲(chǔ)壓力;第二種方式是“分庫(kù)分表”钾埂,既可以分散訪問(wèn)壓力河闰,又可以分散存儲(chǔ)壓力。先來(lái)看看“讀寫(xiě)分離”褥紫,下一期我再介紹“分庫(kù)分表”姜性。

讀寫(xiě)分離原理

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

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

數(shù)據(jù)庫(kù)服務(wù)器搭建主從集群部念,一主一從、一主多從都可以。

數(shù)據(jù)庫(kù)主機(jī)負(fù)責(zé)讀寫(xiě)操作儡炼,從機(jī)只負(fù)責(zé)操作妓湘。

數(shù)據(jù)庫(kù)主機(jī)通過(guò)復(fù)制將數(shù)據(jù)同步到從機(jī),每臺(tái)數(shù)據(jù)庫(kù)服務(wù)器都存儲(chǔ)了所有的業(yè)務(wù)數(shù)據(jù)乌询。

業(yè)務(wù)服務(wù)器將寫(xiě)操作發(fā)給數(shù)據(jù)庫(kù)主機(jī)多柑,將讀操作發(fā)給數(shù)據(jù)庫(kù)從機(jī)。

需要注意的是楣责,這里用的是“主從集群”竣灌,而不是“主備集群”「阳铮“從機(jī)”的“從”可以理解為“仆從”初嘹,仆從是要幫主人干活的,“從機(jī)”是需要提供讀數(shù)據(jù)的功能的沮趣;而“備機(jī)”一般被認(rèn)為僅僅提供備份功能屯烦,不提供訪問(wèn)功能。所以使用“主從”還是“主備”房铭,是要看場(chǎng)景的驻龟,這兩個(gè)詞并不是完全等同的。

讀寫(xiě)分離的實(shí)現(xiàn)邏輯并不復(fù)雜缸匪,但有兩個(gè)細(xì)節(jié)點(diǎn)將引入設(shè)計(jì)復(fù)雜度:主從復(fù)制延遲分配機(jī)制翁狐。

復(fù)制延遲

以 MySQL 為例,主從復(fù)制延遲可能達(dá)到 1 秒凌蔬,如果有大量數(shù)據(jù)同步露懒,延遲 1 分鐘也是有可能的。主從復(fù)制延遲會(huì)帶來(lái)一個(gè)問(wèn)題:如果業(yè)務(wù)服務(wù)器將數(shù)據(jù)寫(xiě)入到數(shù)據(jù)庫(kù)主服務(wù)器后立刻(1 秒內(nèi))進(jìn)行讀取砂心,此時(shí)讀操作訪問(wèn)的是從機(jī)懈词,主機(jī)還沒(méi)有將數(shù)據(jù)復(fù)制過(guò)來(lái),到從機(jī)讀取數(shù)據(jù)讀不到最新數(shù)據(jù)的辩诞,業(yè)務(wù)上就可能出現(xiàn)問(wèn)題坎弯。例如,用戶(hù)剛注冊(cè)完后立刻登錄译暂,業(yè)務(wù)服務(wù)器會(huì)提示他“你還沒(méi)有注冊(cè)”抠忘,而用戶(hù)明明剛才已經(jīng)注冊(cè)成功了。

解決主從復(fù)制延遲有幾種常見(jiàn)的方法:

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

例如秧秉,注冊(cè)賬號(hào)完成后褐桌,登錄時(shí)讀取賬號(hào)的讀操作也發(fā)給數(shù)據(jù)庫(kù)主服務(wù)器。這種方式和業(yè)務(wù)強(qiáng)綁定象迎,對(duì)業(yè)務(wù)的侵入和影響較大荧嵌,如果哪個(gè)新來(lái)的程序員不知道這樣寫(xiě)代碼呛踊,就會(huì)導(dǎo)致一個(gè) bug。

2. 讀從機(jī)失敗后再讀一次主機(jī)

這就是通常所說(shuō)的“二次讀取”啦撮,二次讀取和業(yè)務(wù)無(wú)綁定谭网,只需要對(duì)底層數(shù)據(jù)庫(kù)訪問(wèn)的 API 進(jìn)行封裝即可,實(shí)現(xiàn)代價(jià)較小赃春,不足之處在于如果有很多二次讀取愉择,將大大增加主機(jī)的讀操作壓力。例如织中,黑客暴力破解賬號(hào)锥涕,會(huì)導(dǎo)致大量的二次讀取操作,主機(jī)可能頂不住讀操作的壓力從而崩潰狭吼。

3. 關(guān)鍵業(yè)務(wù)讀寫(xiě)操作全部指向主機(jī)层坠,非關(guān)鍵業(yè)務(wù)采用讀寫(xiě)分離

例如,對(duì)于一個(gè)用戶(hù)管理系統(tǒng)來(lái)說(shuō)刁笙,注冊(cè) + 登錄的業(yè)務(wù)讀寫(xiě)操作全部訪問(wèn)主機(jī)破花,用戶(hù)的介紹、愛(ài)好疲吸、等級(jí)等業(yè)務(wù)座每,可以采用讀寫(xiě)分離,因?yàn)榧词褂脩?hù)改了自己的自我介紹摘悴,在查詢(xún)時(shí)卻看到了自我介紹還是舊的峭梳,業(yè)務(wù)影響與不能登錄相比就小很多,還可以忍受烦租。

分配機(jī)制

將讀寫(xiě)操作區(qū)分開(kāi)來(lái)延赌,然后訪問(wèn)不同的數(shù)據(jù)庫(kù)服務(wù)器,一般有兩種方式:程序代碼封裝中間件封裝叉橱。

1. 程序代碼封裝

程序代碼封裝指在代碼中抽象一個(gè)數(shù)據(jù)訪問(wèn)層(所以有的文章也稱(chēng)這種方式為“中間層封裝”),實(shí)現(xiàn)讀寫(xiě)操作分離和數(shù)據(jù)庫(kù)服務(wù)器連接的管理者蠕。例如窃祝,基于 Hibernate 進(jìn)行簡(jiǎn)單封裝,就可以實(shí)現(xiàn)讀寫(xiě)分離踱侣,基本架構(gòu)是:

程序代碼封裝的方式具備幾個(gè)特點(diǎn):

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

每個(gè)編程語(yǔ)言都需要自己實(shí)現(xiàn)一次抡句,無(wú)法通用探膊,如果一個(gè)業(yè)務(wù)包含多個(gè)編程語(yǔ)言寫(xiě)的多個(gè)子系統(tǒng),則重復(fù)開(kāi)發(fā)的工作量比較大待榔。

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

目前開(kāi)源的實(shí)現(xiàn)方案中腌闯,淘寶的 TDDL(Taobao Distributed Data Layer绳瘟,外號(hào): 頭都大了)是比較有名的。它是一個(gè)通用數(shù)據(jù)訪問(wèn)層姿骏,所有功能封裝在 jar 包中提供給業(yè)務(wù)代碼調(diào)用糖声。其基本原理是一個(gè)基于集中式配置的 jdbc datasource 實(shí)現(xiàn),具有主備分瘦、讀寫(xiě)分離蘸泻、動(dòng)態(tài)數(shù)據(jù)庫(kù)配置等功能,基本架構(gòu)是:

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

2. 中間件封裝

中間件封裝指的是獨(dú)立一套系統(tǒng)出來(lái)嘲玫,實(shí)現(xiàn)讀寫(xiě)操作分離和數(shù)據(jù)庫(kù)服務(wù)器連接的管理悦施。中間件對(duì)業(yè)務(wù)服務(wù)器提供 SQL 兼容的協(xié)議,業(yè)務(wù)服務(wù)器無(wú)須自己進(jìn)行讀寫(xiě)分離趁冈。對(duì)于業(yè)務(wù)服務(wù)器來(lái)說(shuō)歼争,訪問(wèn)中間件和訪問(wèn)數(shù)據(jù)庫(kù)沒(méi)有區(qū)別,事實(shí)上在業(yè)務(wù)服務(wù)器看來(lái)渗勘,中間件就是一個(gè)數(shù)據(jù)庫(kù)服務(wù)器沐绒。其基本架構(gòu)是:

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

能夠支持多種編程語(yǔ)言,因?yàn)閿?shù)據(jù)庫(kù)中間件對(duì)業(yè)務(wù)服務(wù)器提供的是標(biāo)準(zhǔn) SQL 接口旺坠。

數(shù)據(jù)庫(kù)中間件要支持完整的 SQL 語(yǔ)法和數(shù)據(jù)庫(kù)服務(wù)器的協(xié)議(例如乔遮,MySQL 客戶(hù)端和服務(wù)器的連接協(xié)議),實(shí)現(xiàn)比較復(fù)雜取刃,細(xì)節(jié)特別多蹋肮,很容易出現(xiàn) bug,需要較長(zhǎng)的時(shí)間才能穩(wěn)定璧疗。

數(shù)據(jù)庫(kù)中間件自己不執(zhí)行真正的讀寫(xiě)操作坯辩,但所有的數(shù)據(jù)庫(kù)操作請(qǐng)求都要經(jīng)過(guò)中間件,中間件的性能要求也很高崩侠。

數(shù)據(jù)庫(kù)主從切換對(duì)業(yè)務(wù)服務(wù)器無(wú)感知漆魔,數(shù)據(jù)庫(kù)中間件可以探測(cè)數(shù)據(jù)庫(kù)服務(wù)器的主從狀態(tài)。例如却音,向某個(gè)測(cè)試表寫(xiě)入一條數(shù)據(jù)改抡,成功的就是主機(jī),失敗的就是從機(jī)系瓢。

由于數(shù)據(jù)庫(kù)中間件的復(fù)雜度要比程序代碼封裝高出一個(gè)數(shù)量級(jí)阿纤,一般情況下建議采用程序語(yǔ)言封裝的方式,或者使用成熟的開(kāi)源數(shù)據(jù)庫(kù)中間件夷陋。如果是大公司欠拾,可以投入人力去實(shí)現(xiàn)數(shù)據(jù)庫(kù)中間件胰锌,因?yàn)檫@個(gè)系統(tǒng)一旦做好,接入的業(yè)務(wù)系統(tǒng)越多清蚀,節(jié)省的程序開(kāi)發(fā)投入就越多匕荸,價(jià)值也越大。

目前的開(kāi)源數(shù)據(jù)庫(kù)中間件方案中枷邪,MySQL 官方先是提供了 MySQL Proxy榛搔,但 MySQL Proxy 一直沒(méi)有正式 GA,現(xiàn)在 MySQL 官方推薦 MySQL Router东揣。MySQL Router 的主要功能有讀寫(xiě)分離践惑、故障自動(dòng)切換、負(fù)載均衡嘶卧、連接池等尔觉,其基本架構(gòu)如下:

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

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

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

以下是官方介紹侦铜,更多內(nèi)容你可以參考這里

Atlas 是一個(gè)位于應(yīng)用程序與 MySQL 之間中間件钟鸵。在后端 DB 看來(lái)钉稍,Atlas 相當(dāng)于連接它的客戶(hù)端,在前端應(yīng)用看來(lái)棺耍,Atlas 相當(dāng)于一個(gè) DB贡未。Atlas 作為服務(wù)端與應(yīng)用程序通信,它實(shí)現(xiàn)了 MySQL 的客戶(hù)端和服務(wù)端協(xié)議蒙袍,同時(shí)作為客戶(hù)端與 MySQL 通信俊卤。它對(duì)應(yīng)用程序屏蔽了 DB 的細(xì)節(jié),同時(shí)為了降低 MySQL 負(fù)擔(dān)害幅,它還維護(hù)了連接池消恍。

小結(jié)

數(shù)據(jù)庫(kù)讀寫(xiě)分離一般應(yīng)用于什么場(chǎng)景?能支撐多大的業(yè)務(wù)規(guī)模以现?

評(píng)論1

我們做網(wǎng)銀系統(tǒng)哺哼,用redis存了一些不太重要的數(shù)據(jù),比如數(shù)據(jù)字典信息叼风,作為緩存。但是不太敢把用戶(hù)權(quán)限棍苹,交易數(shù)據(jù)等重要信息存在緩存里无宿,因?yàn)?b>redis并不保證事務(wù),我們擔(dān)心一旦緩存服務(wù)器宕機(jī)或者失敗會(huì)影響銀行業(yè)務(wù)枢里。所以緩存的作用也不是很大孽鸡,還是把大部分讀數(shù)據(jù)的壓力放到了數(shù)據(jù)庫(kù)上蹂午,您說(shuō)我們這種擔(dān)心有必要嗎?如果單庫(kù)后續(xù)扛不住壓力彬碱,是否讀寫(xiě)分離比加緩存更好一些豆胸?

交易型業(yè)務(wù)緩存應(yīng)用不多,緩存一般總在查詢(xún)類(lèi)業(yè)務(wù)上巷疼,你們的擔(dān)心有一定必要

評(píng)論2

適合:讀多寫(xiě)少

不適用的情況:1如果并發(fā)寫(xiě)入特別高晚胡,單機(jī)寫(xiě)入無(wú)法支撐,就不適合這種模式嚼沿。

2 通過(guò)存技術(shù)或者程序優(yōu)化能夠滿(mǎn)足要求

同步速度主要受網(wǎng)絡(luò)延遲影響估盘,和硬件關(guān)系不大,而且線(xiàn)上配置最好一樣骡尽,否則出問(wèn)題不好排查

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末遣妥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子攀细,更是在濱河造成了極大的恐慌箫踩,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谭贪,死亡現(xiàn)場(chǎng)離奇詭異境钟,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)故河,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)吱韭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鱼的,你說(shuō)我怎么就攤上這事理盆。” “怎么了凑阶?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵猿规,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我宙橱,道長(zhǎng)姨俩,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任师郑,我火速辦了婚禮环葵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宝冕。我一直安慰自己张遭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布地梨。 她就那樣靜靜地躺著菊卷,像睡著了一般缔恳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洁闰,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天歉甚,我揣著相機(jī)與錄音,去河邊找鬼扑眉。 笑死纸泄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的襟雷。 我是一名探鬼主播刃滓,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耸弄!你這毒婦竟也來(lái)了咧虎?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤计呈,失蹤者是張志新(化名)和其女友劉穎砰诵,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體捌显,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茁彭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扶歪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片理肺。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖善镰,靈堂內(nèi)的尸體忽然破棺而出妹萨,到底是詐尸還是另有隱情,我是刑警寧澤炫欺,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布乎完,位于F島的核電站,受9級(jí)特大地震影響品洛,放射性物質(zhì)發(fā)生泄漏树姨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一桥状、第九天 我趴在偏房一處隱蔽的房頂上張望帽揪。 院中可真熱鬧,春花似錦辅斟、人聲如沸台丛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)挽霉。三九已至,卻和暖如春变汪,著一層夾襖步出監(jiān)牢的瞬間侠坎,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工裙盾, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留实胸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓番官,卻偏偏與公主長(zhǎng)得像庐完,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子徘熔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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