數(shù)據(jù)庫(kù)高可用架構(gòu)設(shè)計(jì),看這篇就夠了

你好桶错,我是小編沐子航唆。

又趕上一年一度的金九銀十的日子,這段期間的招聘崗位相對(duì)前幾個(gè)月會(huì)多些院刁,如果在目前公司沒有進(jìn)步糯钙、沒有前途時(shí),這段時(shí)間可以準(zhǔn)備一下退腥,去外面看看機(jī)會(huì)任岸。不過(guò)在外面找工作時(shí),可以提前在網(wǎng)上看看招聘信息阅虫,看看自己是否達(dá)到公司要求演闭。如果多看下高薪資的技術(shù)人員招聘要求時(shí),就會(huì)發(fā)現(xiàn)對(duì)三高都有一定的要求颓帝,比如下面一家公司的要求就對(duì)高并發(fā)米碰、高負(fù)載和高可用性系統(tǒng)設(shè)計(jì)要有開發(fā)經(jīng)驗(yàn)。

現(xiàn)實(shí)是我們大部分的公司都很少會(huì)遇到三高的場(chǎng)景购城,即很少有這方面的設(shè)計(jì)開發(fā)經(jīng)驗(yàn)吕座,不過(guò)我們可以提前學(xué)習(xí)三高的方案,盡量把這些方案用在工作上瘪板,即使在工作中用不到吴趴,那么在面試中也會(huì)有好處或者對(duì)以后的工作也會(huì)起到一定的幫助。這篇文章我就來(lái)和大家聊一聊侮攀,我在工作中用到的數(shù)據(jù)庫(kù)高可用方案锣枝,以及采用這些方案所遇到的問(wèn)題,希望這些心得可以幫助到你兰英。


一撇叁、 高可用背景

高可用概念

高可用(High Availability)是系統(tǒng)所能提供無(wú)故障服務(wù)的一種能力。簡(jiǎn)單地說(shuō)就是避免因服務(wù)器宕機(jī)而造成的服務(wù)不可用畦贸。


通常來(lái)說(shuō)陨闹,系統(tǒng)至少要達(dá)到 4 個(gè) 9(99.99%),也就是每年宕機(jī)時(shí)間不超過(guò) 52.56 分鐘薄坏,否則用戶體驗(yàn)會(huì)非常差趋厉,感覺系統(tǒng)不穩(wěn)定。

99.99% = 1 - 52.56 / (365*24*60)

不過(guò)

4 個(gè) 9 宕機(jī) 52 分鐘對(duì)于生產(chǎn)環(huán)境的影響還是比較大胶坠,但是 5 個(gè) 9 對(duì)大部分系統(tǒng)來(lái)說(shuō)要求又太高君账。所以一些云服務(wù)商會(huì)提出一個(gè)

99.995% 的可用性概念,那么系統(tǒng)一年的不可用時(shí)長(zhǎng)為:不可用時(shí)長(zhǎng) = (1 - 99.995%)*365*24*60 = 26.28

(分鐘)涵但,即一年最多的影響服務(wù)的時(shí)間為 26.28 分鐘杈绸。

簡(jiǎn)單了解“高可用”有多么重要之后帖蔓,接下來(lái)我們就來(lái)看一下,怎么設(shè)計(jì)數(shù)據(jù)庫(kù)高可用架構(gòu)瞳脓。系統(tǒng)要達(dá)到高可用塑娇,一定要做好軟硬件的冗余,消除單點(diǎn)故障(SPOF single point of failure)劫侧。冗余是高可用的基礎(chǔ)埋酬,通常認(rèn)為,系統(tǒng)投入硬件資源越多烧栋,冗余也就越多写妥,系統(tǒng)可用性也就越高。除了做好冗余审姓,系統(tǒng)還要做好故障轉(zhuǎn)移(Failover)的處理珍特。也就是在最短的時(shí)間內(nèi)發(fā)現(xiàn)故障,然后把業(yè)務(wù)切換到冗余的資源上魔吐。在介紹高可用架構(gòu)之前扎筒,我們先了解一下數(shù)據(jù)庫(kù)復(fù)制的原理

二酬姆、 數(shù)據(jù)庫(kù)復(fù)制原理

數(shù)據(jù)庫(kù)復(fù)制本質(zhì)上就是數(shù)據(jù)同步嗜桌。MySQL 數(shù)據(jù)庫(kù)是基于二進(jìn)制日志(binary log)進(jìn)行數(shù)據(jù)增量同步,而二進(jìn)制日志記錄了所有對(duì)于 MySQL 數(shù)據(jù)庫(kù)的修改操作辞色。

在默認(rèn) ROW 格式二進(jìn)制日志中骨宠,一條 SQL 操作影響的記錄會(huì)被全部記錄下來(lái),比如一條 SQL語(yǔ)句更新了三行記錄相满,在二進(jìn)制日志中會(huì)記錄被修改的這三條記錄的前項(xiàng)(before image)和后項(xiàng)(after image)层亿。

在有二進(jìn)制日志的基礎(chǔ)上,MySQL 數(shù)據(jù)庫(kù)就可以通過(guò)數(shù)據(jù)復(fù)制技術(shù)實(shí)現(xiàn)數(shù)據(jù)同步了立美。而數(shù)據(jù)復(fù)制的本質(zhì)就是把一臺(tái) MySQL 數(shù)據(jù)庫(kù)上的變更同步到另一臺(tái) MySQL 數(shù)據(jù)庫(kù)上棕所,下面這張圖顯示了當(dāng)前 MySQL 數(shù)據(jù)庫(kù)的復(fù)制架構(gòu):


