思路比結(jié)論重要,為什么比是什么重要,今天就花1分鐘,說下這里面架構(gòu)演進(jìn)的思路。畫外音:大家不想聽底層細(xì)節(jié),就不深入細(xì)節(jié)了。最早的數(shù)據(jù)庫都是單機(jī)的,其最大的痛點(diǎn)是啥?磁盤能力無法線性擴(kuò)展,內(nèi)存能力無法線性擴(kuò)展,計算能力無法線性擴(kuò)展。如今,喜歡創(chuàng)造概念的架構(gòu)師們,把這種架構(gòu)稱為“Shared Everything”架構(gòu)。
如上圖所示,DISK/MEM/CPU 都耦合在一個DBMS進(jìn)程內(nèi),必須部署在一臺服務(wù)器上,完全處于競爭態(tài),無法線性擴(kuò)展,并行處理較差。數(shù)據(jù)庫單機(jī)部署,就是典型的“Shared Everything”架構(gòu)。最容易想到的,就是把無狀態(tài)的邏輯計算部分,從DBMS進(jìn)程內(nèi)拆分出來,做成可擴(kuò)展的微服務(wù)集群,實(shí)現(xiàn)“計算與存儲分離”。
(1)CPU邏輯計算拆分出了獨(dú)立的進(jìn)程,可以集群部署,能夠線程擴(kuò)展;(2)DISK/MEM 仍耦合在一個進(jìn)程內(nèi),仍處于競爭態(tài),無法線性擴(kuò)展;Oracle Rac,就是典型的“Shared Disk”架構(gòu),核心思路是“計算與存儲分離”。存儲部分磁盤IO仍有集中的資源競爭,還有沒有進(jìn)一步的優(yōu)化空間呢?最容易想到的,就是把數(shù)據(jù)打散,分布到不同的數(shù)據(jù)庫實(shí)例上,每部分?jǐn)?shù)據(jù)享有單獨(dú)的資源。
(1)把整體數(shù)據(jù)存儲分為了N份,每份之間沒有交集;(2)每份數(shù)據(jù)的 DISK/MEM/CPU 都在一個DBMS進(jìn)程內(nèi),部署在一臺服務(wù)器上;(3)每份數(shù)據(jù)的資源之間的沒有競爭;沒錯,這就是“水平切分”,它是典型的”Shared Nothing”架構(gòu)。對 Shared Everything/Disk/Nothing 這些高大上的名詞,進(jìn)一步認(rèn)識了不?水平切分雖然是一種可擴(kuò)展架構(gòu),能夠?qū)崿F(xiàn)線性擴(kuò)展資源,但它會使得調(diào)用方失去數(shù)據(jù)的全局視野,使得調(diào)用方能力受限:(1)無法實(shí)現(xiàn)全局JOIN;(4)原訪問一次DBMS的操作,需要調(diào)用多次;并把一些原本屬于DBMS職責(zé)的工作,轉(zhuǎn)嫁到調(diào)用方。如何解決“線性擴(kuò)展能力”,同時又解決“失去全局視野”與“調(diào)用方能力受限”的問題呢?最容易想到的方案是,數(shù)據(jù)庫主從集群,每份數(shù)據(jù)都進(jìn)行復(fù)制,每個實(shí)例都獨(dú)享 DISK/MEM/CPU 資源,避免實(shí)例之間的資源競爭。
(1)把整體數(shù)據(jù)存儲分復(fù)制了N份,每份之間數(shù)據(jù)都一樣;(2)每份數(shù)據(jù)的 DISK/MEM/CPU 都在一個DBMS進(jìn)程內(nèi),部署在一臺服務(wù)器上;(3)每份數(shù)據(jù)的資源之間的沒有競爭;理想很豐滿,現(xiàn)實(shí)很骨干,思路沒問題,但實(shí)際執(zhí)行“復(fù)制”的過程中,會碰到一些問題。第一種,異步復(fù)制(Asynchronous Replication)又叫主從復(fù)制(Primary-Secondary Replication),是互聯(lián)網(wǎng)公司用的最多的數(shù)據(jù)復(fù)制與數(shù)據(jù)庫集群化方法,它的思路是,從庫執(zhí)行串行化后的主庫事務(wù)。
- 生成自己的binlog(還可以繼續(xù)二級從庫)是并行執(zhí)行的,主庫并不能保證從庫的事務(wù)一定執(zhí)行成功,甚至不能保證從庫一定收到相關(guān)的請求,這也是其稱作“異步復(fù)制”的原因。第二種,半同步復(fù)制(Semi-synchronous Replication)為了解決異步復(fù)制中“不能保證從庫一定收到請求”等問題,對異步復(fù)制做了升級。
- 等從庫確認(rèn)收到請求,主庫事務(wù)才提交完成 - 執(zhí)行和主庫一樣的事務(wù),并給主庫一個確認(rèn) - 生成自己的binlog(還可以繼續(xù)二級從庫)(2)從庫收到請求后,事務(wù)提交前,會給主庫一個ACK;(1)主庫的性能,會受到較大的影響,事務(wù)提交之前,中間至少要等待2個主從之間的網(wǎng)絡(luò)TTL;(2)從庫仍然有延時,主從之間數(shù)據(jù)仍然不一致;(3)主從角色有差異,主節(jié)點(diǎn)仍然是單點(diǎn);大數(shù)據(jù)量,高并發(fā)量的互聯(lián)網(wǎng)業(yè)務(wù),一般不使用“半同步復(fù)制”,更多的公司仍然使用“異步復(fù)制”的模式。最后是MySQL5.7里,新提出的MySQL組復(fù)制。第三種,組復(fù)制(MySQL Group Replication,MGR)(1)解決了單點(diǎn)寫入的問題,一個分組內(nèi)的所有節(jié)點(diǎn)都能夠?qū)懭?/span>;(2)最終一致性,緩解了一致性問題,可以認(rèn)為大部分實(shí)例的數(shù)據(jù)都是最新的;(3)高可用,系統(tǒng)故障時(即使是腦裂),系統(tǒng)依然可用;
(1)首先,分組內(nèi)的MySQL實(shí)例不再是“主從”關(guān)系,而是對等的“成員”關(guān)系,故每個節(jié)點(diǎn)都可以寫入;(2)其次,增加了一個協(xié)商共識的認(rèn)證(certify)環(huán)節(jié),多數(shù)節(jié)點(diǎn)達(dá)成一致的事務(wù)才能提交;和MySQL傳統(tǒng)的復(fù)制不同,MGR的核心是分布式共識算法,類似于Paxos。不知不覺寫了幾千字了,收個尾做個總結(jié)吧。Shared Everything:數(shù)據(jù)庫單機(jī)系統(tǒng),資源競爭;Shared Disk:Oracle Rac,計算與存儲分離;Shared Nothing:水平切分,復(fù)制集群,資源完全隔離;異步復(fù)制:傳統(tǒng)主從,互聯(lián)網(wǎng)公司最常用;半同步復(fù)制:從庫確認(rèn),主庫才提交;組復(fù)制:MySQL 5.7的新功能,核心在于分布式共識算法;《緩沖池(buffer pool),這次徹底懂了!》
《寫緩沖(change buffer),這次徹底懂了!》
《日志緩沖(log buffer),這次徹底懂了!》
《double write buffer,這次徹底懂了!》
《關(guān)于MySQL,這篇都沒人贊?》
Galera/MGR內(nèi)核,后續(xù)還要寫嗎?