MySQL高可用架構(MHA)與Atlas讀寫分離

file

1.1 MHA簡介

1.1.1 MHA軟件介紹

  MHA(Master High Availability)目前在MySQL高可用方面是一個相對成熟的解決方案,它由日本DeNA公司youshimaton(現就任於Facebook公司)開發,是一套優秀的做爲MySQL高可用性環境下故障切換和主從提高的高可用軟件。在MySQL故障切換過程當中,MHA能作到在10~30秒以內自動完成數據庫的故障切換操做,而且在進行故障切換的過程當中,MHA能在最大程度上保證數據的一致性,以達到真正意義上的高可用。html

  MHA可以在較短的時間內實現自動故障檢測和故障轉移,一般在10-30秒之內;在複製 框架中,MHA可以很好地解決複製過程當中的數據一致性問題,因爲不須要在現有的 replication中添加額外的服務器,僅須要一個manager節點,而一個Manager能管理多套複製,因此能大大地節約服務器的數量;另外,安裝簡單,無性能損耗,以及不須要修改現 有的複製部署也是它的優點之處。前端

  MHA還提供在線主庫切換的功能,可以安全地切換當前運行的主庫到一個新的主庫中 (經過將從庫提高爲主庫),大概0.5-2秒內便可完成。node

  該軟件由兩部分組成:MHA Manager(管理節點)和MHA Node(數據節點)。MHA Manager能夠單獨部署在一臺獨立的機器上管理多個master-slave集羣,也能夠部署在一臺slave節點上。MHA Node運行在每臺MySQL服務器上,MHA Manager會定時探測集羣中的master節點,master出現故障時,它能夠自動將最新數據的slave提高爲新的master,而後將全部其餘的slave從新指向新的master整個故障轉移過程對應用程序徹底透明。mysql

  在MHA自動故障切換過程當中,MHA試圖從宕機的主服務器上保存二進制日誌,最大程度的保證數據的不丟失,但這並不老是可行的。例如,若是主服務器硬件故障或沒法經過ssh訪問,MHA無法保存二進制日誌,只進行故障轉移而丟失了最新的數據。使用MySQL 5.5的半同步複製,能夠大大下降數據丟失的風險。git

  MHA能夠與半同步複製結合起來。若是隻有一個slave已經收到了最新的二進制日誌,MHA能夠將最新的二進制日誌應用於其餘全部的slave服務器上,所以能夠保證全部節點的數據一致性。程序員

  目前MHA主要支持一主多從的架構,要搭建MHA,要求一個複製集羣中必須最少有三臺數據庫服務器,一主二從,即一臺充當master,一臺充當備用master,另一臺充當從庫,由於至少須要三臺服務器,出於機器成本的考慮,淘寶也在該基礎上進行了改造,目前淘寶TMHA已經支持一主一從。github

1.1.2 MHA工做原理

file 工做原理說明: 一、保存master上的全部binlog事件 二、找到含有最新binlog位置點的slave 三、經過中繼日誌將數據恢復到其餘的slave 四、將包含最新binlog位置點的slave提高爲master 五、將其餘從庫slave指向新的master原slave01 並開啓主從複製 六、將保存下來的binlog恢復到新的master上

一、監控全部node節點MHA功能說明:web

二、自動故障切換(failover)面試

前提是必須有三個節點存在,而且有兩個從庫sql

  (1)選主前提,按照配置文件的順序進行,可是若是此節點後主庫100M以上relay-log 就不會選

  (2)若是你設置了權重,總會切換帶此節點;通常在多地多中心的狀況下,通常會把權重設置在本地節點。

  (3)選擇s1爲新主

  (4)保存主庫binlog日誌

三、從新構建主從

  (1)將有問題的節點剔除MHA

    進行第一階段數據補償,S2缺失部分補全90

  (2)s1切換角色爲新主,將s2指向新主S1

     s2 change master to s1

  (3) 第二階段數據補償

     將保存過來的新主和原有主缺失部分的binlog,應用到新主。

  (4)虛擬IP漂移到新主,對應用透明無感知

   (5)通知管理員故障切換

1.1.3 MHA高可用架構圖

file

1.1.4 MHA工具介紹

  MHA軟件由兩部分組成,Manager工具包和Node工具包,具體的說明以下:

  Manager工具包主要包括如下幾個工具:

masterha_check_ssh             #檢査 MHA 的 ssh-key^
masterha_check_repl            #檢査主從複製狀況
masterha_manger                #啓動MHA
masterha_check_status          #檢測MHA的運行狀態^
masterha_mast er_monitor       #檢測master是否宕機一
masterha_mast er_switch        #手動故障轉移—
masterha_conf_host             #手動添加server倍息一
masterha_secondary_check       #創建TCP鏈接從遠程服務器v
masterha_stop                  #中止MHA

Node工具包主要包括如下幾個工具:

save_binary_1ogs       #保存宕機的master的binlog
apply_diff_relay_logs   #識別relay log的差別
filter_mysqlbinlog           #防止回滾事件一MHA已再也不使用這個工具
purge_relay_logs           #清除中繼曰志一不會阻塞SQL線程

1.1.5 MHA的優勢

一、自動故障轉移

二、主庫崩潰不存在數據不一致的狀況

三、不須要對當前的mysql環境作重大修改

四、不須要添加額外的服務器

五、性能優秀,能夠工做再半同步和異步複製框架

六、只要replication支持的存儲引擎mha都支持

1.2 環境說明

   在本次的實驗中,共須要用到三臺主機,系統、軟件說明以下。

1.2.1 系統環境說明

db01主機(master)

[root@db01 ~]# cat /etc/redhat-release 
CentOS release 6.9 (Final)
[root@db01 ~]# uname -r
2.6.32-696.el6.x86_64
[root@db01 ~]# /etc/init.d/iptables status
iptables: Firewall is not running.
[root@db01 ~]# getenforce 
Disabled
[root@db01 ~]# hostname -I
10.0.0.51 172.16.1.51

db02主機(slave1)

1 [root@db02 ~]# cat /etc/redhat-release 
 2 CentOS release 6.9 (Final)
 3 [root@db02 ~]# uname -r
 4 2.6.32-696.el6.x86_64
 5 [root@db02 ~]# /etc/init.d/iptables status
 6 iptables: Firewall is not running.
 7 [root@db02 ~]# getenforce 
 8 Disabled
 9 [root@db02 ~]# hostname -I
10 10.0.0.52 172.16.1.52

db03主機(slave1,MHA Manages、Atlas節點)

1 [root@db02 ~]# cat /etc/redhat-release 
 2 CentOS release 6.9 (Final)
 3 [root@db02 ~]# uname -r
 4 2.6.32-696.el6.x86_64
 5 [root@db02 ~]# /etc/init.d/iptables status
 6 iptables: Firewall is not running.
 7 [root@db02 ~]# getenforce 
 8 Disabled
 9 [root@db02 ~]# hostname -I
10 10.0.0.52 172.16.1.52

1.2.2 mysql軟件說明

​ 三臺服務器上都全新安裝mysql 5.6.36 :

[root@db01 ~]# mysql --version
mysql  Ver 14.14 Distrib 5.6.36, for Linux (x86_64) using  EditLine wrapper

  關於mysql數據庫具體的安裝方法參考:http://www.cnblogs.com/clsn/p/8038964.html#_label3

1.3 基於GTID的主從複製配置

1.3.1 先決條件

  🔊 主庫和從庫都要開啓binlog

  🔊 主庫和從庫server-id必須不一樣

  🔊 要有主從複製用戶

1.3.2 配置主從複製

db01 my.cnf****文件

[root@db01 ~]# cat /etc/my.cnf
[mysqld]
basedir=/application/mysql
datadir=/application/mysql/data
socket=/tmp/mysql.sock
log-error=/var/log/mysql.log
log-bin=/data/mysql/mysql-bin
binlog_format=row
secure-file-priv=/tmp 
server-id=51
skip-name-resolve  # 跳過域名解析
gtid-mode=on    # 啓用gtid類型,不然就是普通的複製架構
enforce-gtid-consistency=true    #強制GTID的一致性
log-slave-updates=1     # slave更新是否記入日誌(5.6必須的)
relay_log_purge = 0 
[mysql]
socket=/tmp/mysql.sock

db02 my.cnf****文件

1 [root@db02 ~]# cat /etc/my.cnf
 2 [mysqld]
 3 basedir=/application/mysql
 4 datadir=/application/mysql/data
 5 socket=/tmp/mysql.sock
 6 log-error=/var/log/mysql.log
 7 log-bin=/data/mysql/mysql-bin
 8 binlog_format=row
 9 secure-file-priv=/tmp 
10 server-id=52
11 skip-name-resolve
12 gtid-mode=on
13 enforce-gtid-consistency=true
14 log-slave-updates=1
15 relay_log_purge = 0 
16 [mysql]
17 socket=/tmp/mysql.sock

db03 my.cnf****文件

1 [root@db03 ~]# cat /etc/my.cnf
 2 [mysqld]
 3 basedir=/application/mysql
 4 datadir=/application/mysql/data
 5 socket=/tmp/mysql.sock
 6 log-error=/var/log/mysql.log
 7 log-bin=/data/mysql/mysql-bin
 8 binlog_format=row
 9 secure-file-priv=/tmp 
10 server-id=53
11 skip-name-resolve
12 gtid-mode=on
13 enforce-gtid-consistency=true
14 log-slave-updates=1
15 relay_log_purge = 0 
16 skip-name-resolve
17 [mysql]
18 socket=/tmp/mysql.sock

建立複製用戶 (51做爲主節點,5二、53爲從)

GRANT REPLICATION SLAVE ON *.* TO repl@'10.0.0.%' IDENTIFIED BY '123';

從庫開啓複製

change master to 
    master_host='10.0.0.51',
    master_user='repl',
    master_password='123',
    MASTER_AUTO_POSITION=1;

啓動從庫複製

start slave;

1.3.3 GTID複製技術說明

