防偽碼:明日復(fù)明日,明日何其多。
生產(chǎn)環(huán)境中一臺(tái)mysql主機(jī)存在單點(diǎn)故障,所以我們要確保mysql的高可用性,即兩臺(tái)MySQL
服務(wù)器如果其中有一臺(tái) MySQL 服務(wù)器掛掉后,另外一臺(tái)能立馬接替其進(jìn)行工作。
MySQL 的高可用方案一般有如下幾種:
keepalived+雙主,MHA,PXC,MMM,Heartbeat+DRBD 等,比較常用的是 keepalived+雙主,
MHA 和 PXC。
本節(jié)主要介紹了利用 keepalived 實(shí)現(xiàn) MySQL 數(shù)據(jù)庫(kù) 的高可用。
Keepalived+mysql雙主來(lái)實(shí)現(xiàn)MySQL-HA,我們必須保證兩臺(tái)MySQL數(shù)據(jù)庫(kù)的數(shù)據(jù)完全一樣,
基本思路是兩臺(tái) MySQL 互為主從關(guān)系(雙主),通過(guò) Keepalived 配置虛擬 IP,實(shí)現(xiàn)當(dāng)其中的一
臺(tái) MySQL 數(shù)據(jù)庫(kù)宕機(jī)后,應(yīng)用能夠自動(dòng)切換到另外一臺(tái) MySQL數(shù)據(jù)庫(kù),保證系統(tǒng)的高可用。
拓?fù)洵h(huán)境
OS:centos6.5 x86_64
Mysql 版本:mysql 5.5.38
Keepalived: keepalived-1.2.20
Mysql-vip:192.168.12.1
Mysql-master1:192.168.12.128
Mysql-master2:192.168.12.129
一、配置兩臺(tái) mysql 主主同步
該過(guò)程的第一部分就是 master 記錄二進(jìn)制日志。在每個(gè)事務(wù)更新數(shù)據(jù)完成之前,master 在
二日志記錄這些改變。MySQL 將事務(wù)寫(xiě)入二進(jìn)制日志。在事件寫(xiě)入二進(jìn)制日志完成后,master
通知存儲(chǔ)引擎提交事務(wù)。
下一步就是 slave 將 master 的 binary log 拷貝到它自己的中繼日志。首先,slave 開(kāi)始一個(gè)工
作線程——I/O線程。I/O線程在master上打開(kāi)一個(gè)普通的連接,然后開(kāi)始binlog dump process。
Binlog dump process 從 master 的二進(jìn)制日志中讀取事件,如果已經(jīng)同步了 master,它會(huì)睡
眠并等待 master 產(chǎn)生新的事件。I/O 線程將這些事件寫(xiě)入中繼日志。
SQL slave thread(SQL 從線程)處理該過(guò)程的最后一步。SQL 線程從中繼日志讀取事件,并
重放其中的事件而更新 slave 的數(shù)據(jù),使其與 master 中的數(shù)據(jù)一致。只要該線程與 I/O 線程
保持一致,中繼日志通常會(huì)位于 OS 的緩存中,所以中繼日志的開(kāi)銷(xiāo)很小。
主主同步就是兩臺(tái)機(jī)器互為主從的關(guān)系,在任何一臺(tái)機(jī)器上寫(xiě)入都會(huì)同步。
若 mysql 主機(jī)開(kāi)啟了防火墻,需要關(guān)閉防火墻或創(chuàng)建規(guī)則。
1、修改 MySQL 配置文件
兩臺(tái) MySQL 均要開(kāi)啟 binlog 日志功能,開(kāi)啟方法:在 MySQL 配置文件[MySQLd]段中加上
log-bin=MySQL-bin 選項(xiàng),兩臺(tái) MySQL 的 server-ID 不能一樣,默認(rèn)情況下兩臺(tái) MySQL 的
serverID 都是 1,需將其中一臺(tái)修改為 2 即可。
master1 中有關(guān)復(fù)制的配置如下:
log-bin = mysql-bin
binlog_format = mixed
server-id = 1
relay-log = relay-bin
relay-log-index = slave-relay-bin.index
auto-increment-increment = 2
auto-increment-offset = 1
重啟 mysqld 服務(wù)
#service mysqld restart
master2 中有關(guān)復(fù)制的配置如下:
log-bin = mysql-bin
binlog_format = mixed
server-id = 2
relay-log = relay-bin
relay-log-index = slave-relay-bin.index
auto-increment-increment = 2
auto-increment-offset = 2
重啟 mysqld 服務(wù)
#service mysqld restart
注:master1 和 master2 只有 server-id 不同和 auto-increment-offset 不同。
mysql 中有自增長(zhǎng)字段,在做數(shù)據(jù)庫(kù)的主主同步時(shí)需要設(shè)置自增長(zhǎng)的兩個(gè)相關(guān)配置:
auto_increment_offset 和 auto_increment_increment。
auto-increment-increment 表示自增長(zhǎng)字段每次遞增的量,其默認(rèn)值是 1。它的值應(yīng)設(shè)為整個(gè)
結(jié)構(gòu)中服務(wù)器的總數(shù),本案例用到兩臺(tái)服務(wù)器,所以值設(shè)為 2。
auto-increment-offset 是用來(lái)設(shè)定數(shù)據(jù)庫(kù)中自動(dòng)增長(zhǎng)的起點(diǎn)(即初始值),因?yàn)檫@兩能服務(wù)器都
設(shè)定了一次自動(dòng)增長(zhǎng)值 2,所以它們的起點(diǎn)必須得不同,這樣才能避免兩臺(tái)服務(wù)器數(shù)據(jù)同步
時(shí)出現(xiàn)主鍵沖突,
注:可以在 my.cnf 文件中添加“binlog_do_db=數(shù)據(jù)庫(kù)名”配置項(xiàng)(可以添加多個(gè))來(lái)指定
要同步的數(shù)據(jù)庫(kù)
2、將 master1 設(shè)為 master2 的主服務(wù)器
在 master1 主機(jī)上創(chuàng)建授權(quán)賬戶,允許在 master2(192.168.1.102)主機(jī)上連接
查看 master1 的當(dāng)前 binlog 狀態(tài)信息
在 master2 上將 master1 設(shè)為自已的主服務(wù)器并開(kāi)啟 slave 功能。
查看從的狀態(tài),以下兩個(gè)值必須為 yes,代表從服務(wù)器能正常連接主服務(wù)器
Slave_IO_Running:Yes
Slave_SQL_Running:Yes
3、將 master2 設(shè)為 master1 的主服務(wù)器
在 master2 主機(jī)上創(chuàng)建授權(quán)賬戶,允許在 master1(192.168.12.128)主機(jī)上連接
查看 master2 的當(dāng)前 binlog 狀態(tài)信息
在 master1 上將 master2 設(shè)為自已的主服務(wù)器并開(kāi)啟 slave 功能。
查看從的狀態(tài),以下兩個(gè)值必須為 yes,代表從服務(wù)器能正常連接主服務(wù)器
Slave_IO_Running:Yes
Slave_SQL_Running:Yes
4、測(cè)試主主同步
在 master1 上創(chuàng)建要同步的數(shù)據(jù)庫(kù)如 test_db,并在 test_db 中創(chuàng)建一張測(cè)試表如 tab1
查看 master2 主機(jī)是否同步了 master1 上的數(shù)據(jù)變化
從上圖可以看出 master2 同步了 master 的數(shù)據(jù)變化
在 master2 主機(jī)上向 tab1 表中插入數(shù)據(jù)
查看 master1 主機(jī)是否同步了 master2 上的數(shù)據(jù)變化
現(xiàn)在任何一臺(tái) MySQL 上更新數(shù)據(jù)都會(huì)同步到另一臺(tái) MySQL,MySQL 同步完成。
注:若主 MYSQL 服務(wù)器已經(jīng)存在,只是后期才搭建從 MYSQL 服務(wù)器,在置配數(shù)據(jù)同步前應(yīng)
先將主 MYSQL 服務(wù)器的要同步的數(shù)據(jù)庫(kù)拷貝到從 MYSQL 服務(wù)器上(如先在主 MYSQL 上備
份數(shù)據(jù)庫(kù),再用備份在從 MYSQL 服務(wù)器上恢復(fù))
下面我們就完成 keepalived 的高可用性。
keepalived 是集群管理中保證集群高可用的一個(gè)軟件解決方案,其功能類(lèi)似于 heartbeat,用
來(lái)防止單點(diǎn)故障
keepalived 是以 VRRP 協(xié)議為實(shí)現(xiàn)基礎(chǔ)的,VRRP 全稱 Virtual Router Redundancy Protocol,即
虛擬路由冗余協(xié)議 。
虛擬路由冗余協(xié)議,可以認(rèn)為是實(shí)現(xiàn)路由器高可用的協(xié)議,即將 N 臺(tái)提供相同功能的路由
器組成一個(gè)路由器組,這個(gè)組里面有一個(gè) master 和多個(gè) backup,master 上面有一個(gè)對(duì)外提
供服務(wù)的 vip,master 會(huì)發(fā)組播(組播地址為 224.0.0.18),當(dāng) backup 收不到 vrrp 包時(shí)就認(rèn)
為 master 宕掉了,這時(shí)就需要根據(jù) VRRP 的優(yōu)先級(jí) 來(lái) 選舉一個(gè) backup 當(dāng) master。這樣的話
就可以保證路由器的高可用了。
keepalived 主要有三個(gè)模塊,分別是 core、check 和 vrrp。core 模塊為 keepalived 的核心,負(fù)
責(zé)主進(jìn)程的啟動(dòng)、維護(hù)以及全局配置文件的加載和解析。check 負(fù)責(zé)健康檢查,包括常見(jiàn)的
各種檢查方式(方式 1:tcp_check,工作第四層。方式 2:http_get,工作在第五層,向指定的
URL 執(zhí)行 http 請(qǐng)求,將得到的結(jié)果用 md5 加密并與指定的 md5 值比較看是否匹配,不匹配
則從服務(wù)器池中移除。方式 3:ssl_get:與 http_get 相似。方式 4:misc_check:用腳本來(lái)檢測(cè)。
方式 5:smtp_check:用來(lái)檢測(cè)郵件服務(wù)的 smtp)。vrrp 模塊是來(lái)實(shí)現(xiàn) VRRP 協(xié)議的。
二、keepalived 的安裝配置
1、在 master1 和 master2 上安裝軟件包 keepalived
安裝 keepalived 軟件包與服務(wù)控制
在編譯安裝 Keepalived 之前,必須先安裝內(nèi)核開(kāi)發(fā)包 kernel-devel 以及 openssl-devel、
popt-devel 等支持庫(kù)。
若沒(méi)有安裝則通過(guò) rpm 或 yum 工具進(jìn)行安裝
編譯安裝 Keepalived
使用指定的 linux 內(nèi)核位置對(duì) keepalived 進(jìn)行配置,并將安裝路徑指定為根目錄,這樣就無(wú)
需額外創(chuàng)建鏈接文件了,配置完成后,依次執(zhí)行 make、make install 進(jìn)行安裝。
注意:如不知道 keepalived 需要哪些依賴包,可到下載后的源碼解壓目錄下查看 INSTALL 文
件內(nèi)容,安裝需要的依賴包,源碼安裝任何一個(gè)軟件都要養(yǎng)成查看源碼包文檔的習(xí)慣,比如
INSTALL,README,doc 等文檔,可以獲得很多有用的信息
注意:在 centos7.2 上安裝 keepalived 不需要添加--with-kernel-dir
[root@localhost keepalived-1.2.20]# ./configure --prefix=/ && make && make install
使用 keepalived 服務(wù)
執(zhí)行 make install 操作之后,會(huì)自動(dòng)生成/etc/init.d/keepalived 腳本文件,但還需要手動(dòng)添加
為系統(tǒng)服務(wù),這樣就可以使用 service、chkconfig 工具來(lái)對(duì) keepalived 服務(wù)程序進(jìn)行管理了。
Master2 主機(jī)也完成 keepalived 安裝,與 master1 一樣,安裝過(guò)程略
注:若開(kāi)啟了防火墻,需要關(guān)閉防火墻或創(chuàng)建規(guī)則。
注:如果在 centos7.2 上安裝 keepalived 防火墻的規(guī)則配置如下:
[root@localhost ~]# firewall-cmd --permanent --add-rich-rule="rule family=ipv4 destination
address=224.0.0.18 protocol value=ip accept"
success
[root@localhost ~]# firewall-cmd --reload
2、修改 Keepalived 的配置文件
keepalived 只有一個(gè)配置文件 keepalived.conf,里面主要包括以下幾個(gè)配置區(qū)域,分別是
global_defs、vrrp_instance 和 virtual_server。
global_defs:主要是配置故障發(fā)生時(shí)的通知對(duì)象以及機(jī)器標(biāo)識(shí)。
vrrp_instance:用來(lái)定義對(duì)外提供服務(wù)的 VIP 區(qū)域及其相關(guān)屬性。
virtual_server:虛擬服務(wù)器定義
master1 主機(jī)上的 keepalived.conf 文件的修改:
vi /etc/keepalived/keepalived.conf:
! Configuration File for keepalived //!表示注釋
global_defs {
router_id MYSQL-1 //表示運(yùn)行 keepalived 服務(wù)器的一個(gè)標(biāo)識(shí)
}
vrrp_instance VI_1 {
state BACKUP //指定keepalived的角色,兩臺(tái)配置此處均是BACKUP,設(shè)為BACKUP將根據(jù)
優(yōu)先級(jí)決定主或從
interface eth0 //指定 HA 監(jiān)測(cè)網(wǎng)絡(luò)的接口
virtual_router_id 51 //虛擬路由標(biāo)識(shí),這個(gè)標(biāo)識(shí)是一個(gè)數(shù)字(取值在 0-255 之間,用來(lái)區(qū)分多個(gè)
instance 的 VRRP 組播),同一個(gè) vrrp 實(shí)例使用唯一的標(biāo)識(shí),確保和 master2 相同,同網(wǎng)內(nèi)不同集群此項(xiàng)必須不同,否則發(fā)生沖突。
priority 100 //用來(lái)選舉 master 的,要成為 master,該項(xiàng)取值范圍是 1-255(在此范圍
之外會(huì)被識(shí)別成默認(rèn)值 100),此處 master2 上設(shè)置為 50
advert_int 1 //發(fā) VRRP 包的時(shí)間間隔,即多久進(jìn)行一次 master 選舉(可以認(rèn)為是健康查
檢時(shí)間間隔)
nopreempt //不搶占,即允許一個(gè) priority 比較低的節(jié)點(diǎn)作為 master,即使有 priority 更高
的節(jié)點(diǎn)啟動(dòng)
authentication { //認(rèn)證區(qū)域,認(rèn)證類(lèi)型有 PASS 和 HA(IPSEC),推薦使用 PASS(密碼
只識(shí)別前 8 位)
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { //VIP 區(qū)域,指定 vip 地址
192.168.12.1
}
}
virtual_server 192.168.1.100 3306 { //設(shè)置虛擬服務(wù)器,需要指定虛擬 IP 地址和服務(wù)端口,
IP 與端口之間用空格隔開(kāi)
delay_loop 2 //設(shè)置運(yùn)行情況檢查時(shí)間,單位是秒
lb_algo rr //設(shè)置后端調(diào)度算法,這里設(shè)置為 rr,即輪詢算法
lb_kind DR //設(shè)置 LVS 實(shí)現(xiàn)負(fù)載均衡的機(jī)制,有 NAT、TUN、DR 三個(gè)模式可選
persistence_timeout 60 //會(huì)話保持時(shí)間,單位是秒。這個(gè)選項(xiàng)對(duì)動(dòng)態(tài)網(wǎng)頁(yè)是非常有用的,
為集群系統(tǒng)中的 session 共享提供了一個(gè)很好的解決方案。
有了這個(gè)會(huì)話保持功能,用戶的請(qǐng)求會(huì)被一直分發(fā)到某個(gè)服務(wù)節(jié)點(diǎn),
直到超過(guò)這個(gè)會(huì)話的保持時(shí)間。
protocol TCP //指定轉(zhuǎn)發(fā)協(xié)議類(lèi)型,有 TCP 和 UDP 兩種
real_server 192.168.1.101 3306 { //配置服務(wù)節(jié)點(diǎn) 1,需要指定 real server 的真實(shí) IP 地址和
端口,IP 與端口之間用空格隔開(kāi)
注:master2 上此處改為 192.168.12.128(即 master2 本機(jī) ip)
weight 3 //配置服務(wù)節(jié)點(diǎn)的權(quán)值,權(quán)值大小用數(shù)字表示,數(shù)字越大,權(quán)值越高,設(shè)置權(quán)
值大小為了區(qū)分不同性能的服務(wù)器
notify_down /etc/keepalived/bin/mysql.sh //檢測(cè)到 realserver 的 mysql 服務(wù) down 后執(zhí)行的
腳本
TCP_CHECK {
connect_timeout 3 //連接超時(shí)時(shí)間
nb_get_retry 3 //重連次數(shù)
delay_before_retry 3 //重連間隔時(shí)間
connect_port 3306 //健康檢查端口
}
}
}
master1 主機(jī)上有關(guān) keepalived.conf 文件的具體配置如下:
啟動(dòng) keepalived 服務(wù)
#/etc/init.d/keepalived start
Master2 主機(jī)上的 keepalived.conf 文件的修改:
Master2 主機(jī)的 keepalived.conf 文件配置與 master1 基本相同,只是 router_id,priority,
real_server 三處不同,其他配置都相同
可以使用 scp 命令把 server1 主機(jī)上配置好的 keepalived.conf 文件拷貝到 server2 主機(jī),只要。
啟動(dòng) keepalived 服務(wù)
#/etc/init.d/keepalived start
3、master1 和 master2 上都添加此檢測(cè)腳本,作用是當(dāng) mysql 停止工作時(shí)自動(dòng)關(guān)閉本機(jī)的
keepalived,從而實(shí)現(xiàn)將故障機(jī)器踢出(因每臺(tái)機(jī)器上 keepalived 只添加了本機(jī)為 realserver).
當(dāng) mysqld 正常啟動(dòng)起來(lái)后,要手動(dòng)啟動(dòng) keepalived 服務(wù)。
#mkdir /etc/keepalived/bin
vi /etc/keepalived/bin/mysql.sh,內(nèi)容如下:
Master2 主機(jī)完成相同的操作
4、測(cè)試
在 master1 和 master2 分別執(zhí)行 ipaddr show dev eth0 命令查看 master1 和 master2 對(duì) VIP
(群集虛擬 IP)的控制權(quán)。
Master1 主的查看結(jié)果:
Master2 主的查看結(jié)果:
從上圖可以看出 master1 是主服務(wù)器,master2 為備用服務(wù)器。
停止 MySQL 服務(wù),看 keepalived 健康檢查程序是否會(huì)觸發(fā)我們編寫(xiě)的腳本
停止 master1 主機(jī)的 mysql 服務(wù)
Master2 主的查看結(jié)果:
這說(shuō)明在主服務(wù)上停止 MySQL 服務(wù),觸發(fā)了我們編寫(xiě)的腳本,進(jìn)行自動(dòng)故障切換。
MySQL 遠(yuǎn)程登錄測(cè)試
我們找一臺(tái)安裝有 MySQL 客戶端,然后登錄 VIP,看是否能登錄,在登錄之兩臺(tái) MySQL 服
務(wù)器都要授權(quán)允許從遠(yuǎn)程登錄。例如:
在客戶端上測(cè)試登錄
上圖顯示說(shuō)明在客戶端訪問(wèn) VIP 地址,由 master1 主機(jī)提供響應(yīng)的,因?yàn)?master1 當(dāng)前是主
服務(wù)器,將 master1 的 mysql 服務(wù)停止,在客戶端執(zhí)行 show variables like‘server_id’;
上圖顯示說(shuō)明在客戶端的查詢請(qǐng)求是由 master2 主機(jī)響應(yīng)的。故障切換成功。
總結(jié):
Keepalived+mysql 雙主一般來(lái)說(shuō),中小型規(guī)模的時(shí)候,采用這種架構(gòu)是最省事的。
在 master 節(jié)點(diǎn)發(fā)生故障后,利用 keepalived 的高可用機(jī)制實(shí)現(xiàn)快速切換到備用節(jié)點(diǎn)。
在這個(gè)方案里,有幾個(gè)需要注意的地方:
1.采用 keepalived 作為高可用方案時(shí),兩個(gè)節(jié)點(diǎn)最好都設(shè)置成 BACKUP模式,避免因?yàn)橐馔?/span>
情況下(比如 腦裂)相互搶占導(dǎo)致往兩個(gè)節(jié)點(diǎn)寫(xiě)入相同數(shù)據(jù)而引發(fā)沖突;
2.把兩個(gè)節(jié)點(diǎn)的 auto_increment_increment(自增步長(zhǎng))和 auto_increment_offset(自增起
始值)設(shè)成不同值。其目的是為了避免 master 節(jié)點(diǎn)意外宕機(jī)時(shí),可能會(huì)有部分 binlog 未能
及時(shí)復(fù)制到slave上被應(yīng)用,從而會(huì)導(dǎo)致slave新寫(xiě)入數(shù)據(jù)的自增值和原先master上沖突了,
因此一開(kāi)始就使其錯(cuò)開(kāi);當(dāng)然了,如果有合適的容錯(cuò)機(jī)制能解決主從自增 ID 沖突的話,也
可以不這么做;
3.slave 節(jié)點(diǎn)服務(wù)器配置不要太差,否則更容易導(dǎo)致復(fù)制延遲。作為熱備節(jié)點(diǎn)的 slave 服務(wù)器,
硬件配置不能低于 master 節(jié)點(diǎn);
4.如果對(duì)延遲問(wèn)題很敏感的話,可考慮使用 MariaDB 分支版本,或者直接上線 MySQL 5.7 最
新版本,利用多線程復(fù)制的方式可以很大程度降低復(fù)制延遲;
謝謝觀看,真心的希望能幫到您!
本文出自 “一盞燭光” 博客,謝絕轉(zhuǎn)載!
更多建議: