閱讀62 返回首頁    go 阿裏雲 go 技術社區[雲棲]


MySQL鏈式複製加速神器: MaxScale Binlog Server(附視頻)

本文根據DBAplus社群第83期線上分享整理而成

 

講師介紹20161202032423546.jpg

賀春暘

普惠金融MySQL專家

 

  • 《MySQL管理之道》第一版、第二版作者,曾任職於中國移動飛信、機鋒安卓市場,擁有豐富的數據庫管理經驗。

  • 目前致力於MySQL、Linux等開源技術的研究。

 

感謝大家參與我今天的分享,希望今天大家能有所收獲,並能把這項新技術玩起來先。在介紹MaxScale Binlog Server前,我先把我們這邊的情況大致闡述下。

 

公司核心數據庫在我15年7月入職第二周,從最原始的MySQL5.5.30社區版全部升級到MariaDB10.0.21企業版,隨後麵的機房遷移,版本再次升級為MariaDB10.0.26企業版。

 

那為啥選用這個版本?對於金融p2p公司來說,換數據庫就意味著風險,因為庫裏都是錢,大多都采用保守的方法。而我之前來機鋒網(安卓市場)的時候,就已經使用MariaDB10.0.17社區版跑了一年半,當時PV是2000萬,數據庫總共8台,一主7從,前端PHP做的讀寫分離,後端用HaProxy做DB的負載均衡,QPS每秒在15000–20000左右,TPS每秒在300–500左右,至今數據庫穩定的跑著,未出現一次故障。

 

有了成功經驗,對我換金融數據庫版本就有了足夠的信心保障,因為金融類的公司並發都遠遠低於傳統互聯網公司,事實證明,目前業務穩定跑了1年4個月。

 

 業務場景  

 

好,再回過頭來說下,對接大數據分析部門遇到的痛點以及我們為何上了MaxScale binlog server。我們給大數據那邊,是提供一台單獨的從庫,注意是二級從庫,他們通過阿裏巴巴開源的canal連接到Slave從庫上,然後Slave推送binlog給canal,接收完binlog再推送給kafka消息隊列,最終存入HBase裏,業務部門通過Hive直接寫SQL的方式來實現業務的實時分析,大體的架構就是這樣。

 

注意剛才我提到的二級從庫,因我們目前線上的從庫一台是Standby僅提供故障切換用的,另一台是提供業務讀寫分離用的。所以我在從庫的下麵接了一台二級從庫,提供對接canal使用。因爬蟲的抓取insert寫入量大,從庫的SQL_THREAD線程隻有commit後才會記本地的binlog裏,然後再推送給二級從庫。這個時候,由於我們是實時分析,延遲5秒也無法接受,被業務方噴了回來,這TMD就尷尬了。

 

下麵進入正題,本次分享將圍繞以下三部分展開:

  1. MariaDB MaxScale的工作原理

  2. MaxScale Binlog服務器主要功能

  3. 如何將MaxScale設置為Binlog服務器

 

 MariaDB MaxScale的工作原理  

 

生產環境中,大多采用的是一主多從架構,即主庫推送三份binlog日誌到S1/S2/S3從庫上。然而,在這個架構中存在了一些問題,當主庫帶了過多的從庫,勢必會增加主庫的網絡IO壓力。而鏈式複製(多級複製)通常為M---S1---S2/S3,S1是S2/S3的主,主庫隻需要給S1推送binlog日誌即可,S1再推送binlog日誌給S2/S3,在這種場景下,緩解了主庫的網絡IO壓力,但其缺點是:S2/S3得到最新的數據,需要再經過一層的複製才到達,期間的延遲比一主多從架構要大。

 

業界通常的做法是在二級主庫上(S1)選擇黑洞引擎(BLACKHOLE)降低鏈式複製(多級複製)的延遲問題。寫入BLACKHOLE表的數據並不會記錄到磁盤上(本身不保存數據),永遠為一個空表,因不會將同步的數據寫回到磁盤上,速度遠遠比INNODB引擎快,它僅僅接收主庫推送過來的binlog日誌。

 

MaxScale對Binlog的收集采用了一個更簡單的方法,其工作在主庫和從庫之間。它不會對binlog進行任何回放操作,自身不保存數據。它把從主庫接收的binlog放入本地緩存,並將其推送給從庫。這意味著從庫總是獲得最新的binlog事件,它們與主庫寫入的binlog事件具有一對一的關係。其延遲主要是添加多台MaxScale帶來的額外的網絡傳輸。

 

充當主庫代理的MaxScale具有與主庫完全相同的binlog事件,這意味著從庫可以在任意一個MaxScale節點之間CHANGE MSATER TO ,無需執行任何特殊處理。MariaDB MaxScale Binlog Server接收器,工作流程類似黑洞引擎(BLACKHOLE)。

 

 MaxScale Binlog服務器主要功能  

 

  • Binlog服務器從主庫請求和接收Binlog事件。

  • 接收的二進製日誌與主庫裏的二進製日誌完全相同,可以理解為MaxScale Binlog每秒rsync主庫的binlog事件。

  • 從庫可以與MaxScale Binlog做CHANGE MSATER TO同步複製,從而不會對主庫網絡IO造成過大影響。

 

 如何將MaxScale設置為Binlog服務器  

 

使用MaxScale作為binlog代理與使用MaxScale作為應用讀寫分離的代理非常相似。

 

基礎架構為:M---MaxScale Binlog---S1/S2:

 

  1. 一個主庫

  2. 兩個或更多的從庫

  3. 一個或兩個MaxScale服務器配置了binlog接收器

 

20161202032440308.jpg

 

MaxScale binlog配置

# cat /etc/maxscale.cnf

[maxscale]

threads=24

##根據CPU核數設置

[Replication]

type=service

router=binlogrouter

user=repl

passwd=repl

# 使用主庫上的repl複製賬號

# 權限:

#   GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repl'@'%' IDENTIFIED BY   'repl';

router_options=server_id=1311,heartbeat=30,binlogdir=/data/binlog,transaction_safety=1,mariadb10-compatibility=1,send_slave_heartbeat=1

# server_id設置maxscale的,記得不能與主和從庫重複,要唯一

#   heartbeat=30秒,意思為當maxscale在30秒內沒有接收到主庫推送的binlog日誌,發送心跳檢查

#   binlogdir設置接收binlog的存放路徑,目錄屬性chown -R

maxscale.maxscale   /data/binlog

# transaction_safety=1此參數用於啟用binlog日誌中的不完整事務檢測。   當MariaDB MaxScale啟動時,如果當前binlog文件已損壞或找到不完整的事務,則可能會出現錯誤消息。   在正常工作期間,binlog事件不會分配到從庫,直到事務已經提交。 默認值為off,設置transaction_safety = on以啟用不完全事務檢測。

#   send_slave_heartbeat=1開啟心跳檢查

[Replication   Listener]

type=listener

service=Replication

protocol=MySQLClient

port=5308

# 後端的從庫CHANGE   MASTER TO這個端口,默認5308

[CLI]

type=service

router=cli

[CLI Listener]

type=listener

service=CLI

protocol=maxscaled

port=6603

#   MaxScale後台管理端口

 

啟動:

# /etc/init.d/maxscale start

 

使用:

# 連接到MaxScale binlog Server後台

# mysql -h192.168.17.131 -urepl -prepl -P5308

# 就像平常建立主從複製一樣,執行下麵的命令

 

MySQL [(none)]> CHANGE MASTER TO

MASTER_HOST='192.168.17.128',MASTER_USER='repl',MASTER_PASSWORD='repl',
MASTER_PORT=3306,MASTER_LOG_FILE='mysql-bin.000012',MASTER_LOG_POS=4;

MySQL [(none)]> start slave;