MySQL GTID****簡介

  GTID的全稱爲 global transaction identifier ,能夠翻譯爲全局事務標示符,GTID在原始master上的事務提交時被建立。GTID須要在全局的主-備拓撲結構中保持惟一性,GTID由兩部分組成:

 GTID = source_id:transaction_id

  source_id用於標示源服務器,用server_uuid來表示,這個值在第一次啓動時生成,並寫入到配置文件data/auto.cnf中

  transaction_id則是根據在源服務器上第幾個提交的事務來肯定。

GTID**事件結構

file
GTID**在二進制日誌中的結構

file
一個GTID*的生命週期包括:*

1.事務在主庫上執行並提交給事務分配一個gtid(由主庫的uuid和該服務器上未使用的最小事務序列號),該GTID被寫入到binlog中。

2.備庫讀取relaylog中的gtid,並設置session級別的gtid_next的值,以告訴備庫下一個事務必須使用這個值

3.備庫檢查該gtid是否已經被其使用並記錄到他本身的binlog中。slave須要擔保以前的事務沒有使用這個gtid,也要擔保此時已分讀取gtid,但未提交的事務也不恩呢過使用這個gtid.

4.因爲gtid_next非空,slave不會去生成一個新的gtid,而是使用從主庫得到的gtid。這能夠保證在一個複製拓撲中的同一個事務gtid不變。因爲GTID在全局的惟一性,經過GTID,咱們能夠在自動切換時對一些複雜的複製拓撲很方便的提高新主庫及新備庫,例如經過指向特定的GTID來肯定新備庫複製座標。

    GTID是用來替代之前classic的複製方法;

    MySQL5.6.2支持 MySQL5.6.10後完善;

GTID****相比傳統複製的優勢:

1.一個事務對應一個惟一ID,一個GTID在一個服務器上只會執行一次

2.GTID是用來代替傳統複製的方法,GTID複製與普通複製模式的最大不一樣就是不須要指定二進制文件名和位置

3.減小手工干預和下降服務故障時間,當主機掛了以後經過軟件從衆多的備機中提高一臺備機爲主機

GTID****的限制:

1.不支持非事務引擎

2.不支持create table ... select 語句複製(主庫直接報錯)

  原理:( 會生成兩個sql,一個是DDL建立表SQL,一個是insert into 插入數據的sql。

  因爲DDL會致使自動提交,因此這個sql至少須要兩個GTID,可是GTID模式下,只能給這個sql生成一個GTID )  

3.不容許一個SQL同時更新一個事務引擎表和非事務引擎表

4.在一個複製組中,必需要求統一開啓GTID或者是關閉GTID

5.開啓GTID須要重啓(5.7除外)

6.開啓GTID後,就再也不使用原來的傳統複製方式

7.對於create temporary table 和 drop temporary table語句不支持

8.不支持sql_slave_skip_counter

1.3.4 COM_BINLOG_DUMP_GTID

從機發送到主機執行的事務的標識符的主範圍

   Master send all other transactions to slave

  一樣的GTID不能被執行兩次,若是有一樣的GTID,會自動被skip掉。

file
  slave1:將本身的UUID1:1發送給master,而後接收到了UUID1:2,UUID1:3 event

  slave2:將本身的UUID1:1,UUID1:2發送給master,而後接收到了UUID1:3事件

GTID****組成

  GTID其實是由UUID+TID組成的。其中UUID是一個MySQL實例的惟一標識。TID表明了該實例上已經提交的事務數量,而且隨着事務提交單調遞增

GTID = source_id :transaction_id
7E11FA47-31CA-19E1-9E56-C43AA21293967:29

1.3.5 【示例二】MySQL GTID複製配置

主節點my.cnf文件

# vi /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
server-id=1
log-bin=mysql-bin
socket=/tmp/mysql.sock
binlog-format=ROW
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1

從節點my.cnf文件

# vi /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/data/mysql
server-id=2
binlog-format=ROW
gtid-mode=on
enforce-gtid-consistency=true
log-bin=mysql-bin
log_slave_updates = 1
socket=/tmp/mysql.sock

配置文件註解

server-id=x                    # 同一個複製拓撲中的全部服務器的id號必須唯一
binlog-format=RO               # 二進制日誌格式,強烈建議爲ROW
gtid-mode=on                   # 啓用gtid類型,不然就是普通的複製架構
enforce-gtid-consistency=true  # 強制GTID的一致性
log-slave-updates=1            # slave更新是否記入日誌

  複製用戶準備(Master主節點)

mysql>GRANT REPLICATION SLAVE ON *.* TO rep@'10.0.0.%' IDENTIFIED BY '123';

  開啓複製(Slave從節點)

mysql>start slave;
mysql>show slave status\G

  如今就能夠進行主從複製測試。

1.4 部署MHA

  本次MHA的部署基於GTID複製成功構建,普通主從複製也能夠構建MHA架構。

1.4.1 環境準備(全部節點操做)

安裝依賴包

yum install perl-DBD-MySQL -y

   下載mha軟件,mha官網:https://code.google.com/archive/p/mysql-master-ha/

​ github下載地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads

*下載軟件包*

mha4mysql-manager-0.56-0.el6.noarch.rpm

mha4mysql-manager-0.56.tar.gz

mha4mysql-node-0.56-0.el6.noarch.rpm

mha4mysql-node-0.56.tar.gz

在全部節點安裝node

rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

建立mha管理用戶

grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';

# 主庫上建立,從庫會自動複製(在從庫上查看)

  建立命令軟鏈接(重要)

  若是不建立命令軟鏈接,檢測mha複製狀況的時候會報錯

ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /application/mysql/bin/mysql /usr/bin/mysql

1.4.2 部署管理節點(mha-manager)

在mysql-db03上部署管理節點

# 安裝epel源,軟件須要
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo 
# 安裝manager 依賴包
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
# 安裝manager管理軟件
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

建立必須目錄

mkdir -p /etc/mha
mkdir -p /var/log/mha/app1    ----》能夠管理多套主從複製

編輯mha-manager*配置文件*

[root@db03 ~]# cat  /etc/mha/app1.cnf
[server default]                        
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/mysql
user=mha
password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306

【配置文件詳解】

[server default]
 2 #設置manager的工做目錄
 3 manager_workdir=/var/log/masterha/app1
 4 #設置manager的日誌
 5 manager_log=/var/log/masterha/app1/manager.log 
 6 #設置master 保存binlog的位置,以便MHA能夠找到master的日誌,我這裏的也就是mysql的數據目錄
 7 master_binlog_dir=/data/mysql
 8 #設置自動failover時候的切換腳本
 9 master_ip_failover_script= /usr/local/bin/master_ip_failover
10 #設置手動切換時候的切換腳本
11 master_ip_online_change_script= /usr/local/bin/master_ip_online_change
12 #設置mysql中root用戶的密碼,這個密碼是前文中建立監控用戶的那個密碼
13 password=123456
14 #設置監控用戶root
15 user=root
16 #設置監控主庫,發送ping包的時間間隔,嘗試三次沒有迴應的時候自動進行failover
17 ping_interval=1
18 #設置遠端mysql在發生切換時binlog的保存位置
19 remote_workdir=/tmp
20 #設置複製用戶的密碼
21 repl_password=123456
22 #設置複製環境中的複製用戶名 
23 repl_user=rep
24 #設置發生切換後發送的報警的腳本
25 report_script=/usr/local/send_report
26 #一旦MHA到server02的監控之間出現問題,MHA Manager將會嘗試從server03登陸到server02
27 secondary_check_script= /usr/local/bin/masterha_secondary_check -s server03 -s server02 --user=root --master_host=server02 --master_ip=10.0.0.51 --master_port=3306
28 #設置故障發生後關閉故障主機腳本(該腳本的主要做用是關閉主機放在發生腦裂,這裏沒有使用)
29 shutdown_script=""
30 #設置ssh的登陸用戶名
31 ssh_user=root 
32 
33 [server1]
34 hostname=10.0.0.51
35 port=3306
36 
37 [server2]
38 hostname=10.0.0.52
39 port=3306
40 #設置爲候選master,若是設置該參數之後,發生主從切換之後將會將此從庫提高爲主庫,即便這個主庫不是集羣中事件最新的slave
41 candidate_master=1
42 #默認狀況下若是一個slave落後master 100M的relay logs的話,MHA將不會選擇該slave做爲一個新的master,由於對於這個slave的恢復須要花費很長時間,經過設置check_repl_delay=0,MHA觸發切換在選擇一個新的master的時候將會忽略複製延時,這個參數對於設置了candidate_master=1的主機很是有用,由於這個候選主在切換的過程當中必定是新的master
43 check_repl_delay=0

配置ssh信任(密鑰分發,在全部節點上執行)

# 生成密鑰
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1
# 分發公鑰,包括本身
for i in 1 2 3 ;do ssh-copy-id -i /root/.ssh/id_dsa.pub root@10.0.0.5$i ;done

​ 分發完成後測試分發是否成功

for i in 1 2 3 ;do ssh 10.0.0.5$i  date ;done
或
[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
最後一行信息爲以下字樣即爲分發成功:
Thu Dec 28 18:44:53 2017 - [info] All SSH connection tests passed successfully.

1.4.3 啓動mha

通過上面的部署事後,mha架構已經搭建完成

# 啓動mha
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

​ 啓動成功後,檢查主庫狀態

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:3298) is running(0:PING_OK), master:10.0.0.51

1.4.4 切換master測試

查看如今的主庫是哪一個

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:11669) is running(0:PING_OK), master:10.0.0.51

手動中止主庫

[root@db01 ~]# /etc/init.d/mysqld stop 
Shutting down MySQL..... SUCCESS!

再中止數據的同時查看日誌信息的變化

[root@db03 ~]# tailf /var/log/mha/app1/manager
~~~
Fri Dec 29 15:51:14 2017 - [info]  All other slaves should start replication from
here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';

修復主從

① 啓動原主庫,添加change master to 信息

[root@db01 ~]# /etc/init.d/mysqld start 
Starting MySQL. SUCCESS!
mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';
mysql> start slave;

② 查看主從複製狀態

mysql> show slave status\G
                   Master_Host: 10.0.0.52
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

修復mha

① 修改app1.cnf配置文件,添加回被剔除主機

[root@db03 ~]# cat  /etc/mha/app1.cnf 
[binlog1]
hostname=10.0.0.53
master_binlog_dir=/data/mysql/binlog/
no_master=1

[server default]
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/mysql
master_ip_failover_script=/usr/local/bin/master_ip_failover
password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root
user=mha

[server1]
hostname=10.0.0.51
port=3306

[server2]
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306

② mha檢查複製狀態

[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
MySQL Replication Health is OK.

③ 啓動mha程序

nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

到此主庫切換成功

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf 
app1 (pid:11978) is running(0:PING_OK), master:10.0.0.52

實驗結束將主庫切換回db01.

① 中止mha

[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf 
Stopped app1 successfully.

② 中止全部從庫slave(全部庫操做)

stop slave;
reset slave all;

③ 重作主從複製(db0二、db03)

CHANGE MASTER TO 
  MASTER_HOST='10.0.0.51', 
  MASTER_PORT=3306, 
  MASTER_AUTO_POSITION=1, 
  MASTER_USER='repl', 
  MASTER_PASSWORD='123';

④ 啓動slave

start slave;

​ 啓動以後檢查從庫是否爲兩個yes show slave status\G

⑤ mha檢查主從複製

[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
MySQL Replication Health is OK.

⑥ 啓動mha

nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

  檢查切換是否成功

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:12127) is running(0:PING_OK), master:10.0.0.51

​ 到此主主節點有切回到db01

1.4.5 設置權重

修改[server1]的權重

[server1]
hostname=10.0.0.51
port=3306
candidate_master=1
check_repl_delay=0

配置說明

candidate_master=1                  ----》無論怎樣都切到優先級高的主機,通常在主機性能差別的時候用           
check_repl_delay=0                  ----》無論優先級高的備選庫,數據延時多久都要往那切

注:

一、多地多中心,設置本地節點爲高權重

二、在有半同步複製的環境中,設置半同步複製節點爲高權重

三、你覺着哪一個機器適合作主節點,配置較高的 、性能較好的

1.5 配置VIP漂移

1.5.1 IP漂移的兩種方式

 🐶 經過keepalived的方式,管理虛擬IP的漂移

   🐶 經過MHA自帶腳本方式,管理虛擬IP的漂移

1.5.2 MHA腳本方式

修改mha****配置文件

[root@db03 ~]# grep "script" /etc/mha/app1.cnf 
[server default]
master_ip_failover_script=/usr/local/bin/master_ip_failover

​ 再主配置中添加VIP腳本

腳本內容

[root@db03 ~]# cat /usr/local/bin/master_ip_failover 
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
    $command,          $ssh_user,        $orig_master_host, $orig_master_ip,
    $orig_master_port, $new_master_host, $new_master_ip,    $new_master_port
);
my $vip = '10.0.0.55/24';
my $key = '0';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

GetOptions(
    'command=s'          => \$command,
    'ssh_user=s'         => \$ssh_user,
    'orig_master_host=s' => \$orig_master_host,
    'orig_master_ip=s'   => \$orig_master_ip,
    'orig_master_port=i' => \$orig_master_port,
    'new_master_host=s'  => \$new_master_host,
    'new_master_ip=s'    => \$new_master_ip,
    'new_master_port=i'  => \$new_master_port,
);

exit &main();

sub main {

    print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";

    if ( $command eq "stop" || $command eq "stopssh" ) {

        my $exit_code = 1;
        eval {
            print "Disabling the VIP on old master: $orig_master_host \n";
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@\n";
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "start" ) {

        my $exit_code = 10;
        eval {
            print "Enabling the VIP - $vip on the new master - $new_master_host \n";
            &start_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn $@;
            exit $exit_code;
        }
        exit $exit_code;
    }
    elsif ( $command eq "status" ) {
        print "Checking the Status of the script.. OK \n";
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}

sub start_vip() {
    `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
     return 0  unless  ($ssh_user);
    `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}

sub usage {
    print
    "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}

  該腳本爲軟件自帶,腳本獲取方法:再mha源碼包中的samples目錄下有該腳本的模板,對該模板進行修改便可使用。路徑如: mha4mysql-manager-0.56/samples/scripts

  腳本修改內容

my $vip = '10.0.0.55/24';
my $key = '0';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";

腳本添加執行權限不然mha沒法啓動

chmod +x /usr/local/bin/master_ip_failover

手動綁定VIP(****主庫)

ifconfig eth0:0 10.0.0.55/24

  檢查

[root@db01 ~]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:6c:7a:11 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
    inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
    inet6 fe80::20c:29ff:fe6c:7a11/64 scope link 
       valid_lft forever preferred_lft forever

至此vip****漂移配置完成

1.5.3 測試虛擬IP漂移

查看db02的slave信息

img View Code 如今主從狀態

停掉主庫

[root@db01 ~]# /etc/init.d/mysqld stop

在db03上查看從庫slave信息

img View Code 停掉主庫後的主從信息

在db01上查看vip信息

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:6c:7a:11 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
    inet6 fe80::20c:29ff:fe6c:7a11/64 scope link 
       valid_lft forever preferred_lft forever

在db02上查看vip信息

[root@db02 ~]# ip a s eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:d6:0a:b3 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.52/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
    inet6 fe80::20c:29ff:fed6:ab3/64 scope link 
       valid_lft forever preferred_lft forever

​ 至此,VIP漂移就測試成功

1.6 配置binlog-server

1.6.1 配置binlog-server

1)前期準備:

一、準備一臺新的mysql實例(db03),GTID必須開啓。

二、未來binlog接收目錄,不能和主庫binlog目錄同樣

2)中止mha

masterha_stop --conf=/etc/mha/app1.cnf

3)在app1.cnf開啓binlogserver功能

[binlog1]
    no_master=1
    hostname=10.0.0.53                         ----> 主機DB03
    master_binlog_dir=/data/mysql/binlog/  ----> binlog保存目錄

4)開啓binlog接收目錄,注意權限