可以看到,在 MySQL 復(fù)制中悯辙,一臺(tái)是數(shù)據(jù)庫(kù)的角色是 Master(也叫 Primary),剩下的服務(wù)器角色是 Slave(也叫 Standby):

a. Master 服務(wù)器會(huì)把數(shù)據(jù)變更產(chǎn)生的二進(jìn)制日志通過(guò) Dump 線程發(fā)送給 Slave 服務(wù)器迎吵;

b. Slave 服務(wù)器中的 I/O 線程負(fù)責(zé)接受二進(jìn)制日志躲撰,并保存為中繼日志;

c. SQL/Worker 線程負(fù)責(zé)并行執(zhí)行中繼日志击费,即在 Slave 服務(wù)器上回放 Master 產(chǎn)生的日志拢蛋。

得益于二進(jìn)制日志,MySQL 的復(fù)制相比其他數(shù)據(jù)庫(kù)蔫巩,如 Oracle谆棱、PostgreSQL 等快压,非常靈活,用戶可以根據(jù)自己的需要構(gòu)建所需要的復(fù)制拓?fù)浣Y(jié)構(gòu)垃瞧,比如:


在上圖中蔫劣,Slave1、Slave2个从、Slave3

都是 Master 的從服務(wù)器脉幢,而 Slave11 是 Slave1 的從服務(wù)器,Slave1 服務(wù)器既是 Master 的從機(jī)嗦锐,又是

Slave11 的主機(jī)嫌松,所以 Slave1 是個(gè)級(jí)聯(lián)的從機(jī)。同理奕污,Slave3 也是臺(tái)級(jí)聯(lián)的從機(jī)萎羔。

MySQL復(fù)制類型及應(yīng)用選項(xiàng)

MySQL 復(fù)制可以分為以下幾種類型:

默認(rèn)的復(fù)制是異步復(fù)制,而很多新同學(xué)因?yàn)椴涣私?MySQL 除了異步復(fù)制還有其他復(fù)制的類型碳默,所以錯(cuò)誤地在業(yè)務(wù)中使用了異步復(fù)制贾陷。為了解決這個(gè)問(wèn)題,我們一起詳細(xì)了解一下每種復(fù)制類型腻窒,以及它們?cè)跇I(yè)務(wù)中的選型昵宇,方便你在業(yè)務(wù)做正確的選型。

異步復(fù)制

在異步復(fù)制(async

replication)中儿子,Master 不用關(guān)心 Slave 是否接收到二進(jìn)制日志瓦哎,所以 Master 與 Slave

沒有任何的依賴關(guān)系。你可以認(rèn)為 Master 和 Slave 是分別獨(dú)自工作的兩臺(tái)服務(wù)器柔逼,數(shù)據(jù)最終會(huì)通過(guò)二進(jìn)制日志達(dá)到一致蒋譬。

異步復(fù)制的性能最好,因?yàn)樗鼘?duì)數(shù)據(jù)庫(kù)本身幾乎沒有任何開銷愉适,除非主從延遲非常大犯助,Dump Thread 需要讀取大量二進(jìn)制日志文件。

如果業(yè)務(wù)對(duì)于數(shù)據(jù)一致性要求不高维咸,當(dāng)發(fā)生故障時(shí)剂买,能容忍數(shù)據(jù)的丟失,甚至大量的丟失癌蓖,推薦用異步復(fù)制瞬哼,這樣性能最好(比如像微博這樣的業(yè)務(wù),雖然它對(duì)性能的要求極高租副,但對(duì)于數(shù)據(jù)丟失坐慰,通常可以容忍)用僧。但往往核心業(yè)務(wù)系統(tǒng)最關(guān)心的就是數(shù)據(jù)安全,比如監(jiān)控業(yè)務(wù)、告警系統(tǒng)俱饿。

半同步復(fù)制

半同步復(fù)制要求 Master 事務(wù)提交過(guò)程中,至少有 N 個(gè) Slave 接收到二進(jìn)制日志攀操,這樣就能保證當(dāng) Master 發(fā)生宕機(jī),至少有 N 臺(tái) Slave 服務(wù)器中的數(shù)據(jù)是完整的着逐。

半同步復(fù)制并不是 MySQL 內(nèi)置的功能崔赌,而是要安裝半同步插件,并啟用半同步復(fù)制功能耸别,設(shè)置 N 個(gè) Slave 接受二進(jìn)制日志成功健芭,比如:

plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"

rpl-semi-sync-master-enabled = 1

rpl-semi-sync-slave-enabled = 1

rpl_semi_sync_master_wait_no_slave = 1

上面的配置中:

第 1 行要求數(shù)據(jù)庫(kù)啟動(dòng)時(shí)安裝半同步插件;

第 2秀姐、3 行表示分別啟用半同步 Master 和半同步 Slave 插件慈迈;

第 4 行表示半同步復(fù)制過(guò)程中,提交的事務(wù)必須至少有一個(gè) Slave 接收到二進(jìn)制日志省有。