Query OK, 0 rows affected (0.03 sec)

 

# 注:這裏MASTER_LOG_POS必須指定4,否則報錯。

# 此外,GTID目前不支持

MySQL [(none)]> set global gtid_slave_pos = '0-17128-37';                                                                                               

ERROR 1064 (42000): You have an error in your SQL syntax; Check the syntax the MaxScale binlog router accepts.

MySQL [(none)]>

MySQL [(none)]> CHANGE MASTER TO 

MASTER_HOST='192.168.17.128',MASTER_USER='repl', MASTER_PASSWORD='repl',MASTER_PORT=3306,master_use_gtid ='slave_pos';

ERROR 1234 (42000): option 'master_use_gtid' is not supported

MySQL [(none)]> show slave status\G

*************************** 1. row ***************************

               Slave_IO_State: Binlog Dump

                  Master_Host: 192.168.17.128

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000012

          Read_Master_Log_Pos: 365

               Relay_Log_File: mysql-bin.000012

                Relay_Log_Pos: 365

        Relay_Master_Log_File: mysql-bin.000012

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

              Replicate_Do_DB:

          Replicate_Ignore_DB:

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                   Last_Errno: 0

                   Last_Error:

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 365

              Relay_Log_Space: 365

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File:

           Master_SSL_CA_Path:

              Master_SSL_Cert:

            Master_SSL_Cipher:

               Master_SSL_Key:

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

               Last_SQL_Errno: 0

               Last_SQL_Error:

  Replicate_Ignore_Server_Ids:

             Master_Server_Id: 17128

                  Master_UUID: ca8da868-a63f-11e6-a6d7-000c29379e1f

             Master_Info_File: /data/binlog/master.ini

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave running

           Master_Retry_Count: 1000

                  Master_Bind:

      Last_IO_Error_TimeStamp:

     Last_SQL_Error_Timestamp:

               Master_SSL_Crl:

           Master_SSL_Crlpath:

           Retrieved_Gtid_Set:

            Executed_Gtid_Set:

                Auto_Position:

1 row in set (0.00 sec)

 

# 如果你配置有誤,清空同步信息即可,執行下麵命令

MySQL [(none)]> stop slave;

Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> reset slave all;

Query OK, 0 rows affected (0.00 sec)

 

# 這一步成功之後,你會在/data/binlog目錄下發現接收過來的binlog日誌,如下圖所示。

 

20161202032502536.jpg

 

# 登錄到MaxScale管理後台,可以看到接收binlog的信息,如下圖所示。

# maxadmin -uadmin -pmariadb -P6603

 

20161202032514598.jpg

 

# 在線搭建一個從庫與MaxScale Binlog Server同步複製步驟:

 

  1. 主庫上導出mysqldump --single-transaction -q -p123456 --master-data=2 -A > all.sql

  2. 從庫上導入

  3. more all.sql查看同步複製的點

  4. CHANGE MASTER TO MaxScale Binlog Server(端口5308)

 

參考文獻:

https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale-as-a-binlog-server/

 

視頻下載:

為了幫助大家理解,已將演示視頻上傳至社群百度網盤,點擊底部【閱讀原文】可獲取。

 

Q&A

 

Q1:“# 注:這裏MASTER_LOG_POS必須指定4  ” 如果運行很久的庫,我搭建一個maxscale binlog server 也要指定  MASTER_LOG_POS=4 ?

A1:是的,必須指定為4,從頭開始接收,這樣是保證binlog日誌的完整性。

 

Q2:賀老師,我有一個運行一段時間的一主N從的架構,我能中間加一個這個binlog server 後,把其他 從庫重新指定到這個binlog server 麼,有什麼需要注意的麼?

A2:可以,這個沒問題。

 

Q3:另外如果主庫的MASTER_LOG_POS=4  的binlog 已經刪除了, 上麵也那個指定也是需要指定4不會有問題嗎?