mkdir -p /data/mysql/binlog/ 
chown -R mysql.mysql /data/mysql
# 進入目錄啓動程序
  cd /data/mysql/binlog/ &&\
  mysqlbinlog  -R --host=10.0.0.51 --user=mha --password=mha --raw  --stop-never mysql-bin.000001 &

  參數說明:-R 遠程主機

5)啓動mha

nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &

1.6.2 測試binlog備份

#查看binlog目錄中的binlog

[root@db03 binlog]# ll
total 44
-rw-r--r-- 1 root root 285 Mar  8 03:11 mysql-bin.000001

#登陸主庫

[root@mysql-db01 ~]# mysql -uroot -p123

#刷新binlog

mysql> flush logs;

#再次查看binlog目錄

[root@db03 binlog]# ll
total 48
-rw-r--r-- 1 root root 285 Mar  8 03:11 mysql-bin.000001
-rw-r--r-- 1 root root 143 Mar  8 04:00 mysql-bin.000002

1.7 mysql中間件Atlas

1.7.1 atlas簡介

  Atlas是由 Qihoo 360公司Web平臺部基礎架構團隊開發維護的一個基於MySQL協議的數據中間層項目。它在MySQL官方推出的MySQL-Proxy 0.8.2版本的基礎上,修改了大量bug,添加了不少功能特性。目前該項目在360公司內部獲得了普遍應用,不少MySQL業務已經接入了Atlas平臺,天天承載的讀寫請求數達幾十億條。

  同時,有超過50家公司在生產環境中部署了Atlas,超過800人已加入了咱們的開發者交流羣,而且這些數字還在不斷增長。並且安裝方便。配置的註釋寫的蠻詳細的,都是中文。

  Atlas官方連接: https://github.com/Qihoo360/Atlas/blob/master/README_ZH.md

  Atlas下載連接: https://github.com/Qihoo360/Atlas/releases

1.7.2 主要功能

  讀寫分離、從庫負載均衡、自動分表、IP過濾

  SQL語句黑白名單、DBA可平滑上下線DB、自動摘除宕機的DB

Atlas相對於官方MySQL-Proxy的優點

1.將主流程中全部Lua代碼用C重寫,Lua僅用於管理接口

2.重寫網絡模型、線程模型

3.實現了真正意義上的鏈接池

4.優化了鎖機制,性能提升數十倍

1.7.3 使用場景

  Atlas是一個位於前端應用與後端MySQL數據庫之間的中間件,它使得應用程序員無需再關心讀寫分離、分表等與MySQL相關的細節,能夠專一於編寫業務邏輯,同時使得DBA的運維工做對前端應用透明,上下線DB前端應用無感知。

file
  Atlas是一個位於應用程序與MySQL之間中間件。在後端DB看來,Atlas至關於鏈接它的客戶端,在前端應用看來,Atlas至關於一個DB。

  Atlas做爲服務端與應用程序通信,它實現了MySQL的客戶端和服務端協議,同時做爲客戶端與MySQL通信。它對應用程序屏蔽了DB的細節,同時爲了下降MySQL負擔,它還維護了鏈接池.

1.7.4 企業讀寫分離及分庫分表其餘方案介紹

Mysql-proxy(oracle)

Mysql-router(oracle)

Atlas (Qihoo 360)

Atlas-sharding (Qihoo 360)

Cobar(是阿里巴巴(B2B)部門開發)

Mycat(基於阿里開源的Cobar產品而研發)

TDDL Smart Client的方式(淘寶)

Oceanus(58同城數據庫中間件)

OneProxy(原支付寶首席架構師樓方鑫開發 )

vitess(谷歌開發的數據庫中間件)

Heisenberg(百度)

TSharding(蘑菇街白輝)

Xx-dbproxy(金山的Kingshard、噹噹網的sharding-jdbc )

amoeba

1.7.5 安裝Atlas

  軟件獲取地址:https://github.com/Qihoo360/Atlas/releases

注意:

一、Atlas只能安裝運行在64位的系統上

二、Centos 5.X安裝 Atlas-XX.el5.x86_64.rpm,Centos 6.X安裝Atlas-XX.el6.x86_64.rpm。

三、後端mysql版本應大於5.1,建議使用Mysql 5.6以上

  Atlas (普通) : Atlas-2.2.1.el6.x86_64.rpm

  Atlas (分表) : Atlas-sharding_1.0.1-el6.x86_64.rpm

下載安裝atlas

wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm

​ 至此安裝完成