在半同步復(fù)制中痒留,有損半同步復(fù)制是 MySQL 5.7 版本前的半同步復(fù)制機(jī)制,這種半同步復(fù)制在Master 發(fā)生宕機(jī)時(shí)蠢沿,Slave 會(huì)丟失最后一批提交的數(shù)據(jù)伸头,若這時(shí) Slave 提升(Failover)為Master,可能會(huì)發(fā)生已經(jīng)提交的事情不見了舷蟀,發(fā)生了回滾的情況恤磷。

有損半同步復(fù)制原理如下圖所示:


可以看到,有損半同步是在

Master 事務(wù)提交后野宜,即步驟 4 后扫步,等待 Slave 返回 ACK,表示至少有 Slave

接收到了二進(jìn)制日志匈子,如果這時(shí)二進(jìn)制日志還未發(fā)送到 Slave河胎,Master 就發(fā)生宕機(jī),則此時(shí) Slave 就會(huì)丟失 Master

已經(jīng)提交的數(shù)據(jù)虎敦。

而 MySQL 5.7 的無(wú)損半同步復(fù)制解決了這個(gè)問(wèn)題游岳,其原理如下圖所示:

從上圖可以看到,無(wú)損半同步復(fù)制 WAIT ACK 發(fā)生在事務(wù)提交之前其徙,這樣即便 Slave 沒有收到二進(jìn)制日志吭历,但是 Master 宕機(jī)了,由于最后一個(gè)事務(wù)還沒有提交擂橘,所以本身這個(gè)數(shù)據(jù)對(duì)外也不可見,不存在丟失的問(wèn)題摩骨。

所以通贞,對(duì)于任何有數(shù)據(jù)一致性要求的業(yè)務(wù)朗若,如電商的核心訂單業(yè)務(wù)、銀行昌罩、保險(xiǎn)哭懈、證券等與資金密切相關(guān)的業(yè)務(wù),務(wù)必使用無(wú)損半同步復(fù)制茎用。這樣數(shù)據(jù)才是安全的遣总、有保障的、即使發(fā)生宕機(jī)轨功,從機(jī)也有一份完整的數(shù)據(jù)旭斥。

多源復(fù)制

無(wú)論是異步復(fù)制還是半同步復(fù)制,都是 1 個(gè) Master 對(duì)應(yīng) N 個(gè) Slave古涧。其實(shí) MySQL 也支持 N 個(gè) Master 對(duì)應(yīng) 1 個(gè) Slave垂券,這種架構(gòu)就稱之為多源復(fù)制。

多源復(fù)制允許在不同 MySQL 實(shí)例上的數(shù)據(jù)同步到 1 臺(tái) MySQL 實(shí)例上羡滑,方便在 1 臺(tái) Slave 服務(wù)器上進(jìn)行一些統(tǒng)計(jì)查詢菇爪,如常見的 OLAP 業(yè)務(wù)查詢。

多源復(fù)制的架構(gòu)如下所示:

上圖顯示了訂單庫(kù)柒昏、庫(kù)存庫(kù)凳宙、供應(yīng)商庫(kù),通過(guò)多源復(fù)制同步到了一臺(tái) MySQL 實(shí)例上职祷,接著就可以通過(guò) MySQL 8.0 提供的復(fù)雜 SQL 能力氏涩,對(duì)業(yè)務(wù)進(jìn)行深度的數(shù)據(jù)分析和挖掘。

延遲復(fù)制

前面介紹的復(fù)制架構(gòu)堪旧,Slave 在接收二進(jìn)制日志后會(huì)盡可能快地回放日志削葱,這樣是為了避免主從之間出現(xiàn)延遲。而延遲復(fù)制卻允許Slave 延遲回放接收到的二進(jìn)制日志淳梦,為了避免主服務(wù)器上的誤操作析砸,馬上又同步到了從服務(wù)器,導(dǎo)致數(shù)據(jù)完全丟失爆袍。

我們可以通過(guò)以下命令設(shè)置延遲復(fù)制:

CHANGE MASTER TO master_delay = 3600

這樣就人為設(shè)置了 Slave 落后 Master 服務(wù)器1個(gè)小時(shí)首繁。

延遲復(fù)制主要用于誤操作防范,也在數(shù)據(jù)庫(kù)的備份架構(gòu)設(shè)計(jì)中非常常見陨囊,比如可以設(shè)置一個(gè)延遲一天的延遲備機(jī)弦疮,這樣本質(zhì)上說(shuō),用戶可以有 1 份 24 小時(shí)前的快照蜘醋。

那么當(dāng)線上發(fā)生誤操作胁塞,如 DROP TABLE、DROP DATABASE 這樣災(zāi)難性的命令時(shí),用戶有一個(gè) 24 小時(shí)前的快照啸罢,數(shù)據(jù)可以快速恢復(fù)编检。

對(duì)金融行業(yè)來(lái)說(shuō),延遲復(fù)制是你備份設(shè)計(jì)中扰才,必須考慮的一個(gè)架構(gòu)部分允懂。

在我們了解了數(shù)據(jù)同步的原理后,接下來(lái)我們進(jìn)入常見的數(shù)據(jù)庫(kù)高可用架構(gòu)方案衩匣。

三蕾总、 常見的架構(gòu)方案

1. 常見的架構(gòu)方案

方案一:主備架構(gòu),只有主庫(kù)提供讀寫服務(wù)琅捏,備庫(kù)冗余作故障轉(zhuǎn)移用