A3:binlog server的binlog就是主庫上rsync過來的,完全一致。指定的時候,是從4開始的,binlog文件都是從4開始,例如mysql-bin.00001,00002,都是從4開始。

 

Q4:我有一個運行一段時間的一主N從的架構,架構中加入binlog server 如何解決單點?

A4:binlog server可以部署兩台,就是同時拉取兩份主庫的binlog。

 

Q5:[maxscale]

threads=24

##根據CPU核數設置

這裏能不按CPU核數設置嗎?

A5:這個可以,但性能會下降。

 

Q6:一主多從的架構,中間部署binlog server,在服務器壓力大時如何降低或確保slave端的延遲?

A6:我們目前生產是開啟了MariaDB的並行複製功能,32核CPU,開啟了32個線程。另外可以通過增加內存,調整INNODB_BUFFER_POOL_SIZE解決延遲的問題。另外一點是注意避免主庫的大事務,比如更新一個表,總共100萬,讓開發通過程序,循環更新,每1000條一個事務,直到全部更新完畢。

 

Q7:賀老師,能給DBA的職業發展給點建議?

A7:不敢當,一個老DBA前輩告訴我的,要多寫博客,多做分享。

(承接上一問)

Q8:對準備轉行進入數據庫的給點建議或者注意事項?

A8:我覺得DBA這個行業,需要謹慎,就跟開車一樣,需要時間磨練。另外就是溝通,因為每天都要對接各種開發,給他們提建議。

Q9:新入行的,做運維,開發,實施,有什麼區別?

A9:運維開發側重點不同。

Q10:Oracle 和MySQL 哪個會更長久?

A10:這個我之前麵試過20個DBA,有很多是從Oralce轉的。目前是MySQL要火一些。

Q11:NoSQL這類數據庫前景如何?

A11:是必須會的,Redis和MongoDB。

 

Q12:MySQL和MariaDB哪個好?MySQL學習中有哪些難點要特別注意的?

A12:這個各有優缺點吧,在生產上之所以選擇的mariadb,是看重他的功能更多,性能更好,穩定等因素。另外是從5.5升級到mariadb10.0,不需要進行導出導入了,隻需卸載mysql,用mariadb啟動即可,很簡單。這對數據庫上T的來說,輕鬆不少。

難點就是經常會遇到坑,心理要能承受得住業務方的噴。最最重要的是,高可用得做起來。

 

Q13:MySQL一個表或數據庫中,大概多少記錄算是大數據呢(新手問)

A13:之前在電商那會,通常是建議開發2000萬行就開始做分表,否則大促的時候,性能非常差。

 

Q14:請問MariaDB和5.7以上的MySQL對比,優勢大麼?

A14:MySQL5.7對InnoDB這塊加強了不少,但最好是5.7.20以後再上。

 

Q15:賀老師,我想問一下關於MySQL漏洞打補丁之類的問題。

A15:這個升級的步驟是,先對從庫做版本升級,然後淩晨的時候用MHA做下切換,再對原先的主庫升級。之前在飛信的時候,經常安全部門找到我們,我就是這樣升級的小版本。

(承接上一問)

Q16:就是直接做數據庫版本升級?

A16:是的,用新版本啟動。

Q17:那數據導入導出一般您是采用哪種方式呢?

A17:推薦用mydumper,是多線程的,速度比單線程的mysqldump快。

Q18:mydumper是不是還不支持設置字符集?

A18:通常數據庫都是UTF8的,導出的時候還真沒特意指定過。

Q19:MHA能支持一主一備,1+2感覺有點浪費。

A19:這必須的。目前最新版本是0.57,老版本0.56就已經支持。

原文發布時間為:2016-12-02

本文來自雲棲社區合作夥伴DBAplus

最後更新:2017-05-11 14:01:40

  上一篇:go  要想成為編程高手就應該具備的八個條件
  下一篇:go  如何利用容器構建持續交付/持續發布係統?