1.7.6 配置Atlas配置文件

  atlas配置文件中的密碼須要加密,可使用,軟件自帶的加密工具進行加密

cd /usr/local/mysql-proxy/conf/
/usr/local/mysql-proxy/bin/encrypt  密碼      ---->製做加密密碼

生產密文密碼:

[root@db03 bin]# /usr/local/mysql-proxy/bin/encrypt 123
3yb5jEku5h4=
[root@db03 bin]# /usr/local/mysql-proxy/bin/encrypt mha
O2jBXONX098=

編輯配置文件

vim  /usr/local/mysql-proxy/conf/test.cnf
[mysql-proxy]
admin-username = user
admin-password = pwd
proxy-backend-addresses = 10.0.0.55:3306
proxy-read-only-backend-addresses = 10.0.0.52:3306,10.0.0.53:3306
pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=
daemon = true
keepalive = true
event-threads = 8
log-level = message
log-path = /usr/local/mysql-proxy/log
sql-log=ON
proxy-address = 0.0.0.0:33060
admin-address = 0.0.0.0:2345
charset=utf8

配置文件內爲全中文註釋,這裏有一份較爲詳細的解釋:

img View Code Atlas配置文件說明

1.7.7 啓動Atlas

編寫一個atlas的管理腳本,固然也能夠寫腳本,能夠直接手動的管理:

/usr/local/mysql-proxy/bin/mysql-proxyd test start   #啓動
/usr/local/mysql-proxy/bin/mysql-proxyd test stop    #中止
/usr/local/mysql-proxy/bin/mysql-proxyd test restart #重啓

  注意:test是配置文件的名稱

腳本內容:

img View Code Atas管理腳本

檢查端口是否正常

[root@db03 ~]# netstat -lntup|grep mysql-proxy
tcp        0      0 0.0.0.0:33060               0.0.0.0:*                   LISTEN      2125/mysql-proxy    
tcp        0      0 0.0.0.0:2345                0.0.0.0:*                   LISTEN      2125/mysql-proxy

1.7.8 Atlas管理操做

  登入管理接口

[root@db03 ~]# mysql -uuser -ppwd -h127.0.0.1 -P2345

  查看幫助信息

mysql> SELECT * FROM help;

  查看後端的代理庫

mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.52:3306 | up    | ro   |
|           3 | 10.0.0.53:3306 | up    | ro   |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)

  平滑摘除mysql

mysql>  REMOVE BACKEND 2;
Empty set (0.00 sec)

   檢查是否摘除

mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.53:3306 | up    | ro   |
+-------------+----------------+-------+------+
2 rows in set (0.00 sec)

  保存到配置文件中

mysql> SAVE CONFIG;

  將節點再添加回來

mysql> add slave 10.0.0.52:3306;
Empty set (0.00 sec)

  查看是否添加成功

mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address        | state | type |
+-------------+----------------+-------+------+
|           1 | 10.0.0.55:3306 | up    | rw   |
|           2 | 10.0.0.53:3306 | up    | ro   |
|           3 | 10.0.0.52:3306 | up    | ro   |
+-------------+----------------+-------+------+
3 rows in set (0.00 sec)

 保存到配置文件中

mysql> SAVE CONFIG;

1.7.9 鏈接數據庫查看負載

經過atlas登錄數據,注意,使用的是數據庫上的用戶及密碼

shell> mysql -umha -pmha -h127.0.0.1 -P33060

第一次查詢server_id

mysql> show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 53    |
+---------------+-------+
1 row in set (0.00 sec)

第二次查詢server_id

mysql> show variables like "server_id";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 52    |
+---------------+-------+
1 row in set (0.00 sec)

​ *經過上面能夠看到負載成功*

1.7.10 讀寫分離的說明

  Atlas會透明的將事務語句和寫語句發送至主庫執行,讀語句發送至從庫執行。具體如下語句會在主庫執行:

顯式事務中的語句

autocommit=0時的全部語句

含有select GET_LOCK()的語句

除SELECT、SET、USE、SHOW、DESC、EXPLAIN外的。

從庫負載均衡配置

proxy-read-only-backend-addresses=ip1:port1@權重,ip2:port2@權重

1.7.11 Atlas高級功能

自動分表

  使用Atlas的分表功能時,首先須要在配置文件test.cnf設置tables參數。

tables參數設置格式:數據庫名.表名.分表字段.子表數量,好比:

你的數據庫名叫school,表名叫stu,分表字段叫id,總共分爲2張表,那麼就寫爲school.stu.id.2,若是還有其餘的分表,以逗號分隔便可。

用戶須要手動創建2張子表(stu_0,stu_1,注意子表序號是從0開始的)。

全部的子表必須在DB的同一個database裏。

當經過Atlas執行(SELECT、DELETE、UPDATE、INSERT、REPLACE)操做時,Atlas會根據分表結果(id%2=k),定位到相應的子表(stu_k)。

例如,執行select * from stu where id=3;,Atlas會自動從stu_1這張子表返回查詢結果。

但若是執行SQL語句(select * from stu;)時不帶上id,則會提示執行stu表不存在。

Atles功能的說明

Atlas暫不支持自動建表和跨庫分表的功能。

