主要內容包含 MySQL 典型數據庫架構介紹、MySQL 主流數據庫架構對比等理論性知識,然后從“訂單、用戶”兩個項目實戰,拋磚引玉,介紹億級互聯網業務數據庫項目如何設計。

MySQL 典型數據庫架構
數據庫架構
我們想要更好地規划和設計 MySQL 數據庫架構,首先需要了解典型的數據庫架構,它通常由三部分組成:
-
數據庫[原生]架構
-
高可用組件
-
中間件

然而,數據庫架構又可以分為三大類:主從架構、集群架構和分布式架構。在主從架構類別中,又可以分 7 小類,分別是。
-
傳統主從復制,有時候也稱為:異步復制(希望大家再復習下 MySQL 中的各種存儲引擎,要注意它們的特性)。
-
基於 GTID 的主從復制,從 MySQL 5.6 版本后,推薦使用這種方式的復制,原因前面的課程中已經有講解。
-
主主復制,這個還有不少傳統企業仍在使用。
-
級連復制,面試的時候特別容易問到關於復制的各種變換,用的就是級連復制,注意技巧,工作中也經常用。
-
多源復制,MySQL 5.7 版本的一個特性,在某些特殊場景中會用到。
-
延遲復制,備份中會用到,尤其是當數據量特別大的情況。
-
半同步復制,對數據一致性要求比較高的業務場景,可以考慮用。
在集群架構類別中,又可以分為 6 小類,分別是:
-
MySQL Group Replication;
-
Percona XtraDB Cluster;
-
MySQL Galera Cluster;
-
MySQL NDB Cluster,有時候也稱為 MySQL Cluster;
-
MySQL + 共享存儲方案;
-
MySQL + DRBD 方案。
在分布式架構類別中,又可以分為 2 小類,分別是:
-
基於分布式事務的數據庫,如 Google Cloud Spanner 和 TiDB。
-
基於分布式存儲的數據庫,如極數雲舟的 ArkDB、Aurora、PolarDB。
數據庫高可用
在前面第 7 課時中,我們詳細介紹了幾種常用的 MySQL 數據庫高可用解決方案,這里再給大家羅列出來了,如果這里列的在前面的課程中沒有介紹到,大家可以自行去學習。主要有下面 6 種:
-
Keepalive、Heartbeat、Haproxy;
-
MMM;
-
MHA;
-
Orchestrator、Raft;
-
極數雲舟的 Arksentinel;
-
Zookeeper、Consul、Etcd。
數據庫中間件
關於數據庫中間件,第 9 課時中有詳細介紹,這里不再贅述了。
在做架構設計時,一方面,要提醒大家的是:數據庫架構、數據庫高可用組件和數據庫中間件既可以獨立使用又可以彼此配合使用。另一方面,要提醒大家了解的是,我們常說的服務的可用性能達到多少個 9,那么它們各自允許服務宕機的具體時間又是多少呢?
-
一個 9(90%),全年 36 天。
-
兩個 9(99%),全年 3.65 天。
-
兩個 9.5(99.5%),全年 1.83 天。
-
三個 9(99.9%),全年 8.76 天。
-
四個 9(99.99%),全年 52.56 分鍾。
-
五個 9(99.999%),全年 5.26 分鍾。
-
六個 9(99.9999%),全年 31.5 秒。
主從架構
下面分別介紹 MySQL 的各種數據庫架構。

第一個是傳統主從復制,架構簡單,部署方便,注意配置必要的參數,如開啟 binlog、relay_log 和 server_id,學習其基本原理,了解常見的故障和處理方法。
第二個是基於 GTID 的主從復制,開啟的方法是設置 gtid_mode = ON 和 enforce_gtid_consistency = ON,要認真學習其原理和主從配置方式,以及故障處理的不同。

第三個是主主復制,這個主要是在前面兩種架構的基礎上的衍生,需要充分了解復制的基本原理。配置時,需要注意 auto_increment_increment、auto_increment_offset、log-slave-updates 三個參數的設置,互為主從的主庫 1 和主庫 2 的 auto_increment_increment 設置不同的值,比如分別設置為 1 和 2。