1生百、高可用分析:高可用,主庫(kù)掛了午绳,keepalive(只是一種工具)會(huì)自動(dòng)切換到備庫(kù)置侍。這個(gè)過(guò)程對(duì)業(yè)務(wù)層是透明的,無(wú)需修改代碼或配置拦焚。

2蜡坊、高性能分析:讀寫都操作主庫(kù),很容易產(chǎn)生瓶頸赎败。大部分互聯(lián)網(wǎng)應(yīng)用讀多寫少秕衙,讀會(huì)先成為瓶頸,進(jìn)而影響寫性能僵刮。另外据忘,備庫(kù)只是單純的備份,資源利用率50%搞糕,這點(diǎn)方案二可解決勇吊。

3、一致性分析:讀寫都操作主庫(kù)窍仰,不存在數(shù)據(jù)一致性問(wèn)題汉规。

4、擴(kuò)展性分析:無(wú)法通過(guò)加從庫(kù)來(lái)擴(kuò)展讀性能驹吮,進(jìn)而提高整體性能针史。

5、可落地分析:兩點(diǎn)影響落地使用碟狞。第一啄枕,性能一般,這點(diǎn)可以通過(guò)建立高效的索引和引入緩存來(lái)增加讀性能族沃,進(jìn)而提高性能频祝。這也是通用的方案泌参。第二,擴(kuò)展性差常空,這點(diǎn)可以通過(guò)分庫(kù)分表來(lái)擴(kuò)展及舍。

方案二:雙主架構(gòu),兩個(gè)主庫(kù)同時(shí)提供服務(wù)窟绷,負(fù)載均衡

1、高可用分析:高可用咐柜,一個(gè)主庫(kù)掛了兼蜈,不影響另一臺(tái)主庫(kù)提供服務(wù)。這個(gè)過(guò)程對(duì)業(yè)務(wù)層是透明的拙友,無(wú)需修改代碼或配置为狸。

2、高性能分析:讀寫性能相比于方案一都得到提升遗契,提升一倍辐棒。

3、一致性分析:存在數(shù)據(jù)一致性問(wèn)題牍蜂。請(qǐng)看漾根,一致性解決方案

4鲫竞、擴(kuò)展性分析:當(dāng)然可以擴(kuò)展成三主循環(huán)辐怕,但筆者不建議(會(huì)多一層數(shù)據(jù)同步,這樣同步的時(shí)間會(huì)更長(zhǎng))从绘。如果非得在數(shù)據(jù)庫(kù)架構(gòu)層面擴(kuò)展的話寄疏,擴(kuò)展為方案四。

5僵井、可落地分析:兩點(diǎn)影響落地使用陕截。第一,數(shù)據(jù)一致性問(wèn)題批什,一致性解決方案可解決問(wèn)題农曲。第二,主鍵沖突問(wèn)題渊季,ID統(tǒng)一地由分布式ID生成服務(wù)來(lái)生成可解決問(wèn)題朋蔫。

方案三:主從架構(gòu),一主多從却汉,讀寫分離

1驯妄、高可用分析:主庫(kù)單點(diǎn),從庫(kù)高可用合砂。一旦主庫(kù)掛了青扔,寫服務(wù)也就無(wú)法提供。

2、高性能分析:大部分互聯(lián)網(wǎng)應(yīng)用讀多寫少微猖,讀會(huì)先成為瓶頸谈息,進(jìn)而影響整體性能。讀的性能提高了凛剥,整體性能也提高了侠仇。另外,主庫(kù)可以不用索引犁珠,線上從庫(kù)和線下從庫(kù)也可以建立不同的索引(線上從庫(kù)如果有多個(gè)還是要建立相同的索引逻炊,不然得不償失;線下從庫(kù)是平時(shí)開發(fā)人員排查線上問(wèn)題時(shí)查的庫(kù)犁享,可以建更多的索引)余素。

3、一致性分析:存在數(shù)據(jù)一致性問(wèn)題炊昆。請(qǐng)看桨吊,一致性解決方案

4凤巨、擴(kuò)展性分析:可以通過(guò)加從庫(kù)來(lái)擴(kuò)展讀性能视乐,進(jìn)而提高整體性能。(帶來(lái)的問(wèn)題是磅甩,從庫(kù)越多需要從主庫(kù)拉取binlog日志的端就越多炊林,進(jìn)而影響主庫(kù)的性能,并且數(shù)據(jù)同步完成的時(shí)間也會(huì)更長(zhǎng))

5卷要、可落地分析:兩點(diǎn)影響落地使用渣聚。第一,數(shù)據(jù)一致性問(wèn)題僧叉,一致性解決方案可解決問(wèn)題奕枝。第二,主庫(kù)單點(diǎn)問(wèn)題瓶堕,筆者暫時(shí)沒想到很好的解決方案隘道。

注:思考一個(gè)問(wèn)題,一臺(tái)從庫(kù)掛了會(huì)怎樣郎笆?讀寫分離之讀的負(fù)載均衡策略怎么容錯(cuò)谭梗?

方案四:雙主+主從架構(gòu),看似完美的方案

1宛蚓、高可用分析:高可用激捏。

2、高性能分析:高性能凄吏。

3远舅、一致性分析:存在數(shù)據(jù)一致性問(wèn)題闰蛔。請(qǐng)看,一致性解決方案 图柏。

