一種MySQL主從同步加速方案
一、問題起源
MySQL的主從同步一直有從庫延遲的問題,背景資料網上很多,原因簡單描述如下:
1、 MySQL從庫上有一個IO執行緒負責從主庫取binlog到寫到本地。另外有一個SQL執行緒負責執行這些本地日誌,實現命令重放;
2、 正常網路狀況下IO執行緒沒有效能問題(這個待會會用到),問題是SQL執行緒只有一個,更新速度跟不上。所以經常會看到從庫的CPU idle很高,但同步效能就是上不去。
二、方案雛形
單執行緒的SQL執行緒是造成這個問題的主要原因。比較直接的想法是把它改成多執行緒版本,這個據說官方版本開發中,其實我們也有一個這樣的patch,但是直接寫大片程式碼線上上提供服務的slave機器上這種事兒,都會因為擔心穩定性而很難推動(寫patch的和運維的同學,你們懂的)。
所以打算用一個“第三方”工具中轉,來實現多執行緒同步。基本結構如下:
說明:
1、這些transefer從master上各自同步一部分的資料,分別獨立更新slave。多程式還是多執行緒均可。
2、Transfer與master之間非同步更新日誌,transfer與slve之間同步更新資料
3、從這可以看出這個方案的缺點之一:更新能夠被獨立分開。比較直觀的想法是,按照表分。
三、關於transfer
作為這個關鍵的轉發工具transfer,需要提供如下功能:
1、能夠指定同步master中的哪部分資料,並且能夠方便地修改這個配置以應對master的加表需求;
2、支援stop slave、start slave。支援快速切換到新主庫的change master命令。
3、能夠記錄讀取點,transfer自己重啟或master重啟後能夠按照記錄點繼續讀後面的binlog;
4、能夠記錄分發點,transfer自己重啟或slave重啟後能夠按照記錄點繼續同步給slave
用起來就會發現還有好多要求。。。
四、方案實現
Transfer的這麼多功能,自己造輪子就累了。這裡直接用MySQL來充當此角色。為了方便描述,下文還將之稱為transfer。Transfer更新slave在功能上可以使用federated引擎,但由於其糾結的實現導致效能上達不到要求,因此在MySQL框架層中作了一點修改――讀到同步日誌後,直接傳送給slave。
方案簡單描述如下:
1、 Slave機器上搭另外的若干個MySQL(transfer),將其設為Master的從庫,且設定replicate-do-table, 每個transfer承擔一部分的表。
2、 所有Transfer的更新目標都設定為slave,其更新方式是讀到日誌後直接mysql_real_query執行到slave上。
從這可以看出這個方案的缺點之二:只能支援statement格式的同步方式。其實row也能支援,後面再說。
五、仍然延遲?
在transfer放棄federated引擎改用直接傳送後,效能提升不少,從庫同步效能增加一倍,但從本文第一個圖的資料對比就知道,延遲還很大。
發現這個時候slave的機器cpu已經很忙了,idle 20%一下――這個算是好訊息,總比idle很高但效能上不去好。
實際上是因為每個transfer,雖然設定只同步其中的部分表,但在實現上是IO執行緒把master上的所有命令都備份到本地,然後在SQL執行緒執行的時候再判斷,若不符合replicate-do-table,再放棄。
這樣存在的問題,是n個transfer,磁碟寫了n倍,更嚴重的是導致SQL執行緒空轉。
我們上文提到整個流程中IO執行緒是比較空閒的,因此修改IO執行緒邏輯,在寫入磁碟前先判斷,若不符合本transfer的replicate-do-table設定,不寫盤,直接放棄。
六、效果
從庫的QPS由於執行緒切換會有抖動,但總的執行時間與主庫相同。從庫的cpu idle下降,與主庫幾乎同時恢復到100。
七、小結
描述完了,總結一下,方案的代價:
1、要求在slave機器上多配置n個transfer(是否在從庫上均可)
2、目前只能支援statement的binlog格式,實際上row可以支援,方案定了,開發計劃中。
3、跨表更新的語句,會按照其更新的第一個表,分發到唯一一個transfer,沒有重複更新的問題,但有時序性問題。
方案的好處:
1、功能比較齊全。直接使用MySQL,原有的管理功能基本都能用,主庫從庫重啟/換庫的代價比較小。
2、開發量小,只在transfer上修改兩處,不包括配置讀取部分,300行以內
3、風險相對小。不直接修改master和slve上的程式碼,線上比較容易接收。
相關文章
- 揭秘MySQL的主從同步實現方案MySql主從同步
- mysql主從同步MySql主從同步
- Mysql主從同步實戰(一)【知其然】MySql主從同步
- MySQL主從同步(一主一從、一主多從、主從從)等結構的概述與配置MySql主從同步
- MySQL主從同步配置MySql主從同步
- MySQL 資料主從同步MySql主從同步
- MySql主從同步介紹MySql主從同步
- MySQL主從同步報error 1236MySql主從同步Error
- mysql主從同步問題整理MySql主從同步
- [資料庫]MYSQL主從同步資料庫MySql主從同步
- Mysql 主從同步原理簡析MySql主從同步
- 使用laradock配置mysql主從同步MySql主從同步
- MySQL-主從複製之同步主從資料MySql
- MySQL 主從配置-之-一主一從MySql
- MySQL 5.7的安裝及主從複製(主從同步)MySql主從同步
- 【mysql】mysql的資料庫主從(一主一從)MySql資料庫
- MySQL 5.7 多主一從(多源複製)同步配置MySql
- SVN程式碼倉庫主從同步方案主從同步
- MySQL(14)---Docker搭建MySQL主從複製(一主一從)MySqlDocker
- mysql主從複製(一):一主多從MySql
- 高併發架構系列:資料庫主從同步的3種方案架構資料庫主從同步
- Window 10 單機配置MYSQL主從同步MySql主從同步
- MySQL 主從同步的基本原理MySql主從同步
- 解決MySQL的主從資料庫沒有同步的兩種方法MySql資料庫
- Mysql 一主一從配置MySql
- MySQL主從複製之半同步複製MySql
- MySQL主從複製之非同步複製MySql非同步
- mysql檢視主從同步狀態的方法MySql主從同步
- MYSQL主從複製製作配置方案MySql
- Mysql實現主從複製(一主雙從)MySql
- 【MySQL(二十二)】一主一從換主MySql
- RocketMQ主從同步MQ主從同步
- Redis主從同步Redis主從同步
- mysql伺服器主從資料庫同步配置MySql伺服器資料庫
- Ubuntu18 mysql8(maridb 10.4.17 )主從同步UbuntuMySql主從同步
- MySQL主從複製延遲解決方案MySql
- MySQL5.7主從複製-半同步複製搭建MySql
- Mongo主從同步原理Go主從同步
- mysql5.6搭建主從過程中遇到主從server_uuid一致無法同步的問題MySqlServerUI