第四個是級連復制,其核心參數是 log-slave-updates,如圖中的從庫 A,必須要設置。要至少會實現在傳統主從復制和基於 GTID 復制下的主從架構變換,比如把圖中的從庫 B 掛到主庫上,實現 A-B-C 的級連為 A-B、A-C。
第五種是多源復制,多源復制在 MySQL 官方社區是從 5.7 版本開始有的,多源復制其實在MariaDB 中出現的時間要早。使用多源復制,一方面要注意其參數設置,另一方面要注意使用規范,如主從鏈接時的 change master 語句的不同。在參數設置時,需要在從庫中配置:
-
master-info-repository = table
-
relay-log-info-repository = table
-
replicate-do-db = master01
-
replicate-do-db = master02
-
replicate_wild_do_table = master01.%
-
replicate_wild_do_table = master02.%
在主從復制時,命令如下:
change master to ...... for channel 'master01'
change master to ...... for channel 'master02'
第六種是延遲復制,這是一種特殊的復制,常用於備份的場景,其目的是讓復制結構中的從庫允許延后多長時間(單位:秒)從主庫進行復制,這在數據量特別大時(如 TB 級),是很有用的。使用時有兩種實現方式,一種是設置 master_delay=1800,這個參數在較新的版本中才有。另一種是用 Percona 公司開發的 pt-slave-delay 工具實現。如果在生產環境中,有許多需要設置延遲復制的情況,建議用后者,方便集中統一管理。

第七種是半同步復制,這個是需要重點關注的,面試中被問的也是最多的,它是通過插件的方式工作在數據庫中,使用時,需要在主庫和從庫分別設置。
在主庫上:
-
plugin-load=rpl_semi_sync_master=semisync_master.so
-
rpl_semi_sync_master_enabled=1
-
rpl_semi_sync_master_timeout=1000
-
rpl_semi_sync_master_wait_point=AFTER_SYNC|AFTER_COMMIT
在從庫上:
-
plugin-load=rpl_semi_sync_slave=semisync_slave.so
-
rpl_semi_sync_slave_enabled=1

這里需要特別注意 AFTER_SYNC 和 AFTER_COMMIT 模式的區別,在 MySQL 5.7 版本以后,默認采用 AFTER_SYNC 模式,這種方式結合 MySQL 中“雙 1”設置,即sync_binlog = 1、innodb_flush_log_at_trx_commit = 1 配合使用的場景在交易系統或者對數據一致性要求比較高的場景中被推薦使用。
集群架構


下面開始介紹六種集群架構,其中 MGR、PXC 或 MGC 在前面的課程中有非常詳細的介紹,這里簡單帶過。首先是 MGR,即 MySQL Group Replication,是 MySQL 5.7 版本出現的新特性,是 MySQL 官方於 2016 年 12 月推出的一個全新的高可用與高擴展的解決方案。它提供了高可用、高擴展、高可靠的 MySQL 集群服務。MGR 分單主模式和多主模式。
-
在單主模式下, 組復制具有自動選主功能,每次只有一個 server 成員接受讀寫。
-
在多主模式下,所有的 server 成員都可以同時接受讀寫。
MGR 目前還處在穩定性驗證階段,在生產環境中使用時,建議使用單主模式。

第二種是 PXC,即 Percona XtraDB Cluster,從名稱中可以看出,這是 Percona 公司推出的一個高可用與高擴展的解決方案,它是以 codership 公司研發的 galera cluster 插件方式為 MySQL 提供高可用集群解決方案的,跟 PXC 類似的產品還有 MariaDB Cluster。特點是具有高可用性,方便擴展,並且可以實現多個 MySQL 節點間的數據同步復制與讀寫,可保障數據庫的服務高可用及數據強一致性。跟 MGR 一樣,也分單主模式和多主模式。

第三種是 MGC,即 MySQL Galera Cluster,這是 codership 公司開發的數據庫高可用插件,是一種新型的數據不共享的高度冗余的高可用方案,通常以 PXC 或 MariaDB Cluster 的方式使用,當然也可以獨立使用,就是自己配置。相比傳統的主從復制架構,Galera Cluster 解決的最核心問題是在三個實例節點之間,它們能以對等的,multi-master(多主)並存的方式存在,在多節點同時寫入的時候,能夠保證整個集群數據的一致性、完整性與正確性。具有支持多主架構、同步復制、並發復制、故障切換、熱插拔、自動節點克隆和對應用透明的特點。