4序六、擴(kuò)展性分析:可以通過(guò)加從庫(kù)來(lái)擴(kuò)展讀性能,進(jìn)而提高整體性能蚤吹。(帶來(lái)的問(wèn)題同方案二

5例诀、可落地分析:同方案二,但數(shù)據(jù)同步又多了一層裁着,數(shù)據(jù)延遲更嚴(yán)重余佃。

2. 一致性問(wèn)題解決方案

第一類:主庫(kù)和從庫(kù)一致性解決方案

注:圖中圈出的是數(shù)據(jù)同步的地方,數(shù)據(jù)同步(從庫(kù)從主庫(kù)拉取binlog日志跨算,再執(zhí)行一遍)是需要時(shí)間的,這個(gè)同步時(shí)間內(nèi)主庫(kù)和從庫(kù)的數(shù)據(jù)會(huì)存在不一致的情況椭懊。如果同步過(guò)程中有讀請(qǐng)求诸蚕,那么讀到的就是從庫(kù)中的老數(shù)據(jù)。如下圖氧猬。

既然知道了數(shù)據(jù)不一致性產(chǎn)生的原因背犯,有下面幾個(gè)解決方案供參考:

1、直接忽略盅抚,如果業(yè)務(wù)允許延時(shí)存在漠魏,那么就不去管它。

2妄均、強(qiáng)制讀主柱锹,采用主備架構(gòu)方案,讀寫都走主庫(kù)丰包。用緩存來(lái)擴(kuò)展數(shù)據(jù)庫(kù)讀性能 禁熏。

有一點(diǎn)需要知道:如果緩存掛了,可能會(huì)產(chǎn)生雪崩現(xiàn)象邑彪,不過(guò)一般分布式緩存都是高可用的瞧毙。

3、選擇讀主寄症,寫操作時(shí)根據(jù)庫(kù)+表+業(yè)務(wù)特征生成一個(gè)key放到Cache里并設(shè)置超時(shí)時(shí)間(大于等于主從數(shù)據(jù)同步時(shí)間)宙彪。讀請(qǐng)求時(shí),同樣的方式生成key先去查Cache有巧,再判斷是否命中释漆。若命中,則讀主庫(kù)剪决,否則讀從庫(kù)灵汪。代價(jià)是多了一次緩存讀寫檀训,基本可以忽略。

4享言、半同步復(fù)制峻凫,等主從同步完成,寫請(qǐng)求才返回览露。就是大家常說(shuō)的“半同步復(fù)制”semi-sync荧琼。這可以利用數(shù)據(jù)庫(kù)原生功能,實(shí)現(xiàn)比較簡(jiǎn)單差牛。代價(jià)是寫請(qǐng)求時(shí)延增長(zhǎng)命锄,吞吐量降低。

5偏化、數(shù)據(jù)庫(kù)中間件脐恩,引入開源(mycat等)或自研的數(shù)據(jù)庫(kù)中間層。個(gè)人理解侦讨,思路同選擇讀主驶冒。數(shù)據(jù)庫(kù)中間件的成本比較高,并且還多引入了一層韵卤。

第二類:DB和緩存一致性解決方案

先來(lái)看一下常用的緩存使用方式:

第一步:淘汰緩存骗污;

第二步:寫入數(shù)據(jù)庫(kù);

第三步:讀取緩存沈条?返回:讀取數(shù)據(jù)庫(kù)需忿;

第四步:讀取數(shù)據(jù)庫(kù)后寫入緩存。

注:如果按照這種方式蜡歹,圖一屋厘,不會(huì)產(chǎn)生DB和緩存不一致問(wèn)題;圖二月而,會(huì)產(chǎn)生DB和緩存不一致問(wèn)題擅这,即r2.read先于w3.sync執(zhí)行。如果不做處理景鼠,緩存里的數(shù)據(jù)可能一直是臟數(shù)據(jù)仲翎。解決方式如下:

3. 總結(jié)

1、架構(gòu)演變

1铛漓、架構(gòu)演變一:方案一 -> 方案一+分庫(kù)分表 -> 方案二+分庫(kù)分表 -> 方案四+分庫(kù)分表溯香;

2、架構(gòu)演變二:方案一 -> 方案一+分庫(kù)分表 -> 方案三+分庫(kù)分表 -> 方案四+分庫(kù)分表浓恶;

3玫坛、架構(gòu)演變?nèi)悍桨敢?-> 方案二 -> 方案四 -> 方案四+分庫(kù)分表;

4包晰、架構(gòu)演變四:方案一 -> 方案三 -> 方案四 -> 方案四+分庫(kù)分表湿镀;

2炕吸、個(gè)人見解

1、加緩存和索引是通用的提升數(shù)據(jù)庫(kù)性能的方式勉痴;

2赫模、分庫(kù)分表帶來(lái)的好處是巨大的,但同樣也會(huì)帶來(lái)一些問(wèn)題蒸矛。

3瀑罗、不管是主備+分庫(kù)分表還是主從+讀寫分離+分庫(kù)分表,都要考慮具體的業(yè)務(wù)場(chǎng)景雏掠。58到家發(fā)展四年斩祭,絕大部分的數(shù)據(jù)庫(kù)架構(gòu)還是采用方案一和方案一+分庫(kù)分表,只有極少部分用方案三+讀寫分離+分庫(kù)分表乡话。另外摧玫,阿里云提供的數(shù)據(jù)庫(kù)云服務(wù)也都是主備方案,要想主從+讀寫分離需要二次架構(gòu)绑青。

