mysql 集群操作系统_高性能MySQL集群详解(二)
一.通過Keepalived搭建MySQL雙主模式的高可用集群系統
1.MySQL Replication介紹:
MySQL Replication是MySQL自身提供的一個主從復制功能,其實也就是一臺MySQL服務器(稱為Slave)從另一臺MySQL服務器(稱為Master)上復制日志,然后解析日志并應用到自身的過程。MySQL Replication是單向、異步復制,基本復制過程為:Master服務器首先將更新寫入二進制日志文件,并維護文件的一個索引以跟蹤日志的循環,這些日志文件可以發送到Slave服務器進行更新。當一臺Slave服務器連接Master服務器時,它從Master服務器日志中讀取上一次成功更新的位置。然后Slave服務器開始接收從上一次完成更新后發生的所有更新,所有更新完成,將等待主服務器通知新的更新。
MySQL Replication支持鏈式復制,也就是說Slave服務器下還可以再鏈接Slave服務器,同時Slave服務器也可以充當Master服務器角色。這里需要注意的是,在MySQL主從復制中,所有表的更新必須在Master服務器上進行,Slave服務器僅能提供查詢操作。
基于單向復制的MySQL Replication技術有如下優點:
□增加了MySQL應用的健壯性,如果Master服務器出現問題,可以隨時切換到Slave服務器,繼續提供服務。
■可以將MySQL讀、寫操作分離,寫操作只在Master服務器完成,讀操作可在多個Slave服務器上完成,由于Master服務器和Slave服務器是保持數據同步的,因此不會對前端業務系統產生影響。同時,通過讀、寫的分離,可以大大降低MySQL的運行負荷。
□在網絡環境較好,業務量不是很大的環境中,Slave服務器同步數據非常快,基本可以達到實時同步,并且,Slave服務器在同步過程中不會干擾Master服務器。
MySQL Replication支持多種類型的復制方式,常見的有基于語句的復制、基于行的復制和混合類型的復制。下面分別進行介紹。
(1)基于語句的復制
MySQL默認采用基于語句的復制,效率很高。基本方式是:在Master服務器上執行的SQL語句,在Slave服務器上再次執行同樣的語句。而一旦發現沒法精確復制時,會自動選擇基于行的復制。
(2)基于行的復制
基本方式為:把Master服務器上改變的內容復制過去,而不是把SQL語句在從服務器上執行一遍,從MySQL5.0開始支持基于行的復制。
(3)混合類型的復制
其實就是上面兩種類型的組合,默認采用基于語句的復制,如果發現基于語句的復制無法精確完成,就會采用基于行的復制。
2.MySQL Replication實現原理:
MySQL Replication是一個從Master復制到一臺或多臺Slave的異步過程,在Master與Slave之間實現整個復制過程主要由三個線程來完成,其中一個IO線程在Master端,另兩個線程(SQL線程和IO線程)在Slave端。
要實現MySQL Replication,首先在Master服務器上打開MySQL的Binary Log(產生二進制日志文件)功能,因為整個復制過程實際上就是Slave從Master端獲取該日志,然后在自身上將二進制文件解析為SQL語句并完全順序地執行SQL語句所記錄的各種操作。更詳細的過程如下。
1)首先Slave上的IO線程連接上Master,然后請求從指定日志文件的指定位置或者從最開始的日志位置之后的日志內容。
2)Master在接收到來自Slave的IO線程請求后,通過自身的IO線程,根據請求信息讀取指定日志位置之后的日志信息,并返回給Slave端的IO線程。返回信息中除了日志所包含的信息之外,還包括此次返回的信息在Master端對應的Binary Log文件的名稱以及在Binary Log中的位置。
3)Slave的IO線程接收到信息后,將獲取到的日志內容依次寫入Slave端的Relay Log文件(類似于mysql-relay-bin.xxxxxx)的最后,并且將讀取到的Master端的Binary Log的文件名和位置記錄到一個名為master-info的文件中,以便在下一次讀取的時候能迅速定位開始往后讀取日志信息的位置。
4)Slave的SQL線程在檢測到Relay Log文件中新增加了內容后,會馬上解析該Relay Log文件中的內容,將日志內容解析為SQL語句,然后在自身執行這些SQL,由于是在Master端和Slave端執行了同樣的SQL操作,所以兩端的數據是完全一樣的。至此整個復制過程結束。
3.MySQL Replication常用架構
MySQL Replication技術在實際應用中有多種實現架構,常見的有:
☆一主一次,即一臺Master服務器和一臺Slave服務器。這是最常見的架構。
★一主多從,即一臺Master服務器和兩臺或兩臺以上Slave服務器,經常用在寫操作不頻繁、查詢量比較大的業務環境中。
☆主主互備,又稱雙主互備,即兩臺MySQL Server互相將對方作為自己的Master,自己又同時作為對方的Slave來進行復制。主要用于對MySQL寫操作要求比較高的環境中,避免了MySQL單點故障。
★雙主多從,其實就是雙主互備,然后再加上多臺Slave服務器。主要用于對MySQL寫操作要求比較高,同時查詢量比較大的環境中。
其實可以根據具體的情況靈活地將Master/Slave結構進行變化組合,但萬變不離其宗,在進行MySQL Replication的各種部署之前,必須遵守的規則如下:
◇同一時刻只能有一臺Master服務器進行寫操作。
◆一臺Master服務器可以有多臺Slave服務器。
◇無論是Master服務器還是Slave服務器,都要確保各自的ServerID唯一,否則雙主互備就會出現問題。
◆一臺Slave服務器可以將其從Master服務器獲得的更新信息傳遞給其他的Slave服務器。
4.MySQL主主互備模式架構
企業級MySQL集群具備高可用、可擴展、易管理、低成本的特點。下面將介紹企業環境中經常應用的一個解決方案,即MySQL的雙主互備架構,主要設計思路是通過MySQL Replication技術將兩臺MySQL Server互相將對方作為自己的Master,自己又同時作為對方的Slave來進行復制。這樣就實現了高可用架構中的數據同步功能,同時,將采用Keepalived來實現MySQL的自動failover。在這種架構中,雖然兩臺MySQL Server互為主從,但同一時刻只能有一臺MySQL Server可讀寫,而另一臺MySQL Server只能進行讀操作,這樣可保證數據的一致性。整個架構如下圖:
5.MySQL主主互備模式配置
MySQL主從復制的配置還是比較簡單的,僅僅需要修改MySQL配置文件即可,這里要配置的是主主互備模式,但配置過程和一主一從結構是完全一樣的,配置環境如下:
主機名? ? ? 操作系統版本? ? ??MySQL版本? ? 主機IP? ? MySQL VIP
DB1(Master)??CentOS release 6.7? mysql-5.1.73? 10.0.0.35? 10.0.0.40
DB2(Slave)? ?CentOS release 6.7? mysql-5.1.73? 10.0.0.36
1.修改MySQL配置文件
在默認情況下,MySQL的配置文件是/etc/my.cnf,首先修改DB1主機的配置文件,在/etc/my.cnf文件中的“[mysqld]”段添加如下內容:
server-id=1
log-bin=mysql-bin
relay-log=mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
然后修改DB2主機的配置文件,在/etc/my.cnf文件中的“[mysqld]”段添加如下內容:
server-id=2
log-bin=mysql-bin
relay-log=mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%
其中,server-id是節點標識,主、從節點不能相同,必須全局唯一。log-bin表示開啟MySQL的binlog日志功能。“mysql-bin”表示日志文件的命名格式,會生成文件名為mysql-bin.000001、mysql-bin.000002等的日志文件。relay-log用來定義relay-log日志文件的命名格式。replicate-wild-ignore-table是個復制過濾選項,可以過濾不需要復制的數據庫或表,例如“mysql.%”表示不復制MySQL庫下的所有對象,其他以此類推。與此對應的是replicate-wild-do-table選項,用來指定需要復制的數據庫或表。
這里需要注意的是,不要在主庫上使用binlog-do-db或binlog-ignore-db選項,也不要在從庫上使用replicate-do-db或replicate-ignore-db選項,因為這樣可能產生跨庫更新失敗的問題。推薦在從庫使用replicate-wild-do-table和replicate-wild-ignore-table兩個選項來解決復制過濾問題。
2.手動同步數據庫
如果DB1上已經有MySQL數據,那么在執行主主互備之前,需要將DB1和DB2上兩個MySQL的數據保持同步,首先在DB1上備份MySQL數據,執行如下SQL語句:
mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.01 sec)
不要退出這個終端,否則這個鎖就失效了。在不退出終端的情況下,再開啟一個終端直接打包壓縮數據文件或使用mysqldump工具導出數據。這里通過打包mysql文件來完成數據的備份,操作過程如下:
[root@db1 ~]# cd /var/lib/
[root@db1 ~]# tar zcvf mysql.tar.gz mysql
[root@db1 ~]# scp mysql.tar.gz db2:/var/lib/
將數據傳輸到DB2后,依次重啟DB1和DB2上面的MySQL。
3.創建復制用戶并授權
首先在DB1的MySQL庫中創建復制用戶,操作過程如下:
mysql> grant replication slave on *.* to 'repl_user'@'10.0.0.36' identified by 'repl_passwd';
Query OK, 0 rows affected (0.01 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+
| File? ? ? ? ? ? ?| Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |? ? ?1698 |? ? ? ? ? ? ? |? ? ? ? ? ? ? ? ? |
+------------------+----------+--------------+------------------+
然后在DB2的MySQL庫中將DB1設為自己的主服務器,操作如下:
mysql> change master to master_host='10.0.0.35',master_user='repl_user',master_password='repl_passwd',master_log_file='mysql-bin.000001',master_log_pos=1698;
這里需要注意master_log_file和master_log_pos兩個選項,這兩個選項的值剛好是在DB1上通過SQL語句“show master status”查詢到的結果。
接著就可以在DB2上啟動slave服務了,可執行如下SQL命令:
mysql> start slave;
查看DB2上slave的運行狀態:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.35
Master_User: repl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 1698
Relay_Log_File: mysql-relay-bin.000016
Relay_Log_Pos: 411
Relay_Master_Log_File: mysql-bin.000001
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: mysql.%,test.%,information_schema.%
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1698
Relay_Log_Space: 711
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:
1 row in set (0.00 sec)
通過查看slave的運行狀態可以發現,一切運行正常,這里需要重點關注的是Slave_IO_Running和Slave_SQL_Running,這兩個就是在Slave節點上運行的主從復制線程,正常情況下這兩個值都應該為Yes。另外,還需要注意的是Slave_IO_State、Master_Host、Master_Log_File、Read_Master_Log_Pos、Relay_Log_File、Relay_Log_Pos和Relay_Master_Log_File幾個選項,可以查看出MySQL復制的運行原理及執行規律。最后還有一個Replicate_Wild_Ignore_Table選項,這個是之前在my.cnf中添加過的,通過此選項的輸出值可以知道過濾了哪些數據庫。
到這里,從DB1到DB2的MySQL主從復制已經完成。接下來開始配置從DB2到DB1的MySQL主從復制,這個配置過程與上面的過程完全一樣,首先在DB2的MySQL庫中創建復制用戶,操作如下:
mysql>grant replication slave on *.* to 'repl_user'@'10.0.0.35' identified by 'repl_passwd';
mysql>show master status;
然后在DB1的MySQL庫中將DB2設為自己的主服務器,操作如下:
mysql>change master to master_host='10.0.0.36',master_user='repl_user',master_password='repl_passwd',master_log_file='mysql-bin.000001',master_log_pos=266;
最后,就可以在DB1上啟動slave服務了,可以執行如下SQL命令:
mysql>start slave;
查看DB1上slave的運行狀態,Slave_IO_Running和Slave_SQL_Running都是Yes狀態,表明DB1上復制服務運行正常。至此,MySQL雙主模式的主從復制配置完畢。
6.配置Keepakived實現MySQL雙主高可用
在進行高可用配置之前,首先需要在DB1和DB2服務器上安裝Keepalived軟件。我這里是直接yum安裝,關于keepalived的安裝這里不再說明,直接進入Keepalived的配置過程。下面是DB1服務器上/etc/keepalived/keepalived.conf文件的內容。
[root@db1 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script check_mysqld {
script "/etc/keepalived/mysqlcheck/slave.sh"? #檢測MySQL復制狀態的腳本
interval 2
weight 21
}
vrrp_instance HA_1 {
state BACKUP? ? ? ? ? ? #在DB1和DB2上均配置為BACKUP
interface eth0
virtual_router_id 80
priority 100
advert_int 2
nopreempt? ? ? ? ? ? ? #不搶占模式,只在優先級高的機器上設置即可,優先級低的機器可不設置
authentication {
auth_type PASS
auth_pass aaaavvv
}
track_script {
check_mysqld
}
virtual_ipaddress {
10.0.0.40/24 dev eth0? ? #MySQL的對外服務Ip,即VIP
}
}
其中,/etc/keepalived/mysqlcheck/slave.sh文件的內容為:
[root@db1 mysqlcheck]# cat slave.sh
#!/bin/bash
#Date: 2017-07-16
#Mail: 1135757611@qq.com
#Function: 監控mysql主從同步
#
. /etc/init.d/functions
Slave_IO=`/usr/bin/mysql -uroot -e "show slave status\G;" | grep -i " Slave_IO_R"|awk -F ": " '{print $2}'`
Slave_SQL=`/usr/bin/mysql -uroot -e "show slave status\G;" | grep -i "Slave_SQL_R"|awk -F ": " '{print $2}'`
if [[ $Slave_IO = 'Yes' &&? $Slave_SQL = 'Yes' ]]
then
action "Slave is Running" /bin/true
MYSQL_SLAVE_STATUS=0
else
action "Slave is not Running" /bin/false
MYSQL_SLAVE_STATUS=1
fi
exit $MYSQL_SLAVE_STATUS
使用前要保證此腳本有執行權限。
接著將Keepalived.conf文件中priority值修改為90。由于配置的是不搶占模式,因此,還需要去掉nopreempt選項。
在完成所有配置后,分別在DB1和DB2上啟動Keepalived服務,在正常情況下VIP地址應該運行在DB1服務器上。
7.測試MySQL主從同步功能
為了驗證MySQL的復制功能,可以編寫一個簡單的程序進行測試,也可以通過遠程客戶端登錄進行測試。這里通過一個MySQL客戶端,然后利用MySQL的VIP地址登錄,看能否登錄,并在登錄后進行讀、寫操作,看看DB1和DB2之間能否實現數據同步。由于采用遠程登錄測試,因此DB1和DB2兩臺MySQL服務器都要事先做好授權,允許從遠程登錄。
1.在遠程客戶端通過VIP登錄測試
首先通過遠程MySQL客戶端命令行登錄VIP為“10.0.0.40”的數據庫,操作如下:
[root@zabbix ~]# mysql -u test -h 10.0.0.40 -pyan123
Welcome to the MySQL monitor.? Commands end with ; or \g.
Your MySQL connection id is 51298
Server version: 5.1.73-log Source distribution
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show variables like "%hostname%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname? ? ? | db1? ?|
+---------------+-------+
1 row in set (0.00 sec)
mysql> show variables like "%server_id%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id? ? ?| 1? ? ?|
+---------------+-------+
1 row in set (0.01 sec)
從SQL輸出結果看,可以通過VIP登錄,并且登錄了DB1服務器。
2.數據復制功能測試
接著上面的SQL操作過程,通過遠程的MySQL客戶端連接VIP,進行讀、寫操作測試,操作過程如下:
mysql> create database bbs;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database? ? ? ? ? ?|
+--------------------+
| information_schema |
| bbs? ? ? ? ? ? ? ? |
| blog? ? ? ? ? ? ? ?|
| mysql? ? ? ? ? ? ? |
| test? ? ? ? ? ? ? ?|
| wordpress? ? ? ? ? |
+--------------------+
6 rows in set (0.00 sec)
mysql> use bbs;
Database changed
mysql> create table user (id int,email varchar(80),password varchar(40) not null);
Query OK, 0 rows affected (0.20 sec)
mysql> show tables;
+---------------+
| Tables_in_bbs |
+---------------+
| user? ? ? ? ? |
+---------------+
1 row in set (0.01 sec)
mysql> insert into user (id,email,password) values(1,"bbs@163.com","aa1234");
Query OK, 1 row affected (0.00 sec)
這個過程創建了一個數據庫bbs,然后在bbs庫中創建了一張表user。為了驗證數據是否復制到DB2主機上,登錄DB2主機的MySQL命令行,查詢過程如下:
[root@db2 ~]# mysql
mysql> show databases;
+--------------------+
| Database? ? ? ? ? ?|
+--------------------+
| information_schema |
| bbs? ? ? ? ? ? ? ? |
| blog? ? ? ? ? ? ? ?|
| mysql? ? ? ? ? ? ? |
| wordpress? ? ? ? ? |
+--------------------+
5 rows in set (0.00 sec)
mysql> use bbs;
Database changed
mysql> show tables;
+---------------+
| Tables_in_bbs |
+---------------+
| user? ? ? ? ? |
+---------------+
1 row in set (0.00 sec)
mysql> select * from user;
+------+-------------+----------+
| id? ?| email? ? ? ?| password |
+------+-------------+----------+
|? ? 1 | bbs@163.com | aa1234? ?|
+------+-------------+----------+
1 row in set (0.00 sec)
從SQL輸出結果看,剛才創建的庫和表都已經同步到了DB2服務器上。其實也可以直接登錄DB2服務器,然后執行數據庫的讀、寫操作,看數據能否迅速同步到DB1的MySQL數據庫中。
8.測試Keepalived實現MySQL故障轉移
為了測試Keepalived實現的故障轉移功能,需要模擬一些故障,比如,可以通過斷開DB1主機的網絡、關閉DB1主機、關閉DB1上MySQL服務等各種操作實現。這里在DB1服務器上關閉MySQL的日志接收功能,以此來模擬DB1上MySQL的故障。由于在DB1和DB2服務器上都添加了監控MySQL運行狀態的腳本slave.sh,因此當關閉DB1的MySQL日志接收功能后,Keepalived會立刻檢測到,接著執行切換操作。
1.停止DB1服務器的日志接收功能
首先在遠程MySQL客戶端以VIP地址登錄MySQL系統,不用退出這個連接,然后在DB1服務器的MySQL命令行執行如下操作:
[root@db1 ~]# mysql
mysql> stop slave;
2.在遠程客戶端測試
繼續在剛才打開的遠程MySQL連接中執行命令,操作如下:
mysql> select * from user;
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql> select * from user;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:? ? 62855
Current database: bbs
+------+-------------+----------+
| id? ?| email? ? ? ?| password |
+------+-------------+----------+
|? ? 1 | bbs@163.com | aa1234? ?|
+------+-------------+----------+
1 row in set (0.24 sec)
mysql> show variables like "%hostname%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname? ? ? | db2? ?|
+---------------+-------+
1 row in set (0.00 sec)
mysql> show variables like "%server_id%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id? ? ?| 2? ? ?|
+---------------+-------+
1 row in set (0.00 sec)
從這個操作過程可以看出,在Keepalived切換后,之前的session連接失效,所以第一查詢命令失敗。然后重新執行查詢命令,MySQL會執行重新連接,隨后輸出了查詢結果,從后面兩個SQL的查詢結果可知,MySQL服務已經從DB1服務器切換到DB2服務器。Keepalived的切換過程非常迅速,整個過程大概持續1~3s,重新切換到新的服務器后,之前所有的MySQL連接失效,重新連接可以恢復正常。
接著,重新打開DB1上MySQL的日志接收功能,可以發現Keepalived將不再執行切換操作,因為上面將Keepalived配置為不搶占模式,此時,MySQL服務將一直在DB2服務器上運行,直到DB2主機或服務出現故障才再次進行切換操作。這樣做的原因是在數據庫環境下,每次切換的代價很大,因而關閉了Keepalived的主動搶占模式。
總結
以上是生活随笔為你收集整理的mysql 集群操作系统_高性能MySQL集群详解(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: bootstrap 新闻列表_kuapi
 - 下一篇: mysql libs 冲突_mysql-