第四種是 MNC,即 MySQL NDB Cluster,有時又稱為 MySQL Cluster,是 MySQL 官方推出的一個適用於分布式計算環境的高可用性、高冗余的 MySQL 集群解決方案。主要由使用 NDB 引擎的 SQL 節點、數據存儲節點和 NDB 管理節點三部分組成。NDB 是一個內存存儲引擎,提供高可用的數據持久化功能,可以配置故障轉移和負載均衡等策略,因其管理復雜,目前在國內除中國移動等個別公司在使用外,使用的相對比較少,國外使用的比較多,尤其是電信行業。

第五種是共享存儲方案,MySQL 主從數據庫共享同一份數據,但是在同一個集群中,只有一個庫提供讀寫服務,其他的庫提供只讀服務,其性能也受限於分布式共享存儲,在實際環境中基於 SAN 或 GlusterFS 的應用較多,但是前者成本昂貴,生產環境中使用的不多。

第六種是基於 DRBD 的方案,DRBD 的全稱是 Distributed ReplicatedBlock Device(分布式塊設備復制),是一個用軟件實現的、無共享的、服務器之間鏡像塊設備內容的存儲復制解決方案。它的功能實現是由 Linux 系統中的 DRBD 內核模塊和相關腳本構成的,用來構建存儲高可用集群。跟上面共享存儲方案有異曲同工之妙,只是實現方式有所不同。也是一寫多讀,生產中基本不用。
分布式架構

第一種是基於分布式事務的方案,以 TiDB 為例。

第二種是基於分布式存儲的方案,以 ArkDB 為例。
在第 9 課中已經詳細介紹了這兩種方案,這里不一一贅述了,大家對其有所了解即可。
MySQL 典型數據庫架構方案對比

前面簡單介紹了 MySQL 使用過程中存在的三大類共 15 種架構方案,這里整理歸納對其中 5 種典型架構進行對比,分別從部署配置、運維管理(易用性)、高可用、性能、復制延遲、多點寫入支持、數據一致性、擴展性、大數據量支持、性能比、跨雲支持等方面對比,僅一家之言,供參考。
億級互聯網業務數據庫設計

在進行數據庫架構設計之前,我們需要了解普適的數據庫技術選型,顯然這里沒有進行擴展,如果想要了解數據庫家族產品,可以回到開篇課了解更多內容。正所謂“工欲善其事,必先利其器”,“磨刀不誤砍柴工”,了解了各種技術,有利於進行設計時的有的放矢。企業中常用的有:
-
數據庫
-
MySQL
-
Oracle
-
SQL Server
-
DB2
-
MongoDB
-
PostgreSQL
-
ArkDB等
-
消息隊列
-
ActiveMQ
-
RabbitMQ
-
Kafka
-
RocketMQ
-
MemcacheQ等
-
搜索引擎
-
ES
-
Solr
-
Sphinx等
-
KV存儲
-
Pika
-
Aerospike等
-
緩存
-
Memcached
-
Redis
-
Codis等
-
數據同步ETL
-
Arkgate
-
Goldengate
-
go-mysql
-
DataX
-
Canal等
-
中間件
-
中間件在第9課中有詳細介紹

這里舉一個生產環境的多數據中心的業務架構拓撲例子,很具有典型性,在這個例子中有兩個本地機房和一個雲機房(可以理解為公有雲、行業雲或自建私有雲),我們着重關注一下業務后端資源(數據庫)的部署,這是一個單寫的多活的業務場景,顯然機房 1 為核心機房,所有的業務數據都從機房 1 寫入,大量的寫操作通過消息隊列異步更新到緩存和數據庫中,數據庫通過復制方式同步到其他兩個機房提供讀服務,每個機房有各自的緩存服務用於應對高並發的讀請求,緩存的更新是在本地的數據庫中,提供數據庫的最終一致性。當然,如果業務中不存在數據更新沖突的可能,也可以實現多寫的多活,比如外賣業務。對於一些特殊的業務場景,在三個數據中心中可以單獨實現一套隊列處理程序,從隊列中抽取數據進行協同處理,比如抽取訂單數據轉存到 ES 中用於查詢、大數據分析等操作。