4席赂、記住一句話:不考慮業(yè)務(wù)場(chǎng)景的架構(gòu)都是耍流氓。

四时迫、 容災(zāi)方案

高可用用于處理各種宕機(jī)問(wèn)題,而宕機(jī)可以分成服務(wù)器宕機(jī)谓晌、機(jī)房級(jí)宕機(jī)掠拳,甚至是一個(gè)城市發(fā)生宕機(jī)。

機(jī)房級(jí)宕機(jī):機(jī)房光纖不通/被挖斷纸肉,機(jī)房整體掉電(雙路備用電源也不可用)溺欧;

城市級(jí)宕機(jī):一般指整個(gè)城市的進(jìn)出口網(wǎng)絡(luò),骨干交換機(jī)發(fā)生的故障(這種情況發(fā)生的概率很邪胤尽)姐刁。

如果綜合考慮的話,高可用就成了一種容災(zāi)處理機(jī)制烦味,對(duì)應(yīng)的高可用架構(gòu)的評(píng)判標(biāo)準(zhǔn)就上升了聂使。

機(jī)房?jī)?nèi)容災(zāi):機(jī)房?jī)?nèi)某臺(tái)數(shù)據(jù)庫(kù)服務(wù)器不可用,切換到同機(jī)房的數(shù)據(jù)庫(kù)實(shí)例谬俄,保障業(yè)務(wù)連續(xù)性柏靶;

同城容災(zāi):機(jī)房不可用,切換到同城機(jī)房的數(shù)據(jù)庫(kù)實(shí)例溃论,保障業(yè)務(wù)連續(xù)性屎蜓;

跨城容災(zāi):?jiǎn)蝹€(gè)城市機(jī)房都不可用,切換到跨城機(jī)房的數(shù)據(jù)庫(kù)實(shí)例钥勋,保障業(yè)務(wù)連續(xù)性炬转。

前面我們談到的高可用設(shè)計(jì)辆苔,都只是機(jī)房?jī)?nèi)的容災(zāi)。也就是說(shuō)扼劈,我們的主服務(wù)器和從服務(wù)器都在一個(gè)機(jī)房?jī)?nèi)驻啤,現(xiàn)在我們來(lái)看一下同城和跨城的容災(zāi)設(shè)計(jì)(我提醒一下,不論是機(jī)房?jī)?nèi)容災(zāi)测僵、同城容災(zāi)街佑,還是跨城容災(zāi),都是基于 MySQL 的無(wú)損半同步復(fù)制捍靠,只是物理部署方式不同沐旨,解決不同的問(wèn)題)。

對(duì)于同城容災(zāi)榨婆,我看到很多這樣的設(shè)計(jì):

這種設(shè)計(jì)沒有考慮到機(jī)房網(wǎng)絡(luò)的抖動(dòng)磁携。如果機(jī)房 1 和機(jī)房 2 之間的網(wǎng)絡(luò)發(fā)生抖動(dòng),那么因?yàn)槭聞?wù)提交需要機(jī)房 2 中的從服務(wù)器接收日志良风,所以會(huì)出現(xiàn)事務(wù)提交被 hang 住的問(wèn)題谊迄。

而機(jī)房網(wǎng)絡(luò)抖動(dòng)非常常見,所以核心業(yè)務(wù)同城容災(zāi)務(wù)要采用三園區(qū)的架構(gòu)烟央,如下圖所示:

該架構(gòu)稱為“三園區(qū)的架構(gòu)”统诺,如果三個(gè)機(jī)房都在一個(gè)城市,則稱為“ 一地三中心”疑俭,如果在相鄰兩個(gè)城市粮呢,那么就叫“兩地三中心”。但這種同城/近城容災(zāi)钞艇,要求機(jī)房網(wǎng)絡(luò)之間的延遲不超過(guò) 5ms啄寡。

在三園區(qū)架構(gòu)中,一份數(shù)據(jù)被存放在了 3 個(gè)機(jī)房哩照,機(jī)房之間根據(jù)半同步復(fù)制挺物。這里將 MySQL 的半同步復(fù)制參數(shù)

rpl_semi_sync_master_wait_for_slave_count 設(shè)置為 1,表示只要有 1 個(gè)半同步備機(jī)接收到日志飘弧,主服務(wù)器上的事務(wù)就可以提交识藤。

這樣的設(shè)計(jì),保證除主機(jī)房外次伶,數(shù)據(jù)在其他機(jī)房至少一份完整的數(shù)據(jù)蹋岩。

另外,即便機(jī)房 1 與機(jī)房 2 發(fā)生網(wǎng)絡(luò)抖動(dòng)学少,因?yàn)闄C(jī)房 1 與機(jī)房 3 之間的網(wǎng)絡(luò)很好剪个,不會(huì)影響事務(wù)在主服務(wù)器上的提交。如果機(jī)房 1 的出口交換機(jī)或光纖發(fā)生故障,那么這時(shí)高可用套件會(huì) FAILOVER 到機(jī)房 2 或機(jī)房 3扣囊,因?yàn)橹辽儆幸环輸?shù)據(jù)是完整的乎折。

機(jī)房 2、機(jī)房 3 的數(shù)據(jù)用于保障數(shù)據(jù)一致性侵歇,但是如果要實(shí)現(xiàn)讀寫分離骂澄,或備份,還需要引入異步復(fù)制的備機(jī)節(jié)點(diǎn)惕虑。所以整體架構(gòu)調(diào)整為:

