Mysql實現高可用
MMM
MMM(master-master replication manager for mysql)mysql主主複製管理器。
MMM是一套靈活的腳本程序,基於perl實現,用來對mysql replication進行監控和故障遷移,並能管理mysql master-master複製的配置(同一時間只有一個節點是可寫的)。
MMM的監管端是會提供多個虛擬ip(vip),包括一個可寫的vip,多個可讀的vip,經過監管的管理,這些ip會綁定在可用的mysql上,當某一臺mysql宕機時,會將vip遷移到其餘mysql。
mmm_mond:監控進程,負責全部的監控工做,決定和處理全部節點角色活動。所以,腳本須要在監管上運行。
mmm_agentd:運行在每一個msql服務器上的代理進程,完成監控的探針工做和執行簡單的遠端服務設置。此腳本須要在被監管機上運行。
mmm_control:一個簡單的腳本,提供管理mmm_mond進行的命令。
MMM實現mysql高可用
MMM(Master-Master replication manager for MySQL)是一套支持雙主故障切換和雙主平常管理的腳本程序。
MMM使用Perl語言開發,主要用來監控和管理MySQL Master-Master(雙主)複製,雖然叫作雙主複製,可是業務上同一時刻只容許對一個主進行寫入,另外一臺備選主上提供部分讀服務,以加速在主主切換時刻備選主的預熱,能夠說MMM這套腳本程序一方面實現了故障切換的功能,另外一方面其內部附加的工具腳本也能夠實現多個slave的read負載均衡。
MMM提供了自動和手動兩種方式移除一組服務器中複製延遲較高的服務器的虛擬ip,同時它還能夠備份數據,實現兩節點之間的數據同步等。
因爲MMM沒法徹底的保證數據一致性,因此MMM適用於對數據的一致性要求不是很高,可是又想最大程度的保證業務可用性的場景。
對於那些對數據的一致性要求很高的業務,很是不建議採用MMM這種高可用架構。
MMM項目來自 Google:http://code.google.com/p/mysql-master-master
官方網站爲:http://mysql-mmm.org
下面咱們經過一個實際案例來充分了解MMM的內部架構,以下圖所示。
具體的配置信息以下所示:
角色 ip地址 主機名字 server-id
monitoring 192.168.0.30 db2 -
master1 192.168.0.60 db1 1
master2 192.168.0.50 db2 2
slave1 192.168.0.40 db3 3
業務中的服務ip信息以下所示:
ip地址 角色 描述
192.168.0.108 write 應用程序鏈接該ip對主庫進行寫請求
192.168.0.88 read 應用程序鏈接該ip進行讀請求
192.168.0.98 read 應用程序鏈接該ip進行讀請求
具體的配置步驟以下:
(1)主機配置
配置/etc/hosts,在全部主機中,添加全部的主機信息:
[root@192.168.0.30 ~]# cat /etc/hosts
192.168.0.60 db1
192.168.0.50 db2
192.168.0.40 db3
[root@192.168.0.30 ~]#
(2)首先在3臺主機上安裝mysql和搭建複製(192.168.0.60和192.168.0.50互爲主從,192.168.0.40爲192.168.0.60的從)具體的複製搭建這裏就省略,而後在每一個mysql的配置文件中加入如下內容,注意server_id 不能重複。
db1(192.168.0.60)上:
server-id = 1
log_slave_updates = 1
auto-increment-increment = 2
auto-increment-offset = 1
db2(192.168.0.50)上:
server-id = 2
log_slave_updates = 1
auto-increment-increment = 2
auto-increment-offset = 2
db3(192.168.0.40)上:
server-id = 3
log_slave_updates = 1
上面的id不必定要按順序來,只要沒有重複便可。
(3)安裝MMM所須要的Perl模塊(全部服務器)執行該腳本,也能夠安裝epel源,而後yum -y install mysql-mmm*來安裝MMM:
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum -y install mysql-mmm*
[root@192.168.0.60 ~]# cat install.sh
#!/bin/bash
wget http://xrl.us/cpanm --no-check-certificate
mv cpanm /usr/bin
chmod 755 /usr/bin/cpanm
cat > /root/list << EOF
install Algorithm::Diff
install Class::Singleton
install DBI
install DBD::mysql
install File::Basename
install File::stat
install File::Temp
install Log::Dispatch
install Log::Log4perl
install Mail::Send
install Net::ARP
install Net::Ping
install Proc::Daemon
install Thread::Queue
install Time::HiRes
EOF
for package in `cat /root/list`
do
cpanm $package
done
[root@192.168.0.60 ~]#
(4)下載mysql-mmm軟件,在全部服務器上安裝:
[root@192.168.0.60 ~]# wget http://mysql-mmm.org/_media/:mmm2:mysql-mmm-2.2.1.tar.gz
[root@192.168.0.60 ~]# mv :mmm2:mysql-mmm-2.2.1.tar.gz mysql-mmm-2.2.1.tar.gz
[root@192.168.0.60 ~]# tar xf mysql-mmm-2.2.1.tar.gz
[root@192.168.0.60 ~]# cd mysql-mmm-2.2.1
[root@192.168.0.60 mysql-mmm-2.2.1]# make install
mysql-mmm安裝後的主要拓撲結構以下所示(注意:yum安裝的和源碼安裝的路徑有所區別):
目錄 介紹
/usr/lib/perl5/vendor_perl/5.8.8/MMM MMM使用的主要perl模塊
/usr/lib/mysql-mmm MMM使用的主要腳本
/usr/sbin MMM使用的主要命令的路徑
/etc/init.d/ MMM的agent和monitor啓動服務的目錄
/etc/mysql-mmm MMM配置文件的路徑,默認因此的配置文件位於該目錄下
/var/log/mysql-mmm 默認的MMM保存日誌的位置
到這裏已經完成了MMM的基本需求,接下來須要配置具體的配置文件,其中mmm_common.conf,mmm_agent.conf爲agent端的配置文件,mmm_mon.conf爲monitor端的配置文件。
(5)配置agent端的配置文件,須要在db1,db2,db3上分別配置。
在db1主機上配置agent配置文件:
[root@192.168.0.60 ~]# cd /etc/mysql-mmm/
[root@192.168.0.60 mysql-mmm]# cat mmm_common.conf
active_master_role writer
<host default>
cluster_interface eth1
pid_path /var/run/mmm_agentd.pid
bin_path /usr/lib/mysql-mmm/
replication_user repl
replication_password 123456
agent_user mmm_agent
agent_password mmm_agent
</host>
<host db1>
ip 192.168.0.60
mode master
peer db2
</host>
<host db2>
ip 192.168.0.50
mode master
peer db1
</host>
<host db3>
ip 192.168.0.40
mode slave
</host>
<role writer>
hosts db1, db2
ips 192.168.0.108
mode exclusive
</role>
<role reader>
hosts db2, db3
ips 192.168.0.88, 192.168.0.98
mode balanced
</role>
[root@192.168.0.60 mysql-mmm]#
其中replication_user用於檢查複製的用戶,agent_user爲agent的用戶,mode標明是否爲主或者備選主,或者從庫。mode exclusive主爲獨佔模式,同一時刻只能有一個主,<role write>中hosts表示目前的主庫和備選主的真實主機ip或者主機名,ips爲對外提供的虛擬機ip地址,<role readr>中hosts表明從庫真實的ip和主機名,ips表明從庫的虛擬ip地址。
因爲db2和db3兩臺主機也要配置agent配置文件,咱們直接把mmm_common.conf從db1拷貝到db2和db3兩臺主機的/etc/mysql-mmm下。
注意:monitor主機要須要:
scp /etc/mysql-mmm/mmm_common.conf db2:/etc/mysql-mmm/
scp /etc/mysql-mmm/mmm_common.conf db3:/etc/mysql-mmm/
分別在db1,db2,db3三臺主機的/etc/mysql-mmm配置mmm_agent.conf文件,分別用不一樣的字符標識,注意這三臺機器的this db1這塊要想,好比本環境中,db1要配置this db1,db2要配置爲this db2,而db3要配置爲this db3。
在db1(192.168.0.60)上:
[root@192.168.0.60 ~]# cat /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1
[root@192.168.0.60 ~]#
在db2(192.168.0.50)上:
[root@192.168.0.50 ~]# cat /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db2
[root@192.168.0.50 ~]#
在db3(192.168.0.40)上:
[root@192.168.0.40 ~]# cat /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db3
[root@192.168.0.40 ~]#
在db2(192.168.0.30)配置monitor的配置文件:
[root@192.168.0.30 ~]# cat /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
<monitor>
ip 127.0.0.1
pid_path /var/run/mysql-mmm/mmm_mond.pid
bin_path /usr/libexec/mysql-mmm
status_path /var/lib/mysql-mmm/mmm_mond.status
ping_ips 192.168.0.40,192.168.0.50,192.168.0.60
auto_set_online 60
</monitor>
<host default>
monitor_user mmm_monitor
monitor_password mmm_monitor
</host>
debug 0
[root@192.168.0.30 ~]#
這裏只在原有配置文件中的ping_ips添加了整個架構被監控主機的ip地址,而在<host default>中配置了用於監控的用戶。
(6)建立監控用戶,這裏須要建立3個監控用戶,具體描述以下:
用戶名 描述 權限
monitor user MMM的monitor端監控全部的mysql數據庫的狀態用戶 REPLICATION CLIENT
agent user 主要是MMM客戶端用於改變的master的read_only狀態用戶 SUPER,REPLICATION CLIENT,PROCESS
repl 用於複製的用戶 REPLICATION SLAVE
在3臺服務器(db1,db2,db3)進行受權,由於我以前的主主複製,以及主從已是ok的,因此我在其中一臺服務器執行就ok了。用於複製的帳號以前已經有了,因此這裏就受權兩個帳號。
mysql> GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent'@'192.168.0.%' IDENTIFIED BY 'mmm_agent';
Query OK, 0 rows affected (0.08 sec)
mysql> GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor'@'192.168.0.%' IDENTIFIED BY 'mmm_monitor';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.03 sec)
mysql>
若是是從頭至尾重新搭建,則加上另一個複製帳戶(分別在3臺服務器都須要執行這3條SQL):
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.0.%' IDENTIFIED BY '123456';
(7)啓動agent服務。
最後分別在db1,db2,db3上啓動agent,並在db2(192.168.0.30)上啓動monitor程序:
[root@192.168.0.60 ~]# /etc/init.d/mysql-mmm-agent start
Daemon bin: '/usr/sbin/mmm_agentd'
Daemon pid: '/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Ok
[root@192.168.0.60 ~]#
[root@192.168.0.50 ~]# /etc/init.d/mysql-mmm-agent start
Starting MMM Agent Daemon: [ OK ]
[root@192.168.0.50 ~]#
由於我有些使用yum安裝的,因此啓動信息有些不同。^_^
[root@192.168.0.40 ~]# /etc/init.d/mysql-mmm-agent start
Starting MMM Agent Daemon: [ OK ]
[root@192.168.0.40 ~]#
啓動monitor:
[root@192.168.0.30 ~]# /etc/init.d/mysql-mmm-monitor start
Starting MMM Monitor Daemon: [ OK ]
[root@192.168.0.30 ~]#
其中agent的日誌存放在/var/log/mysql-mmm/mmm_agentd.log,monitor日誌放在/var/log/mysql-mmm/mmm_mond.log,啓動過程當中有什麼問題,一般日誌都會有詳細的記錄。
(8)在monitor主機上檢查集羣主機的狀態:
[root@192.168.0.30 ~]# mmm_control checks all
db2 ping [last change: 2014/04/18 00:29:01] OK
db2 mysql [last change: 2014/04/18 00:29:01] OK
db2 rep_threads [last change: 2014/04/18 00:29:01] OK
db2 rep_backlog [last change: 2014/04/18 00:29:01] OK: Backlog is null
db3 ping [last change: 2014/04/18 00:29:01] OK
db3 mysql [last change: 2014/04/18 00:29:01] OK
db3 rep_threads [last change: 2014/04/18 00:29:01] OK
db3 rep_backlog [last change: 2014/04/18 00:29:01] OK: Backlog is null
db1 ping [last change: 2014/04/18 00:29:01] OK
db1 mysql [last change: 2014/04/18 00:29:01] OK
db1 rep_threads [last change: 2014/04/18 00:29:01] OK
db1 rep_backlog [last change: 2014/04/18 00:29:01] OK: Backlog is null
[root@192.168.0.30 ~]#
(9)在monitor主機上檢查集羣環境在線情況:
[root@192.168.0.30 ~]# mmm_control show
db1(192.168.0.60) master/ONLINE. Roles: writer(192.168.0.108)
db2(192.168.0.50) master/ONLINE. Roles: reader(192.168.0.88)
db3(192.168.0.40) slave/ONLINE. Roles: reader(192.168.0.98)
[root@192.168.0.30 ~]#
(10)online(上線)全部主機:
我這裏主機已經在線了,若是沒有在線,可使用下面的命令將相關主機online
[root@192.168.0.30 ~]# mmm_control set_online db1
OK: This host is already ONLINE. Skipping command.
[root@192.168.0.30 ~]#
提示主機已經在線,已經跳過命令執行了。
到這裏整個集羣就配置完成了。從輸出中能夠看到虛擬ip 192.168.0.108已經順利添加到主機192.168.0.60上做爲主對外提供寫服務,虛擬ip 192.168.0.88添加到主機192.168.0.50上對外提供讀服務,而虛擬ip 192.168.0.98添加到192.168.0.40上對外提供讀服務。
MMM高可用測試
咱們已經完成高可用環境的搭建了,下面咱們就能夠作MMM的HA測試咯。首先查看整個集羣的狀態,能夠看到整個集羣狀態正常。
[root@192.168.0.30 ~]# mmm_control show
db1(192.168.0.60) master/ONLINE. Roles: writer(192.168.0.108)
db2(192.168.0.50) master/ONLINE. Roles: reader(192.168.0.88)
db3(192.168.0.40) slave/ONLINE. Roles: reader(192.168.0.98)
[root@192.168.0.30 ~]#
模擬db2(192.168.0.50 )宕機,手動中止mysql服務,觀察monitor日誌:
[root@192.168.0.30 ~]# tail -f /var/log/mysql-mmm/mmm_mond.log
2014/04/18 00:55:53 FATAL State of host 'db2' changed from ONLINE to HARD_OFFLINE (ping: OK, mysql: not OK)
從日誌發現db2的狀態有ONLINE轉換爲HARD_OFFLINE
從新查看集羣的最新狀態:
[root@192.168.0.30 ~]# mmm_control show
db1(192.168.0.60) master/ONLINE. Roles: writer(192.168.0.108)
db2(192.168.0.50) master/HARD_OFFLINE. Roles:
db3(192.168.0.40) slave/ONLINE. Roles: reader(192.168.0.88), reader(192.168.0.98)
[root@192.168.0.30 ~]#
重啓db2,能夠看到db2由HARD_OFFLINE轉到AWAITING_RECOVERY。這裏db2再次接管讀請求。
[root@192.168.0.30 ~]# mmm_control show
db1(192.168.0.60) master/ONLINE. Roles: writer(192.168.0.108)
db2(192.168.0.50) master/ONLINE. Roles: reader(192.168.0.88)
db3(192.168.0.40) slave/ONLINE. Roles: reader(192.168.0.98)
[root@192.168.0.30 ~]#
模擬db1主庫宕機:
查看集羣狀態:
[root@192.168.0.30 ~]# mmm_control show
db1(192.168.0.60) master/HARD_OFFLINE. Roles:
db2(192.168.0.50) master/ONLINE. Roles: reader(192.168.0.88), writer(192.168.0.108)
db3(192.168.0.40) slave/ONLINE. Roles: reader(192.168.0.98)
[root@192.168.0.30 ~]#
查看MMM日誌:
[root@192.168.0.30 ~]# tail -f /var/log/mysql-mmm/mmm_mond.log
2014/04/18 01:09:20 FATAL State of host 'db1' changed from ONLINE to HARD_OFFLINE (ping: OK, mysql: not OK)
從上面能夠發現,db1由之前的ONLINE轉化爲HARD_OFFLINE,移除了寫角色,由於db2是備選主,因此接管了寫角色,db3指向新的主庫db2,應該說db3實際上找到了db2的sql如今的位置,即db2 show master返回的值,而後直接在db3上change master to到db2。
db1,db2,db3之間爲一主兩從的複製關係,一旦發生db2,db3延時於db1時,這個時刻db1 mysql宕機,db3將會等待數據追上db1後,再從新指向新的主db2,進行change master to db2操做,在db1宕機的過程當中,一旦db2落後於db1,這時發生切換,db2變成了可寫狀態,數據的一致性將會沒法保證。
總結:
MMM不適用於對數據一致性要求很高的環境。可是高可用徹底作到了。
參考資料:
http://mysql-mmm.org/mmm2:guide
MHA
MHA是一款開源的MySQL高可用程序,MHA在監控到master節點故障時,會自動提高其中擁有最新數據的slave節點成爲新的master節點。
在此期間,MHA會獲取其餘節點的額外信息來避免一致性方面的問題,也就是MHA會獲取其餘從節點中的數據信息,並將信息發給最接近主節點的從節點,這樣主節點故障時會提高此從節點爲主節點,而此從節點擁有其餘從節點全部的數據信息。
MHA還提供了master節點的在線切換功能,即按需切換master/slave節點。
實現master HA
環境
A:192.168.213.251,node1,MHA
B:192.168.213.252,node2,主
C:192.168.213.253,node3,從
D:192.168.213.254,node4,從
1》同步各節點的時間。
2》能夠修改/etc/hosts文件,使各節點能使用主機名交互
192.168.213.251 node1
192.168.213.252 node2
192.168.213.253 node3
192.168.213.254 node4
3》使各節點能基於ssh祕鑰的驗證
在node1節點上操做
ssh-keygen ##生成公鑰私鑰對
ssh-copy-id node1: ##將祕鑰文件保存在本身的家目錄下,會自動保存到root家目錄的.ssh目錄中
[root@node1 ~]# ls .ssh ##能夠發現公鑰 和私鑰對及祕鑰文件都已經生成
authorized_keys id_rsa id_rsa.pub known_hosts
scp -r .ssh/ node2:
scp -r .ssh/ node3:
scp -r .ssh/ node4:
##將此目錄傳給其餘節點,這樣各節點就能夠基於key的驗證互相通信了
注意:基於ssh的key的驗證和可以互相解析主機名是此實驗的前提
4》搭建好主從複製的集羣環境,並確保複製運行無錯誤
在node2上的配置
vim /etc/my.cnf.d/server.cnf ##開啓二進制日誌和中繼日誌
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
log_bin = bin-log
server_id = 1
relay-log = relay-log
在node3和node4上的配置
vim /etc/my.cnf.d/server.cnf
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
relay-log = relay-log
server_id = 2 ##id號必須惟一
log-bin = bin-log
relay_log_purge = 0 ##不修剪中繼日誌
read_only = 1 ##只讀
5》在主從節點上受權一個用戶,用於MHA鏈接到各主從節點進行管理及各主從節點間通信用
在node2上操做,建立後其餘從節點也會有這個用戶
MariaDB [(none)]> grant all on *.* to mhaadmin@'192.168.213.%' identified by 'centos';
MariaDB [(none)]> flush privileges;
注意:這裏受權的用戶不是隻給MHA使用,其餘的主從節點也要使用這個用戶進行互相鏈接通信,因此受權的時候要保證IP地址段對全部節點都能經過這個帳號鏈接彼此
6》下載MHA軟件包並安裝
在https://github.com/官方網站上下載,搜索的時候輸入mha
或者到以下網站上去下載
https://code.google.com/p/mysql-master-ha/wiki/Downloads?tm=2。
mha4mysql-manager-0.56-0.el6.noarch.rpm
mha4mysql-node-0.56-0.el6.noarch.rpm
在node1節點上安裝mha4mysql-manager-0.56-0.el6.noarch.rpm和mha4mysql-node-0.56-0.el6.noarch.rpm兩個軟件包
注意:安裝mha4mysql-manager-0.56-0.el6.noarch.rpm時會依賴會多的包,因此yum安裝以前要把本身的yum倉庫配置以下
root@node1 ~]# vim /etc/yum.repos.d/aliyun.repo
[aliyun]
name=aliyun
baseurl=https://mirrors.aliyun.com/epel/7/x86_64/
gpgcheck=0
安裝以前要把網絡配置好,保證node1節點能訪問互聯網
在其餘node二、node三、node4節點上只安裝mha4mysql-node-0.56-0.el6.noarch.rpm包便可
7》初始化MHA
mkdir /etc/masterha ##建立一個配置文件
cd /etc/masterha
vim test.cnf
[server default]
user=mhaadmin ##用戶MHA和各節點互相通信的管理用戶
password=centos
manager_workdir=/data/masterha/test ##MHA的工做目錄
manager_log=/data/masterha/test/manager.log ##MHA的日誌目錄
remote_workdir=/data/masterha/test ##各節點的工做目錄
ssh_user=root ##ssh鏈接的用戶,由於基於key的驗證了,因此不用密碼
repl_user=repluser ##主從複製時的用戶
repl_password=rpluser
ping_interval=1 ##MHA監控各節點的時間間隔
[server1]
hostname=192.168.213.252
candidate_master=1 ##是否能夠作爲候選,也就是主節點掛了,是否能夠提高爲主節點
[server2]
hostname=192.168.213.253
candidate_master=1
[server3]
hostname=192.168.213.254
candidate_master=1
8》檢查各節點ssh互相通信
masterha_check_ssh --conf=/etc/masterha/app1.cnf
All SSH connection tests passed successfully.
檢查管理的mysql複製集羣的鏈接配置參數
masterha_check_repl --conf=/etc/masterha/app1.cnf
MySQL Replication Health is OK.
9》測試
在node1上啓動MHA,並關閉node2節點的mariadb服務進行測試
masterha_manager --conf=/etc/masterha/test.cnf ##發現啓動MHA後爲前臺運行的
在node2節點上關閉服務
systemctl stop mariadb
在node4上查看
MariaDB [(none)]> show slave status \G ##發現node3變成了主,切換成功
在node1節點上
masterha_manager --conf=/etc/masterha/test.cnf
MySQL Replication Health is NOT OK! ##發現主從複製集羣已經not ok
10》如何恢復node2?將node2變爲node3的從
在node2上進行以下配置
vim /etc/my.cnf.d/server.cnf
[server]
skip_name_resolve = on
innodb_file_per_table = on
max_connections = 20000
log_bin = bin-log
server_id = 1
relay-log = relay-log
relay_log_purge = 0 ##不修剪中繼日誌
read_only = on ##只讀,修改這兩項就能夠
將node2變爲node3的從
[root@node2 ~]#mysql
MariaDB [(none)]> change master to master_user='rpluser',master_host='192.168.213.253',master_password='1234',master_log_file='bin-log.000003',master_log_pos=245;
##將本身變成node3的從,若是node2修復時間很長,恢復爲從的時候要先將主上的數據進行一次全量備份,在node2上恢復後再進行恢復爲從的操做,保證不丟失數據
MariaDB [(none)]> start slave;
MariaDB [(none)]> show slave status \G
在node1上檢查
masterha_check_repl --conf=/etc/masterha/test.cnf ---發現ok了
這樣咱們又能夠啓動監控了,爲了保證監控時在後臺執行,而且記錄在日誌中能夠進行以下操做
[root@node1 masterha]# nohup masterha_manager --conf=/etc/masterha/test.cnf &> /data/masterha/app1/manager.log &
故障轉移完成後,manager將會自動中止,此時使用masterha_check_status --conf=/etc/masterha/test.cnf 命令將會遇到錯誤提示
test is stopped(2:NOT_RUNNING).
masterha_stop --conf=/etc/masterha/test.cnf ##中止MHA