之前,有一年多的工作客戶端領域的工作經(jīng)驗贰镣。
后來呜象,也在字節(jié)做了一年多的后端業(yè)務。
現(xiàn)在希望做一些MySQL
總結碑隆,豐富一下自己在后端領域的積累恭陡。
目錄如下:
MySQL 基礎技術(一) —— MySQL 是如何查詢的?
MySQL 基礎技術(二) —— MySQL 是如何更新的上煤?
MySQL 基礎技術(三)—— MySQL 如何保證數(shù)據(jù)不丟失休玩?
MySQL 基礎技術(四)—— MySQL 如何保證高可用?
一、引子
上一篇文章哥捕,我們講述了:《MySQL 如何保證數(shù)據(jù)不丟失牧抽?》,介紹了 binlog
和 redo log
的工作流程遥赚。
那么扬舒,MySQL
怎么保證高可用呢?
為了提高 MySQL
的讀寫性能凫佛,我們往往采用 MySQL
一主多從的方案讲坎。
即一個主庫(主要負責寫),多個從庫(只負責讀)愧薛。
因為單實例有性能瓶頸晨炕,多從庫能優(yōu)先解決 MySQL
的讀負載壓力。
二毫炉、主從同步
原理:
將 MySQL
設計成一主多從模式瓮栗。
簡單來說,主要分為三步:
- 第一步:所有增刪改的
DML
語句都在master
節(jié)點的示例上完成瞄勾。 - 第二步:將處理完成的
binlog
日志傳輸?shù)礁鱾€slave
節(jié)點费奸。 - 第三步:多個
slave
節(jié)點處理binlog
,從而保持主從一致进陡。
詳細來說愿阐,
Master
與 Slave
之間會維護一個長連接,專門用來同步binlog
趾疚。
創(chuàng)建從庫的過程:
- 在
Slave
機器上缨历,通過change master
命令,設置主庫的 IP糙麦、端口號辛孵、用戶名、密碼赡磅,以及binlog
從哪里開始獲取等信息(具體binlog
文件名 + 文件偏移量)觉吭。 - 在
Slave
機器上,執(zhí)行start slave
命令仆邓,啟動io_thread
和sql_thread
線程。
其中io_thread
用于接收主庫的binlog
伴鳖,sql_thread
用于處理主庫的binlog
节值。 -
Slave
開始嘗試連接Master
,Master
校驗完用戶名密碼后榜聂,dump_thread
根據(jù)Slave
設置的binlog
文件和偏移量搞疗,開始讀取binlog
發(fā)送給Slave
。 -
Slave
的io_thread
將接收到的binlog
寫到relay log
(中轉日志)须肆。 -
sql_thread
讀取中轉日志匿乃,執(zhí)行對應SQL桩皿,同步完成。
問題:
1. 主從延遲
即“同步延遲”幢炸。
表示同一個事務下泄隔,主庫執(zhí)行完成到備庫執(zhí)行完成的時間差值。
時間線:
-
Master
執(zhí)行一個事務宛徊,成功寫入binlog
—— 這個時刻佛嬉,我們記為 T1。 -
Slave
的io_thread
接收到binlog
—— 這個時刻闸天,我們記為 T2暖呕。 -
Slave
執(zhí)行完這個事務“—— 這個時刻湾揽,我們記為 T3。
所謂主從延遲笼吟,就是 T3-T1 的時間库物。
如果在這段時間里,在從庫上查詢主庫剛插入/修改的數(shù)據(jù)赞厕,會出現(xiàn)主從不一致的現(xiàn)象艳狐。
這時,一些對可靠性要求比較高的業(yè)務場景里皿桑,就會出現(xiàn)錯誤毫目。
我們可以在從庫上執(zhí)行:
show slave status;
其中,seconds_behind_master
就是從庫延遲的時間(T3-T1)
主從延遲的根本原因是:從庫消費中轉日志(
relay log
)的速度比主庫生產(chǎn)binlog
的速度慢诲侮。
2. 主從切換
在實際場景下镀虐,可能會遇到主庫所在機器異常、掉電沟绪、或者機房升級等等刮便。
這就會涉及到“主庫”與“從庫”之間的切換問題。
由于主從延遲的存在绽慈,在主從切換的時候恨旱,就會有不同的策略。
可靠性優(yōu)先策略(推薦):
- 查詢
slave
的seconds_behind_master
坝疼,如果小于預定的某個值(比如3秒)搜贤,就下一步。
否則就一直輪訓钝凶,直到出現(xiàn)滿足條件的Slave
仪芒。(選未來主庫) - 將
master
的readonly = true
,降為從庫。 - 查詢該
slave
(未來主庫) 的seconds_behind_master
值變成 0掂名。(即無主從延遲) - 將該
slave
(未來主庫)的狀態(tài)變成讀寫据沈。readonly = false
,升成主庫饺蔑。 - 將請求流量切到新主庫锌介。
- 優(yōu)點:可靠性高,數(shù)據(jù)可靠膀钠。
- 缺點:會有一小段不可用的時間掏湾。
因此,得選擇
seconds_behond_master
比較短的slave
升master
肿嘲。
可用性優(yōu)先策略:
- 直接將
slave
(未來主庫)的狀態(tài)變成讀寫融击。readonly = false
,升成主庫雳窟。 - 將請求流量切到新主庫尊浪。
- 將老主庫的
readonly = true
,降為從庫封救。
- 優(yōu)點:可用性高拇涤,沒有真空期。
- 缺點:可能會出現(xiàn)數(shù)據(jù)不一致的情況誉结。
三鹅士、如何保證高可用
MySQL 如果要保證高可用,就要滿足三個條件惩坑。
- 數(shù)據(jù)不丟失掉盅。(雙1策略)
- 主從最終一致性。(主庫所有binlog以舒,備庫都執(zhí)行了)
- 無主從延遲趾痘。
主從延遲的來源:
1. Slave
所在機器性能問題。(部署在同一機器上)
我就遇到過這種 case:
我們的數(shù)據(jù)庫和飛書的數(shù)據(jù)庫部署在同一個機器上蔓钟,
他們在大量的做一些DML操作永票,刪除/歸檔很多老數(shù)據(jù)。
導致于我們的Slave資源被一直搶占滥沫,進而出現(xiàn)主從延遲侣集。
解決思路:
- 如果成本允許,按服務兰绣,分開獨立部署肚吏。
2. Slave 壓力大,查詢耗費了大量CPU資源狭魂,影響了同步速度。
這種也比較常見,表/索引設計不合理雌澄、或者有臨時任務在拖庫斋泄,導致慢慢查詢,耗費了大量CPU
資源镐牺。導致 io_thread
炫掐、sql_thread
搶占不到資源進而同步緩慢。
解決思路:
1.優(yōu)化表設計睬涧、索引設計募胃。解決慢 SQL 問題。
2.增加從庫畦浓,分擔現(xiàn)有從庫的壓力痹束。
3.對于一些臨時/定時任務:可用 Binlog -> Hadoop。轉移讓另外一個系統(tǒng)來提供查詢能力讶请。
3. 大事務
這種也比較好理解祷嘶,主庫上執(zhí)行一個大事務花了n分鐘,那么大概率就會導致從庫延遲n分鐘夺溢。
比如论巍,磁盤空間快滿了,需要歸檔一些歷史數(shù)據(jù)风响,需要一次性刪除大量歷史數(shù)據(jù)嘉汰。這時候和就會出現(xiàn)主從延遲。
解決思路:
1.業(yè)務允許的話状勤,控制每個事務的數(shù)據(jù)量鞋怀,分成多次操作。
參考與致謝:
1.《MySQL實戰(zhàn)45講》(林曉斌老師)