從圖中可以看到坟冲,我們加入兩個(gè)異步復(fù)制的節(jié)點(diǎn),用于業(yè)務(wù)實(shí)現(xiàn)讀寫分離溃蔫,另外再?gòu)臋C(jī)房 3 的備機(jī)中健提,引入一個(gè)異步復(fù)制的延遲備機(jī),用于做數(shù)據(jù)誤刪除操作的恢復(fù)伟叛。

當(dāng)設(shè)計(jì)成類似上述的架構(gòu)時(shí)私痹,你才能認(rèn)為自己的同城容災(zāi)架構(gòu)是合格的!

另一個(gè)重要的點(diǎn):因?yàn)闄C(jī)房 1 中的主服務(wù)器要向四個(gè)從服務(wù)器發(fā)送日志统刮,這時(shí)網(wǎng)卡有成為瓶頸的可能紊遵,所以請(qǐng)務(wù)必配置萬(wàn)兆網(wǎng)卡。

在明白三園區(qū)架構(gòu)后侥蒙,要實(shí)現(xiàn)跨城容災(zāi)也就非常簡(jiǎn)單了暗膜, 只要把三個(gè)機(jī)房放在不同城市就行。但這樣的設(shè)計(jì)鞭衩,當(dāng)主服務(wù)器發(fā)生宕機(jī)時(shí)学搜,數(shù)據(jù)庫(kù)就會(huì)切到跨城,而跨城之間的網(wǎng)絡(luò)延遲超過(guò)了25 ms醋旦。所以,跨城容災(zāi)一般設(shè)計(jì)成“三地五中心”的架構(gòu)会放,如下圖所示:

由于有五個(gè)機(jī)房饲齐,所以 ACK 設(shè)置為 2,保證至少一份數(shù)據(jù)在兩個(gè)機(jī)房有數(shù)據(jù)咧最。這樣當(dāng)發(fā)生城市級(jí)故障捂人,則城市 2 或城市 3 中,至少有一份完整的數(shù)據(jù)矢沿。

在真實(shí)的互聯(lián)網(wǎng)業(yè)務(wù)場(chǎng)景中滥搭,“三地五中心”應(yīng)用并不像“三園區(qū)”那樣普遍。這是因?yàn)?25ms的延遲對(duì)業(yè)務(wù)的影響非常大捣鲸,一般這種架構(gòu)應(yīng)用于讀多寫少的場(chǎng)景瑟匆,比如用戶中心。

另外栽惶,真實(shí)的互聯(lián)網(wǎng)業(yè)務(wù)場(chǎng)景中愁溜,實(shí)現(xiàn)跨城容災(zāi)疾嗅,一般基于同城容災(zāi)架構(gòu),然后再由業(yè)務(wù)層來(lái)保障跨城的數(shù)據(jù)一致性冕象。

五代承、 兜底策略:數(shù)據(jù)核對(duì)

到目前為止,我們的高可用是基于 MySQL 的復(fù)制技術(shù)渐扮。但你有沒有想過(guò)這樣幾個(gè)問(wèn)題:

萬(wàn)一數(shù)據(jù)庫(kù)的復(fù)制有 Bug 呢论悴?導(dǎo)致最終的數(shù)據(jù)在邏輯上不一致呢?主從的數(shù)據(jù)一定一致嗎墓律?你如何判斷一定一致呢膀估?

所以,除了高可用的容災(zāi)架構(gòu)設(shè)計(jì)只锻,我們還要做一層兜底服務(wù)玖像,用于判斷數(shù)據(jù)的一致性。這里要引入數(shù)據(jù)核對(duì)齐饮,用來(lái)解決以下兩方面的問(wèn)題捐寥。

數(shù)據(jù)在業(yè)務(wù)邏輯上一致:這個(gè)保障業(yè)務(wù)是對(duì)的;

主從服務(wù)器之間的數(shù)據(jù)一致:這個(gè)保障從服務(wù)器的數(shù)據(jù)是安全的祖驱、可切的握恳。

業(yè)務(wù)邏輯核對(duì)由業(yè)務(wù)的同學(xué)負(fù)責(zé)編寫, 從整個(gè)業(yè)務(wù)邏輯調(diào)度看賬平不平捺僻。例如“今天庫(kù)存的消耗”是否等于“訂單明細(xì)表中的總和”乡洼,“在途快遞” + “已收快遞”是否等于“已下快遞總和”∝芭鳎總之束昵,這是個(gè)業(yè)務(wù)邏輯,用于對(duì)賬葛峻。

主從服務(wù)器之間的核對(duì)锹雏,是由數(shù)據(jù)庫(kù)團(tuán)隊(duì)負(fù)責(zé)的。需要額外寫一個(gè)主從核對(duì)服務(wù)术奖,用于保障主從數(shù)據(jù)的一致性礁遵。這個(gè)核對(duì)不依賴復(fù)制本身,也是一種邏輯核對(duì)采记。思路是:將最近一段時(shí)間內(nèi)主服務(wù)器上變更過(guò)的記錄與從服務(wù)器核對(duì)佣耐,從邏輯上驗(yàn)證是否一致。其實(shí)現(xiàn)如圖所示:

那么現(xiàn)在的難題是:如何判斷最近一段時(shí)間內(nèi)主服務(wù)器上變更過(guò)的記錄唧龄?這里有兩種思路:

