數據庫的高可用是指最大程度地為用戶提供服務,避免服務器宕機等故障帶來的服務中斷。數據庫的高可用性不僅僅體現在數據庫能否持續提供服務,而且也體現在能否保證數據的一致性。
SequoiaDB 巨杉數據庫作為一款100%兼容 MySQL 的國產開源分布式數據庫,它在高可用方面的表現如何?它的高可用性是如何實現的?本文將詳細描述SequoiaDB巨杉數據庫的高可用性原理,並進行測試驗證。
01 巨杉分布式集群架構SequoiaDB 巨杉數據庫采用計算與存儲分離架構,SequoiaSQL-MySQL 是 SQL 計算層,存儲層由協調節點、編目節點和數據節點組成。
圖1 SequoiaDB分布式架構
如圖1所示是最簡單的 SequoiaDB 分布式數據庫集群架構圖,由1個協調節點,1個編目節點,3個數據節點和 SequoiaSQL-MySQL 構成。其中數據節點在三個服務器上,包括三個數據復制組1、2、3,每個數據復制組由3個完全相同的數據副本組成,數據副本之間通過日志同步保持數據一致。
A, A1, A2組成數據復制組1,三者是完全相同數據副本。數據復制組2、3類似於數據復制組1。在 SequoiaDB 分布式集群中,每個復制組最多支持 7 個數據副本。
本文的高可用測試環境采用圖1所示的分布式集群架構,其中主節點有讀寫功能,兩個備副本可以執行讀操作或備份。
02 巨杉數據庫高可用實現SequoiaDB 高可用采用 Raft 算法實現,多副本之間通過日志同步保持數據一致性。
圖2 三個節點之間保持連接
如圖2所示,SequoiaDB 集群三個副本之間通過心跳保持連接。
數據組副本之間通過共享心跳信息 sharing-beat 進行狀態共享。如圖3所示,sharing-beat 心跳信息結構包括心跳 ID、自身開始LSN、自身終止LSN、時間戳、數據組版本號、自身當前的角色和同步狀態。
圖3 心跳狀態信息結構
每個節點都維護一張 status-sharing table 表,用來記錄節點狀態。sharing-beat 每2秒發送一次,采集應答信息,若連續N秒未收到應答信息,則認為節點宕機。
集群中只有一個節點作為主節點,其他節點為備節點。如果出現多主或者雙主,需要根據 LSN 對比進行降備,保證集群中只有一個主節點。
Note:1)當主節點宕機時,需要從備節點中選舉出一個新的節點作為新的主節點。 2)當備節點宕機時,主節點不受影響,等備節點恢復后,通過日志同步繼續與主節點保持數據一致即可。
下面介紹當主節點宕機時,選舉新主節點的過程。選舉條件滿足下面2個條件可以被選舉成為主節點:1. 多數備節點投票通過2. 該節點LSN最大
選舉過程1)當主節點A宕機時,A自動降為備節點,關閉協調節點的業務連接。
圖4 集群中主節點掛掉
2)A1和A2都會判斷自身是否具備升為主節點的條件,若符合即發起選舉請求。條件內容:
-
自己不是主節點
-
剩下的備節點占半數以上
-
自己的LSN比其它備節點的LSN新
3)其它備節點會把被投票節點的 LSN 與自己的 LSN 做對比,若比自己的 LSN 新,則投贊成票,否則投反對票。4)若贊成票超過(n/2+1),則支持該節點為主節點,選舉成功。否則保持備節點角色,選舉失敗。5)選舉成功后,通過心跳狀態信息共享數據組信息給其它節點。
03 高可用容災驗證一般分布式數據庫 POC 測試包含功能測試、性能測試、分布式事務測試、高可用容災測試和兼容性測試等。下面將對 SequoiaDB 巨杉數據庫的高可用性進行驗證測試。
測試環境說明
本文測試環境采用分布式集群,包含1個 SequoiaSQL-MySQL,3個數據節點,1個編目節點,1個協調節點,搭建集群方式具體可參考巨杉官網虛擬機鏡像搭建教程。在 kill 掉主節點進程之后,我們對分布式數據庫集群進行讀寫操作,來驗證高可用性。
-
查看服務器集群狀態
# service sdbcm status ..... Main PID: 803 (sdbcm) Tasks: 205 (limit: 2319) CGroup: /system.slice/sdbcm.service ├─ 779 sdbcmd ├─ 803 sdbcm(11790) ├─1166 sequoiadb(11840) D ├─1169 sequoiadb(11810) S ├─1172 sequoiadb(11830) D ├─1175 sdbom(11780) ├─1178 sequoiadb(11820) D ├─1181 sequoiadb(11800) C 1369 /opt/sequoiadb/plugins/SequoiaSQL/bin/../../../java/jdk/bin/java -jar /opt/sequoiadb/plugins/SequoiaSQL .....
-
SequoiaDB 分布式集群中數據節點端口在11820,11830,11840;編目節點11800,協調節點在11810
sdbadmin@sequoiadb:~$ ps -ef|grep sequoiadb sdbadmin 1166 1 0 Aug20 ? 00:02:23 sequoiadb(11840) D sdbadmin 1169 1 0 Aug20 ? 00:01:43 sequoiadb(11810) S sdbadmin 1172 1 0 Aug20 ? 00:02:24 sequoiadb(11830) D sdbadmin 1178 1 0 Aug20 ? 00:02:33 sequoiadb(11820) D sdbadmin 1181 1 0 Aug20 ? 00:04:01 sequoiadb(11800) C
-
kill 掉11820的主節點,執行查詢和寫入sql
sdbadmin@sequoiadb:~$ kill 1178 sdbadmin@sequoiadb:~$ ps -ef|grep sequoiadb sdbadmin 1166 1 0 Aug20 ? 00:02:24 sequoiadb(11840) D sdbadmin 1169 1 0 Aug20 ? 00:01:43 sequoiadb(11810) S sdbadmin 1172 1 0 Aug20 ? 00:02:24 sequoiadb(11830) D sdbadmin 1181 1 0 Aug20 ? 00:04:01 sequoiadb(11800) C sdbadmin 1369 1 0 Aug20 ? 00:01:33 /opt/sequoiadb ....
-
執行查看 sql,查看插入操作之前數據為121
mysql> select * from news.user_info; +------+-----------+ | id | unickname | +------+-----------+ | 1 | test1 | ........ | 119 | test119 | | 120 | test120 | | 121 | test121 | +------+-----------+ 121 rows in set (0.01 sec)
-
執行寫入 sql,查看插入是否成功
mysql> insert into news.user_info(id,unickname)values(122,"s uccess"); Query OK, 1 row affected (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.01 sec) mysql> select * from news.user_info; +------+-----------+ | id | unickname | +------+-----------+ | 1 | test1 | ......... | 120 | test120 | | 121 | test121 | | 122 | success | +------+-----------+ 122 rows in set (0.00 sec)
數據(122, “success”)數據插入成功,在其中一個主節點掛掉情況下,讀寫都沒有受到影響,數據讀寫保持一致,高可用性得到驗證。
現在執行導入1000w數據寫入腳本 imprt.sh,在執行過程中 kill 掉主數據節點,模擬主節點故障場景,在巨杉數據庫圖形化監控界面 SAC 上查看集群讀寫變化。
Note: 如果需要獲取 imprt.sh 腳本,關注“巨杉數據庫”公眾號回復 “imprt” 即可獲取。
-
執行導入數據腳本
./imprt.sh 協調節點主機 協調節點端⼝ 次數
./imprt.sh 192.168.1.122 11810 100
-
如圖5所示,在執行導入數據時刻,kill 掉主數據節點,insert 寫入下降,之后集群恢復高可用
圖5 SAC監控界面集群讀寫變化示意圖
圖6 SAC查看tpcc寫入數據量示意圖
從 SAC 可視化界面中可以看到,當主數據節點在我們執行插入1000w數據操作的過程中出現故障,數據讀寫受到影響的持續時間很短。最后通過使用 imprt.sh 腳本重新導入插入失敗的數據,則可以保證數據最終一致性。
04 總結SequoiaDB
分布式集群具備較好的高可用性,集群可以設置多個數據復制組,每個數據復制組由多個完全相同的副本構成,副本之間通過 Raft 算法和日志同步方式保持數據一致性。最后,本文也驗證了在執行千萬級數據寫操作時,若集群主數據節點宕機,分布式集群可以正常讀寫數據,並且數據保持最終一致,高可用性得到驗證。