天天看點

MySQL鍊式複制加速神器: MaxScale Binlog Server(附視訊)

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

講師介紹

MySQL鍊式複制加速神器: MaxScale Binlog Server(附視訊)

賀春旸

普惠金融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就尴尬了。

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

mariadb maxscale的工作原理

maxscale binlog伺服器主要功能

如何将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:

一個主庫

兩個或更多的從庫

一個或兩個maxscale伺服器配置了binlog接收器

MySQL鍊式複制加速神器: MaxScale Binlog Server(附視訊)

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]

router=cli

[cli 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;

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

MySQL鍊式複制加速神器: MaxScale Binlog Server(附視訊)

# 登入到maxscale管理背景,可以看到接收binlog的資訊,如下圖所示。

# maxadmin -uadmin -pmariadb -p6603

MySQL鍊式複制加速神器: MaxScale Binlog Server(附視訊)

# 線上搭建一個從庫與maxscale binlog server同步複制步驟:

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

從庫上導入

more all.sql檢視同步複制的點

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]

這裡能不按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