80后聊架構:必知必會,三類數(shù)據(jù)庫高可用與一致性架構實踐
上一篇《數(shù)據(jù)庫擴展性架構實踐》聊的是數(shù)據(jù)庫架構設計中的scalability實踐,并沒有解決availability與consistency的問題。
數(shù)據(jù)庫架構設計的過程中,如何折衷高可用與一致性的問題呢?
前面的文章聊過,高可用的核心方法論是:冗余(replication) + 故障自動轉移(fail-over)。
最容易想到的,是數(shù)據(jù)庫主從集群,每份數(shù)據(jù)都進行復制,每個實例都獨享 DISK/MEM/CPU 資源,避免實例之間的資源競爭。
如上圖所示:
- 把整體數(shù)據(jù)存儲分復制了N份,每份之間數(shù)據(jù)都一樣;
- 每份數(shù)據(jù)的 DISK/MEM/CPU 都在一個DBMS進程內(nèi),部署在一臺服務器上;
- 每份數(shù)據(jù)的資源之間的沒有競爭;
理想很豐滿,現(xiàn)實很骨感,思路沒問題,但實際執(zhí)行“復制”的過程中,會碰到一些問題。
以MySQL為例,有3種常見的復制方式:
- 異步復制;
- 半同步復制;
- 組復制;
第一種,異步復制(Asynchronous Replication)
又叫主從復制(Primary-Secondary Replication),是互聯(lián)網(wǎng)公司用的最多的數(shù)據(jù)復制與數(shù)據(jù)庫集群化方法,它的思路是,從庫執(zhí)行串行化后的主庫事務。
其核心原理如上圖所示:
(1) 第一條時間線:主庫時間線;
- 主庫執(zhí)行事務
- 主庫事務串行化binlog
- binlog同步給從庫
- 主庫事務提交完成
(2) 第二條/第三條時間線:從庫時間線;
- 收到relay log
- 執(zhí)行和主庫一樣的事務
- 生成自己的binlog(還可以繼續(xù)二級從庫)
- 從庫事務提交完成
從這個時間線可以看到:
- 主庫事務提交;
- 從庫事務執(zhí)行;
是并行執(zhí)行的,主庫并不能保證從庫的事務一定執(zhí)行成功,甚至不能保證從庫一定收到相關的請求,這也是其稱作“異步復制”的原因。
第二種,半同步復制(Semi-synchronous Replication)
為了解決異步復制中“不能保證從庫一定收到請求”等問題,對異步復制做了升級。
其核心原理如上圖所示:
(1) 第一條時間線:主庫時間線;
- 主庫執(zhí)行事務
- 主庫事務串行化binlog
- binlog同步給從庫
- 等從庫確認收到請求,主庫事務才提交完成
(2) 第二條/第三條時間線:從庫時間線;
- 收到relay log
- 執(zhí)行和主庫一樣的事務,并給主庫一個確認
- 生成自己的binlog(還可以繼續(xù)二級從庫)
- 從庫事務提交完成
從這個時間線可以看到:
- 主庫收到從庫的ACK,才會提交;
- 從庫收到請求后,事務提交前,會給主庫一個ACK;
半同步復制存在什么問題呢?
- 主庫的性能,會受到較大的影響,事務提交之前,中間至少要等待2個主從之間的網(wǎng)絡TTL;
- 從庫仍然有延時,主從之間數(shù)據(jù)仍然不一致;
- 主從角色有差異,主節(jié)點仍然是單點;
大數(shù)據(jù)量,高并發(fā)量的互聯(lián)網(wǎng)業(yè)務,一般不使用“半同步復制”,更多的公司仍然使用“異步復制”的模式。
最后是MySQL5.7里,新提出的MySQL組復制。
第三種,組復制(MySQL Group Replication,MGR)
MGR有一些帥氣的能力:
- 解決了單點寫入的問題,一個分組內(nèi)的所有節(jié)點都能夠寫入;
- 最終一致性,緩解了一致性問題,可以認為大部分實例的數(shù)據(jù)都是最新的;
- 高可用,系統(tǒng)故障時(即使是腦裂),系統(tǒng)依然可用;
如上圖所示:
- 首先,分組內(nèi)的MySQL實例不再是“主從”關系,而是對等的“成員”關系,故每個節(jié)點都可以寫入;
- 其次,增加了一個協(xié)商共識的認證(certify)環(huán)節(jié),多數(shù)節(jié)點達成一致的事務才能提交;
畫外音:Garela也是此類機制。
結尾稍作總結,為了折衷數(shù)據(jù)庫高可用,一致性,性能等架構設計要素,一般有三類常見復制方式:
- 異步復制,傳統(tǒng)主從,互聯(lián)網(wǎng)公司最常用;
- 半同步復制,從庫確認,主庫才提交;
- 組復制,MySQL 5.7的新功能,核心在于分布式共識算法;
知其然,知其所以然。
思路比結論更重要。