這里聚焦在 MySQL 數據庫的兩地三中心的規划和使用中,如圖所示,在總部機房中,業務層通過中間代理層訪問后端的 MySQL 數據庫集群,這里說的 MySQL 的集群可以是前面介紹的任何一種 MySQL 集群。MySQL 集群的高可用通過分布式監控系統 Arksentinel 提供故障檢測和故障切換。其他三個機房也有着相同的部署方案,四個機房之間的數據流通是通過數據庫實時數據同步系統 Arkgate 來提供服務,完成數據在不同機房間的流通。
在一般的企業需求中,都是總部中心機房負責業務數據讀寫,而其他三個機房都是只讀,但是對於一些特殊的場景,數據不存在沖突的場景,是可以實現多機房寫入的,Arkgate 內部可以設置 ETL 沖突處理的邏輯,從而避免數據回環的產生。需要注意的是,在每個機房又可以有自己獨立的 MySQL 集群,處理邊緣業務或者一些特殊的業務,但是數據最終都要匯總和歸檔到總部中心機房進行持久化永久存儲。

在總部數據中心圖中,有一個組件是 Arkcontrol,它是一個數據庫自動化運維管理平台。試想一下,動輒數百個實例的數據庫或者是數百套數據庫集群的資源,如果用傳統的 Excel 方式手工管理,其工作量和維護成本有多高,一套可以管理多種數據庫資源的管理平台的重要性顯得格外重要,一方面可以破解企業內部復雜的數據庫管理流程,極大地提高工作效率,降低企業成本;另一方面還能規避生產過程中數據庫運維操作的安全性;再有就是可以快速構建起企業級數據庫全維度的管理體系,讓數據庫的運行更具感知性。這需要在日后的工作中逐步積累,持續迭代,擁有對類似平台的研發能力,也是對新時代 DBA 的考核要求,起碼要知道其實現原理。

具體到一個訂單業務場景中,比如:火車票、機票預定,大量用戶的訂單請求通過負載均衡分散路由到業務處理層 Server,業務處理層會先從預分配好的資源中進行分配,並做減庫存、生成訂單等系列操作,當某個 Server 的資源不足或分配完后,會從總庫存 Redis 中進行調取,這里的 Redis 提供統一的庫存管理,其目的是充分發揮 Redis 豐富的數據結構和高性能的特性。然后生產的訂單和訂單狀態等信息寫入消息隊列 MQ,訂單處理程序 OrderProc 接受並處理消息,分別存儲到 MySQL 和 ES 中,存儲到 MySQL 中是為了方便數據庫的持久化存儲,也會提供給 Server 做資源信息的查詢使用,比如對賬等。存儲到 ES 中,是為了方便用戶對訂單進行查詢,這里也包括對航班和車次、余票等信息的查詢。

具體到一個用戶業務場景中,比如微博粉絲、微信好友,大量的用戶信息,包括用戶注冊、用戶信息更新、好友綁定與解綁等信息的更新操作通過負載均衡分散路由到用戶信息處理模塊 Server 層,如果是用戶新注冊的話,會從 UUID Server 中請求分配一個新 UID 給這個用戶,這個 UID 是永久性的並且是全局唯一的,比如微信有十幾億用戶,那么就有十幾億對應的唯一 UID。然后各種大量復雜的請求通過消息隊列處理程序處理后,存儲到 Redis 和 MySQL 數據庫中,比如好友列表,粉絲列表、關注列表、黑名單等存儲在 Redis 中,MySQL 中存儲全量的用戶信息,包括用戶昵稱、用戶名、用戶圖像、用戶簽名等。在微博或微信的社交業務中,現在也應用在更廣泛的其他相關社交領域,有一種業務用戶的“二度關系” ,二度關系是指用戶與用戶通過關注者為橋梁發現到的關注者之間的關系。目前微博通過二度關系實現了潛在用戶的推薦。用戶的一度關系包含了關注、好友兩種類型,二度關系則得到關注的關注、關注的好友、好友的關注、好友的好友四種類型。這種典型業務有着巨大商業價值,故在各大社交領域大量使用,用戶的信息數據,可以通過一個 ETL 從 MySQL 數據庫中進行提取,存儲到 HBase 中或其他大數據集群中供機器學習使用,如圖中舉例的 Spark 進行分析使用,生成用戶畫像等。
重點總結回顧

