高併發,高效能,高可用MySQL 實戰-搭建三高架構的基礎-如何實現資料冗餘
1. 三高架構之路
- 什麼是三高
- 高併發:同一時刻能處理的事務數高
- 高效能:事務/sql執行速度高
- 高可用:系統可用時間高
- 如何達到三高
複製---擴充套件---切換
2. 複製有哪些型別
-
複製的基本原理
主從複製用四個字概括就是:binlog 傳送 -
複製的型別:
-
非同步複製
非同步複製原理簡單,網路延遲較小,不能保證日誌被傳送到了備庫,有可能資料丟失 -
半同步複製
半同步複製原理簡單,但是對網路延遲有一定要求,最好在同一個機房,可以保證日誌被傳送到了備庫,不易丟失資料
rpl_semi_sync_master_timeout 引數可以調整脫扣時間,也就是說如果從庫一直不返回ACD給主庫,主庫就不等了,直接返回 -
組複製
組複製原理比較複雜,需要依賴共識演算法,實際應用較少,是資料庫走向原生分散式的示範
- 總結:
按照同步型別可以分為:非同步複製、半同步複製、組複製
半同步複製是兼顧資料安全與效率的較好選擇
組複製雖然使用較少,是newsql資料庫的前奏
主從複製配置實戰
-
/etc/mysql/my.cnf 主庫
log-bin=/var/lib/mysql/mysql-bin
server-id=123454 -
/etc/mysql/my.cnf 從庫
log-bin=/var/lib/mysql/mysql-bin
server-id=111111 -
主庫全域性上鎖
flush tables with read lock; -
檢視主庫binlog狀態
show master status\G -
備份主庫
mysqldump -h xxxx -P 33306 -u root --all-databases --master-data > dbdump.sql -p -
將備份檔案複製到從庫
cp ../mysql8/dbdump.sql . -
釋放主庫鎖
unlock tables; -
進入從庫msyql客戶端,匯入備份檔案
source dbdump.sql; -
檢視從庫狀態
show slave status\G -
修改從庫對應的主庫
change master to master_host="xxxx", master_user="root", master_log_file="mysql-bin.000001", master_log_pos=156; -
開啟從庫
start slave; -
停止從庫、重置從庫
stop slave;
reset slave; -
重新配置從庫對應的主庫,需要輸入埠號和密碼
change master to master_host="4xxxxxxx", master_port=xxxx, master_user="root", master_password='xxxx', master_log_file="mysql-bin.000001", master_log_pos=156; -
向主庫插入一條資料,從庫也跟著有了
主庫和從庫的狀態是一致的
show master status;
show slave status;
預設主從採用的非同步複製
-
如何使用半同步複製,主要在主和從配置檔案中加入三行
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 -
檢視主從脫庫時間(只有半同步複製才有這個時間,非同步複製沒有的)
show variables like "rpl_semi_sync_master_timeout"; -
檢視正在做的執行緒
show processlist\G
到此主從複製完成了。
怎麼使得配置的複製更方便
-
主庫和從庫配置中都開啟GTID配置
gtid_mode=on
enforce_gtid_consistency=on -
重啟主庫和從庫
sudo docker-compose restart -
停止從庫
stop slave; -
使用GTID進行主從複製
change master to master_host="xxxxx", master_port=33306, master_user="root", master_password='xxxxx.', master_auto_position=1; -
開啟從庫
start slave;
GTID主從複製完成,向主庫中插入一條資料試試吧。
- 總結:
- GTID可以給事務分配全域性唯一ID
- GTID方便了主從複製的配置,推薦開啟
- GTID對主從切換,故障恢復也有很大的意義
為什麼binlog格式會影響複製
- 設定從庫只讀選項,只需要在從庫的配置檔案中加入
innodb_read_only=1
read_only=1
super_read_only=1
transaction_read_only=1
- statement格式的binlog
- 5.0之前的mysql預設使用了statement格式的binlog
- binlog記錄的是sql語句原文
- 由於主備庫對sql語句的執行不一致,可能有資料安全風險
- row格式的binlog
- 不記錄sql語句原文
- 記錄資料行的變化
- 不是物理日誌,還是邏輯日誌
- 佔用空間較大
- 檢視binlog中記錄的是啥東西
show master status\G
show binlog events in "mysql-bin.000003"\G
- mixed格式的binlog
- 兩種格式混合使用
- 有資料風險的語句使用ROW
- 無風險的使用statement
- 基於語句或行的複製
- 基於語句的複製-statement
- 基於行的複製=row
- 總結:
- statement格式記錄了實際執行的sql語句
- row格式按照整行記錄了資料的變化
- 推薦直接使用row格式的binlog
備庫延遲太大怎麼辦
-
為什麼會有延遲呢
即使是半同步複製,主庫dump_thread等待binlog傳送給從庫io_thread之後是寫入到了中繼日誌,並沒有落盤到binlog日誌
sql_thread將中繼日誌複製到binlog也是需要時間的, -
備庫延遲的原因
- binlog傳送開銷較小,主要是重放relay log耗時
- 備庫效能不如主庫
- 備庫承擔了很多分析SQL
- 主庫的長事務未提交
- 處理方法
- 主備使用相同配置的機器
- 備庫關閉log實時落盤
- 增加從庫數量,應對分析sql
- binlog傳送至大資料系統供分析
- 大事務-分多
- 依然存在問題
- 備庫對硬體資源利用天然不如主庫
- 備庫單執行緒執行,主庫是多執行緒執行
- 總結:
- 備庫延遲的主要原因是備庫執行慢(主庫binlog傳送至備庫relay log快,但是備庫重放relay log到備庫的binlog慢)
- 提升效能,升級備庫應將,關閉Log實時落盤
- 減少負擔:增加數量,使用其它元件
- 依然存在備庫單執行緒的問題
-
多執行緒寫binlog,單執行緒重放relay log,解決辦法-多執行緒重放relay log
-
並行複製的思路
-
mysql5.6並行複製
- mysql5.6使用按庫並行的策略
- 優點:分發選擇快,支援各種log格式(statement、row)
- 缺點:庫粒度太大,很難負載平衡
// 從庫配置 - slave-parallel-type = DATABASE
- mysql5.7使用按事務組並行的策略
- binlog刷盤其實是兩步動作
- 先把binlog從binlog cache中寫到記憶體的binlog檔案
- 呼叫fsync持久化到磁碟
-
事務組圖譜
-
使用事務組並行的策略
- binlog_group_commit_sync_delay: 延遲多少微秒後才呼叫fsync
- binlog_group_commit_sync_no_delay_count: 累計多少次後才呼叫fsync
- 兩個條件是或的關係
- mysql5.7使用了按事務組並行的策略
- mysql5.7使用按事務組並行的策略
- 同時處於prepare狀態的事務,在備庫執行是可以並行的
// 備庫開啟並行 - slave-parallel-type = LOGICAL_CLOCK
- mysql5.7.22並行複製
- binlog-transaction-dependency-tracking引數:
- COMMIT_ORDER: 按事務組並行(5.7)
- WRITESET: 沒有修改相同行的事務可以並行
- WRITESET_SESSION: 同一個執行緒先後執行的兩個事務不能並行
- 總結:
- 備庫延遲的根本原因是主庫多執行緒,備庫單執行緒
- 並行複製思路:按表複製、按行復制
- 5.7借鑑了事務組的思想,將同一個事務組的relay log並行
- 5.7.22引入了沒有修改相同行的事務並行的方法
- 推薦使用5.7事務組並行的方法
如何在備庫讀到最新資料
- 如何判斷備庫已經追上
- 強制延時
- seconds_behind_master=0
- 對比binlog執行位點
- 對比GTID執行情況
- 備庫延遲理論上無法消滅
- binlog傳送、中繼日誌重放需要時間
- 理論上,備庫延遲只能減小無法消滅
- 在備庫讀取資料時,永遠面臨資料延遲問題
- 判斷具體的事務是否已經重放
- 等待binlog位點
- select master_pos_wait(file, pos[, timeout]); 預設是阻塞的,重放好了就解堵塞
- 等待GTID(5.7.6之後可以返回每次的GTID),select wait_for_executed_gtid_set(gtid_set, 1);
- 總結:
- 可以通過對比執行位點的方法判斷從庫延時
- 從庫延時可能無法消滅
- 可以通過具體的某一個binlog位點是否已經執行,和某一個GTID是否執行的方法來等待從庫更新成跟主庫一致的狀態
怎麼樣實現最簡單的高可用架構
- 主主複製架構
- 兩個節點均為master
- 兩個節點互為slave
- 一個節點出現故障時無須切換
- 主主架構實現就簡單了
前面主從已經實現了,現在讓主也去跟蹤從,就變成了主主
在主伺服器上執行
show slave status\G
stop slave;
change master to master_host="xxxx", master_port=33307, master_user="root", master_password="xxxx", master_auto_position=1;
start slave;
show slave status\G
主主架構完成,在兩臺伺服器上新增修改資料試試吧。
- 主主架構的問題
- 資料衝突問題
兩邊插入相同ID時,就會出現衝突
兩邊約定好插入相同ID
只寫一個主,另一個只讀
有切換過快的資料丟失問題 - 客戶端切換
應用自己切換比較麻煩
使用keepalived等手段可以完成自動切換 - 迴圈複製
理論有此問題
未開GTID,使用serverID過濾
GTID天然避免
- 總結
- 主主架構是最簡單的高可用架構
- 存在資料衝突,客戶端切換不便等問題
本章小結
- 複製有哪些型別
- 按照同步型別可分為:非同步、半同步、組複製
- 半同步複製是資料安全與效率的較好選擇
- GTID(global transaction identifier)
- GTID可以給事務分配全域性唯一ID
- GTID方便了主從複製的配置,推薦開啟
- GTID對主從切換,故障恢復也有很大的意義
- binlog格式
- statement格式記錄了實際執行的sql語句
- row格式按照整行記錄了資料的變化
- 推薦直接使用row格式 (row格式雖然佔用的資料空間大,但是一致性方面是更好的)
- 備庫延遲
- 提升效能:設計本庫硬體,關閉log實時刷盤
- 減少負擔:增加數量,使用其它元件
- 並行複製
- 並行複製
- 備庫延遲的根本原因是主庫多執行緒,備庫單執行緒
- 並行複製思路:按表複製,按行復制
- 按事務組複製,將同一個事務組的relay log並行
- 判斷主備同步情況
- 可以通過對比執行位點的方法判斷從庫延時
- 從庫延時可能無法取消
- 可以通過binlog位點和GTID等待方法等待具體事務
- 主主複製架構
- 主主架構是最簡單的高可用架構
- 存在資料衝突、客戶端切換不便等問題