1) 表結(jié)構(gòu)設(shè)計(jì)規(guī)范中兼砖,有講過(guò)每張表有一個(gè) last_modify_date,用于記錄每條記錄的最后修改時(shí)間,按照這個(gè)條件過(guò)濾就能查出最近更新的記錄掖鱼,然后每條記錄比較即可然走。

2) 核對(duì)服務(wù)掃描最近的二進(jìn)制日志,篩選出最近更新過(guò)記錄的表和主鍵戏挡,然后核對(duì)數(shù)據(jù)芍瑞。這種的實(shí)現(xiàn)難度會(huì)更大一些,但是不要求在數(shù)據(jù)庫(kù)上進(jìn)行查詢褐墅。

如果在核對(duì)過(guò)程中拆檬,記錄又在主上發(fā)生了變化,但是還沒有同步到從機(jī)妥凳,我們可以加入復(fù)核邏輯竟贯,按理來(lái)說(shuō)多復(fù)核幾次,主從數(shù)據(jù)應(yīng)該就一致了逝钥。如果復(fù)核多次不一致屑那,那么大概率,主從數(shù)據(jù)就已經(jīng)是不一致的了艘款。

核對(duì)服務(wù)的邏輯比較簡(jiǎn)單持际,但是要實(shí)現(xiàn)線上業(yè)務(wù)的數(shù)據(jù)核對(duì),開發(fā)上還是有一些挑戰(zhàn)哗咆,但這不就是我們 DBA 的價(jià)值所在嗎蜘欲?

總結(jié)

小編沐子總結(jié)了數(shù)據(jù)庫(kù)高可用的架構(gòu)設(shè)計(jì),內(nèi)容非常干貨晌柬,建議你反復(fù)閱讀姥份,其中涉及的內(nèi)容在原理上并不復(fù)雜,但在實(shí)現(xiàn)細(xì)節(jié)上需要不斷打磨年碘,歡迎你在后續(xù)的架構(gòu)設(shè)計(jì)過(guò)程中與我交流澈歉,總結(jié)來(lái)說(shuō):

1. 核心業(yè)務(wù)復(fù)制務(wù)必為無(wú)損半同步復(fù)制;

2. 同城容災(zāi)使用三園區(qū)架構(gòu)屿衅,一地三中心埃难,或者兩地三中心,機(jī)房見網(wǎng)絡(luò)延遲不超過(guò)5ms傲诵;

3. 跨城容災(zāi)使用"三地五中心"凯砍,跨城機(jī)房距離超過(guò)200KM箱硕,延遲超過(guò)25ms拴竹;

4. 跨城容災(zāi)架構(gòu)由于網(wǎng)絡(luò)耗時(shí)高,因此一般僅用于讀多寫少的業(yè)務(wù)剧罩,例如用戶中心栓拜;

5. 除了復(fù)制進(jìn)行數(shù)據(jù)同步外,還需要額外的核對(duì)程序進(jìn)行邏輯核對(duì);

6. 數(shù)據(jù)庫(kù)層的邏輯核對(duì)幕与,可以使用last_modify_date字段挑势,取出最近修改的記錄。

最后啦鸣,小編提出一個(gè)思考題:對(duì)于跨城容災(zāi)潮饱,有什么優(yōu)化技術(shù)可以減少耗時(shí)增大帶來(lái)的性能影響呢?歡迎大家留言與小編交流诫给,一同探討和學(xué)習(xí)香拉。歡迎關(guān)注公眾號(hào)(微信搜索公眾號(hào):首席架構(gòu)師專欄),里面有許多技術(shù)干貨中狂,也有我對(duì)技術(shù)的思考和感悟凫碌,還有作為架構(gòu)師的驗(yàn)驗(yàn)分享;關(guān)注后回復(fù) 【面試題】胃榕,有我準(zhǔn)備的面試題盛险、架構(gòu)師大型項(xiàng)目實(shí)戰(zhàn)視頻等福利 , 小編會(huì)帶著你一起學(xué)習(xí)勋又、成長(zhǎng)苦掘,讓我們一起加油!4托础鸟蜡!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市挺邀,隨后出現(xiàn)的幾起案子揉忘,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摔竿,死亡現(xiàn)場(chǎng)離奇詭異矗漾,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)您朽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)换淆,“玉大人哗总,你說(shuō)我怎么就攤上這事”妒裕” “怎么了讯屈?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)县习。 經(jīng)常有香客問(wèn)我涮母,道長(zhǎng)谆趾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任叛本,我火速辦了婚禮沪蓬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘来候。我一直安慰自己跷叉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布营搅。 她就那樣靜靜地躺著性芬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪剧防。 梳的紋絲不亂的頭發(fā)上植锉,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音峭拘,去河邊找鬼俊庇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鸡挠,可吹牛的內(nèi)容都是我干的辉饱。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼拣展,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼彭沼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起备埃,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤姓惑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后按脚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體于毙,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年辅搬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唯沮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堪遂,死狀恐怖介蛉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情溶褪,我是刑警寧澤币旧,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站竿滨,受9級(jí)特大地震影響佳恬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜于游,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一毁葱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贰剥,春花似錦倾剿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至担忧,卻和暖如春芹缔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背瓶盛。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工最欠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惩猫。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓芝硬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親轧房。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拌阴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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