Atlas目前支持分表的語句有SELECT、DELETE、UPDATE、INSERT、REPLACE。

IP****過濾:client-ips

  該參數用來實現IP過濾功能。

  在傳統的開發模式中,應用程序直接鏈接DB,所以DB會對部署應用的機器(好比web服務器)的IP做訪問受權。

在引入中間層後,由於鏈接DB的是Atlas,因此DB改成對部署Atlas的機器的IP做訪問受權,若是任意一臺客戶端均可以鏈接Atlas,就會帶來潛在的風險。

  client-ips參數用來控制鏈接Atlas的客戶端的IP,能夠是精確IP,也能夠是IP段,以逗號分隔寫在一行上便可。

  如: client-ips=192.168.1.2, 192.168.2

  這就表明192.168.1.2這個IP和192.168.2.*這個段的IP能夠鏈接Atlas,其餘IP均不能鏈接。若是該參數不設置,則任意IP都可鏈接Atlas。若是設置了client-ips參數,且Atlas前面掛有LVS,則必須設置lvs-ips參數,不然能夠不設置lvs-ips。

SQL****語句黑白名單功能: Atlas會屏蔽不帶where條件的delete和update操做,以及sleep函數。

1.8 Atlas-Sharding版本

1.8.1 版本介紹

  Sharding的基本思想就是把一個數據表中的數據切分紅多個部分, 存放到不一樣的主機上去(切分的策略有多種), 從而緩解單臺機器的性能跟容量的問題.

  sharding是一種水平切分, 適用於單表數據龐大的情景. 目前atlas支持靜態的

  sharding方案, 暫時不支持數據的自動遷移以及數據組的動態加入.

  Atlas以表爲單位sharding, 同一個數據庫內能夠同時共有sharding的表和不sharding的表, 不sharding的表數據存在未sharding的數據庫組中.

  目前Atlas sharding支持insert, delete, select, update語句, 只支持不跨shard的事務. 全部的寫操做如insert, delete, update只能一次命中一個組, 不然會報"ERROR 1105 (HY000):write operation is only allow to one dbgroup!"錯誤.

  因爲sharding取替了Atlas的分表功能, 因此在Sharding分支裏面, Atlas單機分表的功能已經移除, 配置tables將不會再有效.

1.8.2 Atlas-Sharding架構

file

1.8.3 Sharding配置示例

  Atlas支持非sharding跟sharding的表共存在同一個Atlas中, 2.2.1以前的配置能夠直接運行. 以前的配置如

proxy-backend-addresses = 192.168.0.12:3306
proxy-read-only-backend-addresses = 192.168.0.13:3306,192.168.0.14:3306 ...

  這配置了一個master和兩個slave,這屬於非sharding的組, 全部非sharding的表跟語句都會發往這個組內.

  因此以前沒有Sharding的Atlas的表能夠無縫的在新版上使用,

注意: 非Sharding的組只能配置一個, 而sharding的組能夠配置多個. 下面的配置, 配置了Sharding的組, 注意與上面的配置區分

[shardrule-0]
table = test.sharding_test

  分表名,有數據庫+表名組成 t

ype = range

  sharding類型:range 或 hash

shard-key = id

  sharding 字段

groups = 0:0-999,1:1000-1999

  分片的group,若是是range類型的sharding,則groups的格式是:group_id:id範圍。若是是hash類型的sharding,則groups的格式是:group_id。例如groups = 0, 1

[group-0]
proxy-backend-addresses=192.168.0.15:3306
proxy-read-only-backend-addresses=192.168.0.16:3306
[group-1]
proxy-backend-addresses=192.168.0.17:3306
proxy-read-only-backend-addresses=192.168.0.18:3306

1.8.4 Sharding限制

關於支持的語句

  Atlas sharding只對sql語句提供有限的支持, 目前支持基本的Select, insert/replace, delete,update語句,支持所有的Where語法(SQL-92標準), 不支持DDL(create drop alter)以及一些管理語句,DDL請直連MYSQL執行, 請只在Atlas上執行Select, insert, delete, update(CRUD)語句.

  對於如下語句, 若是語句命中了多臺dbgroup, Atlas均未作支持(若是語句只命中了一個dbgroup, 如 select count(*) from test where id < 1000, 其中dbgroup0範圍是0 - 1000, 那麼這些特性都是支持的)Limit Offset(支持Limit)

Order by

Group by Join

ON

Count, Max, Min等函數

增長節點

  注意: 暫時只支持range方式的節點擴展, hash方式因爲須要數據遷移, 暫時未作支持.

  擴展節點在保證原來節點的範圍不改變的狀況下, 如已有dbgroup0爲範圍0 - 999, dbgroup1爲範圍 1000-1999, 這個時候能夠增長範圍>2000的節點. 如增長一個節點爲2000 - 2999, 修改配置文件, 重啓Atlas便可.

來源:博客園 http://dwz.date/d8qV

歡迎關注公衆號 【碼農開花】一塊兒學習成長 我會一直分享Java乾貨,也會分享免費的學習資料課程和麪試寶典 回覆:【計算機】【設計模式】【面試】有驚喜哦

相關文章
相關標籤/搜索