http://blog.sina.com.cn/s/blog_166c0ec620102wz03.html
一凰浮、MHA及相關軟件簡介
MHA是一款MySQL高可用開源軟件我抠,實現(xiàn)MySQL一主多從架構下,主備的failover自動切換、手動切換、狀態(tài)監(jiān)控等功能梯捕,是比較常用的高可用解決方案之一。
LVS是linux下的一款虛擬服務器軟件纳鼎,內部實現(xiàn)了虛擬路由協(xié)議,實現(xiàn)多節(jié)點服務器之間負載均衡裳凸。
Keepalived高可用軟件贱鄙,支持LVS算法,從而結合LVS實現(xiàn)負載均衡服務器的高可用姨谷。
二逗宁、服務器及軟件版本
操作系統(tǒng):CentOS6.5 64
MySQL:5.7
IP地址主機名稱MySQL軟件LVSKeepalived
10.211.55.41centos6mha01mysql clientlvs主節(jié)點keep主節(jié)點
10.211.55.42centos6mha02mysql master
10.211.55.43centos6mha03mysql slave1 (備用master)lvs realserver
10.211.55.44centos6mha04mysql slave2lvs realserver
10.211.55.45centos6mha05mysql clientlvs備節(jié)點keep備節(jié)點
vip:10.211.55.100 master寫入
10.211.55.200 slave讀取
讀寫分離策略,通過mha的failover檢查腳本梦湘,實現(xiàn)寫入vip的綁定切換瞎颗,即綁定master為寫入服務器
通過keepalived配置vip實現(xiàn)slave節(jié)點讀取請求的統(tǒng)一接入
三、MySQL主從部署
mysql軟件的安裝過程略過捌议,本次采用通用二進制安裝包哼拔,解壓安裝,主要針對主從架構的三臺服務器
10.211.55.42瓣颅、10.211.55.43倦逐、10.211.55.44,另外兩臺只作為mysql的客戶端宫补,因為涉及一些mysql相關腳本的調用檬姥,所以yum安裝mysql相關庫即可,當然用二進制安裝包安裝更好粉怕,下面主要是主從相關配置項健民,mysql通用配置項省略。
10.211.55.42:
vim /etc/my.cnf
server_id=42 #以主機IP的末位作為標識斋荞,區(qū)分不同mysql節(jié)點
log_bin=mysql-bin
binlog_format=mixed
#for replication
binlog_cache_size=1M
expire_logs_days=14 #日志過期時間
relay_log=mysql-relay-bin
skip-slave-start #關閉slave復制進程隨數(shù)據(jù)庫啟動而啟動荞雏,方便維護
relay_log_purge=0?#為了保證主從環(huán)境順利的failover切換虐秦,禁用自動清除平酿,采用腳本定期清除
relay_log_index=mysql-relay-bin.index
從庫10.211.55.43、10.211.55.44的配置除了server_id不同悦陋,其余配置與10.211.55.42相同
四蜈彼、MHA軟件安裝
1、安裝yum源
為了方便后續(xù)軟件的安裝俺驶,每臺機器安裝幸逆,最好將此源rpm下載到本地備用棍辕,wget以下地址即可
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
yum clean all
2、創(chuàng)建MHA用戶(在主從環(huán)境的主上執(zhí)行)
mysql> grantall privileges on *.* to 'mha'@'10.211.55.%' identified by 'oracle';
mysql> flush privileges;
3还绘、創(chuàng)建軟連接(在所有mysql上都執(zhí)行)
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql
4楚昭、配置SSH無密碼登錄認證
各節(jié)點生成秘鑰,并將公鑰傳送到其他服務器拍顷,包括自身抚太,如
創(chuàng)建秘鑰
ssh-keygen -t rsa
傳送到其他機器生成認證文件
ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.211.55.41
ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.211.55.42
ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.211.55.43
ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.211.55.44
ssh-copy-id -i /root/.ssh/id_rsa.pub root@10.211.55.45
5、配置hosts
[root@panda ~]# vim /etc/hosts
10.211.55.41 centos6mha01
10.211.55.42 centos6mha02
10.211.55.43 centos6mha03
10.211.55.44 centos6mha04
10.211.55.45 centos6mha05
說明:在所有機器上的 /etc/hosts中添加上面配置.
5昔案、部署MHA Node
在所有運行MySQL服務的服務器上安裝運行MHA Node尿贫,無論是master還是slave。由于MHA Manager需要MHA Node踏揣,因此在運行MHA Manager的服務器上也需要安裝MHA Node庆亡。當然也可以在任意一個slave上運行MHA Manager。因為部署步驟相同捞稿,所以就列出一個安裝步驟又谋。
10.211.55.41 10.211.55.42 10.211.55.43 10.211.55.44
為了perl-DBD-MySQL安裝合適的相關依賴,建議刪除操作系統(tǒng)自帶的mysql組件
查找相關mysql-lib包括享,并刪除之
rpm -qa|grep mysql
rpm -e --nodeps mysql-libXXXX.rpm
yum install -y perl-DBD-MySQL perl-DBI cpan git
tar -xf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install
6搂根、部署MHA Manager
MHA Manager僅運行在作為manager的服務器上。當然也可以部署在其中任意一臺slave上铃辖。
這個示例里是部署在10.211.55.41
(1)安裝MHA Manager
yum install -y perl perl-Config-Tiny perl-Email-Date-Format perl-Log-Dispatch perl-MIME-Lite perl-MIME-Types perl-Mail-Sender perl-Mail-Sendmail perl-MailTools perl-Parallel-ForkManager perl-Params-Validate perl-Time-HiRes perl-TimeDate
tar mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install
(2)規(guī)范mha目錄
mkdir -p /usr/local/mha/conf
mkdir -p /usr/local/mha/logs
mkdir -p /usr/local/mha/workstatus/app1
cp mha4mysql-manager-0.57/samples/conf/* /usr/local/mha/conf
(3)配置app1.cnf
cd /usr/local/mha/conf
cp app1.cnf app1.cnf.old
vim app1.cnf
[server default]
manager_log=/usr/local/mha/logs/app1.log
manager_workdir=/usr/local/mha/workstatus/app1
master_binlog_dir=/mydata/data
remote_workdir=/var/log/mha/app1
user=mha
password=oracle
port=3306
repl_password=oracle
repl_user=repl
secondary_check_script= /usr/local/bin/masterha_secondary_check -s centos6mha02 -s centos6mha03 -s centos6mha04
master_ip_failover_script= /usr/local/bin/master_ip_failover
#master_ip_online_change_script= /usr/local/bin/master_ip_online_change
[server1]
candidate_master=1
hostname=centos6mha02
[server2]
candidate_master=1
hostname=centos6mha03
[server3]
hostname=centos6mha04
(4)剩愧、配置全局配置文件
cp masterha_default.cnf masterha_default.cnf.old
vim masterha_default.cnf
[server default]
log-level=debug
check_repl_delay=1
check_repl_filter=1
ping_interval=5
ping_type=CONNECT
(5)設置定時清理relay腳本
使用如下定時任務設置crontab來定期清理relay log
10.211.55.42 - 44
vim /etc/cron.d/purge_relay_logs
0 4 * * * /usr/local/bin/purge_relay_logs --user=root --password=oracle --disable_relay_log_purge --port=3306 --workdir=/mydata/data >>/usr/local/mha/logs/purge_relay_logs.log 2>&1
(6)failover切換腳本
伴隨mha啟動和failover切換調用的檢查腳本,實現(xiàn)mysql master切換時的vip綁定
10.211.55.41
vim /usr/local/bin/master_fail_over
#!/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.211.55.100/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip up";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
$ssh_user = "root";
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";
????`ssh $ssh_user\@$orig_master_ip \" $ssh_start_vip \"`;
????exit 0;
??}
??else {
????&usage();
????exit 1;
??}
}
sub start_vip() {
??`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
??return 0unless($ssh_user);
??`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
??"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 --n
ew_master_ip=ip --new_master_port=port\n";
}
(7)mha ssh連通性及m/s復制狀態(tài)檢查
10.211.55.41
cd /usr/local/bin
masterha_check_ssh --conf=/usr/local/mha/con/app1.cnf
masterha_check_repl --conf=/usr/local/mha/con/app1.cnf
如發(fā)現(xiàn)異常和錯誤娇斩,需要檢查做過的相關步驟仁卷,比如ssh無密碼登錄是否通過,mysql master slave服務是否開啟犬第,相關的rpm包是否安裝完全等
(8)啟動mha管理進程
nohup masterha_manager --conf=/usr/local/mha/conf/app1.cnf --ignore_last_failover /usr/local/mha/logs/manager.log 2>&1 &
觀察寫入vip的綁定情況
在當前mysql master服務器上锦积,也就是10.211.55.42上執(zhí)行以下命令可以發(fā)現(xiàn)10.211.55.100被綁定在eth0上
ip a或者ifconfig
通過客戶端對vip發(fā)起mysql連接請求,成功登入歉嗓。
此時mha的高可用架構就完成了丰介。
五、LVS安裝與配置
lvs主備節(jié)點均瑤安裝 10.211.55.41 鉴分、10.211.55.45
yum install libnl* popt* -y
以下步驟根據(jù)實際服務器的內核版本目錄修改2.6.32-358.el6.x86_64哮幢,安裝lvs必要步驟,否則編譯失敗
ln -s /usr/src/kernels/2.6.32-358.el6.x86_64/ /usr/src/linux
wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz
tar zxf ipvsadm-1.26.tar.gz
cd ipvsadm-1.26
make
make install
將lvs載入內核
ipvsadm
查看lvs虛擬路由列表
lsmod |grep ip_vs
realserver腳本
10.211.55.43 10.211.55.44分別執(zhí)行
綁定讀vip到mysql slave節(jié)點及設置arp抑制
vim arp_vip.sh
#!/bin/bash
vip=10.211.55.200
open() {
ifconfig lo:Rvip ${vip}/32 up
sysctl -w net.ipv4.conf.lo.arp_announce=2
sysctl -w net.ipv4.conf.lo.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
sysctl -w net.ipv4.conf.all.arp_ignore=1
}
close(){
ifconfig lo:Rvip down
sysctl -w net.ipv4.conf.lo.arp_announce=0
sysctl -w net.ipv4.conf.lo.arp_ignore=0
sysctl -w net.ipv4.conf.all.arp_announce=0
sysctl -w net.ipv4.conf.all.arp_ignore=0
}
case $1 in
start)
????open ;;
stop)
????close;;
*)
????echo "Usage: $0 need argument [start|stop]"
;;
esac
執(zhí)行后觀察,vip已綁定在lo上
ifconfig
六志珍、Keepalived安裝與配置
lvs主備節(jié)點安裝10.211.55.41 10.211.55.45
yum install openssl* popt* -y
tar zxf keepalived-1.3.5.tar.gz
cd keepalived-1.3.5
./configure --prefix=/usr/localkeepalived
make
檢查編譯狀態(tài)橙垢,0為成功,否則返回檢查
echo $?
make install
拷貝相關命令及配置
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
拷貝服務命令到系統(tǒng)目錄伦糯,如遇安裝目錄下沒有柜某,
可以拷貝安裝文件目錄下的keepalived-1.3.5/keepalived/etc/init.d/keepalived
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
添加keepalived配置文件嗽元,主備的差別已注明
mkdir -p /etc/keepalived
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
????hahaha@sina.com
}
????notification_email_from alert-noreply@test.com.cn
????smtp_server 127.0.0.1
????smtp_connect_timeout 30
????router_id MHA_LVS_HA
}
# db master server.
vrrp_instance VI_1 {
????state MASTER
????interface eth0
????virtual_router_id 52
????priority 200 #節(jié)點優(yōu)先級,主節(jié)點要高于從節(jié)點喂击,主節(jié)點200從節(jié)點150
????advert_int 5
????authentication {
????auth_type PASS
????auth_pass cuixd
}
????virtual_ipaddress {
????????10.211.55.200/24
????}
}
# VIP 10.211.55.200
virtual_server 10.211.55.200 3306 {
????delay_loop 10
????lb_algo rr
????lb_kind DR
????protocol TCP
????real_server 10.211.55.43 3306 {
????????weight 1
????????TCP_CHECK {
????????????connect_port 3306
????????????connect_timeout 10
????????????delay_before_retry 5
????????}
????????MISC_CHECK {
????????????misc_path "/etc/keepalived/check_slave.py 10.211.55.43 3306"
????????????#misc_path "/etc/keepalived/monitor_mysql.sh 10.211.55.43"
????????????misc_dynamic
????????}
????}
????real_server 10.211.55.44 3306 {
????????weight 1
????????TCP_CHECK {
????????????connect_port 3306
????????????connect_timeout 10
????????????delay_before_retry 5
????????}
????????MISC_CHECK {
????????????misc_path "/etc/keepalived/check_slave.py 10.211.55.44 3306"
????????????#misc_path "/etc/keepalived/monitor_mysql.sh 10.211.55.44"
????????????misc_dynamic
????????}
????}
}
keepalived mysql狀態(tài)檢查腳本check_slave.py剂癌,如遇狀態(tài)檢查失敗,將失敗節(jié)點從lvs讀負載均衡列表中剔除
vim /etc/keepalived/check_slave.py
#!/usr/bin/env python
#encoding:utf-8
import MySQLdb
import sys
ip=sys.argv[1]
user='repl'
pwd='oracle'
port=int(sys.argv[2])
sbm=200
Slave_IO_Running = ''
Slave_SQL_Running = ''
Seconds_Behind_Master = ''
e=''
try:
????conn = MySQLdb.connect(host=ip,user=user,passwd=pwd,port=port,charset='utf8')
????cur = conn.cursor()
????cur.execute('show slave status')
????db_info = cur.fetchall()
????for n in db_info:
????????Slave_IO_Running = n[10]
????????Slave_SQL_Running = n[11]
????????Seconds_Behind_Master = n[32]
????cur.close()
????conn.close()
except MySQLdb.Error,e:
????print "MySQLdb Error",e
if e == "":
????if db_info != ():
????????if Slave_IO_Running == "No" or Slave_SQL_Running == "No":
????????????#print 'thread err'
????????????exit(1)
????????else:
????????????if Seconds_Behind_Master > sbm:
????????????????#print 'timeout err'
????????????????exit(1)
????????????else:
????????????????#print 'OK'
????????????????exit(0)
????else:
????????#print 'slave err'
????????exit(1)
else:
????#print 'db err'
????exit(1)
啟動keepalived
service keepalived start
觀察日志及讀VIP綁定情況
taif /var/log/message
當前l(fā)vs主節(jié)點即10.211.55.41上
ip a
看到10.211.55.200綁定在eth0上翰绊,表示成功
通過客戶端對10.211.55.200發(fā)起mysql連接珍手,成功登入。
七辞做、測試與驗證
1琳要、驗證讀vip的高可用及負載均衡
客戶端發(fā)起多次如下連接,檢查server_id在兩臺slave切換表示負載均衡功能正常
mysql -urepl -h10.211.55.200 -poracle -e "show variables like 'server_id'"
保持多個客戶端連接在lvs主機上查看連接
ipvsadm -Ln
關閉10.211.55.44 mysql服務后秤茅,重復上述檢查稚补,應能成功登入,server_id只有43
2框喳、恢復初始狀態(tài)课幕,將10.211.55.44 mysql服務啟動,設置半同步五垮,開啟salve復制乍惊,設置只讀
service mysqld start
mysql>set global rpl_semi_sync_slave_enabled=on ;
mysql>start slave;
mysql>set global read_only=1;
3、驗證mha failover切換及寫vip綁定放仗,讀vip從新mysql master上剔除
關閉10.211.55.42 mysql服務
檢查mha切換日志润绎,應能成功切換,master切換至10.211.55.43
tailf /usr/local/mha/logs/app1.log
觀察寫vip的綁定切換到了10.211.55.43
ip a
發(fā)起對寫vip的mysql連接诞挨,依然能成功登入表示正常
mysql -urepl -h10.211.55.100 -poracle
發(fā)起對讀vip的mysql連接莉撇,能夠成功登入,且只有10.211.55.44
mysql -urepl -h10.211.55.200 -poracle -e "show variables like 'server_id'"
lvs主節(jié)點10.211.55.41上
ipvsadm -Ln
4惶傻、驗證lvs的高可用
關閉lvs主節(jié)點的keepalived
service keepalived stop
觀察從節(jié)點10.211.55.45日志變化棍郎,此時切換為master主節(jié)點
tailf /var/log/message
查看讀vip綁定已切換到10.211.55.45
ip a
此時發(fā)起對兩個vip的mysql連接,依然能夠正常登入银室,表示LVS主備高可用正常涂佃。
八、問題備注
1蜈敢、安裝過程多為聯(lián)網(wǎng)狀態(tài)安裝辜荠,必要時應先準備好安裝包,在非聯(lián)網(wǎng)狀態(tài)下使用扶认,如mysql 侨拦、mha殊橙、lvs辐宾、keepalived狱从,相關依賴的rpm建議在部署前聯(lián)網(wǎng)狀態(tài)下安裝完畢
2、perl-MySQL-DBD在操作系統(tǒng)存在自帶mysql-lib相關rpm的情況下叠纹,進行yum install perl-MySQL-DBD很有可能無法正常安裝季研,建議先刪除自帶包
3、check_slave.py是keepalived配置中的mysql檢查腳本誉察,涉及mysql遠程登錄与涡,所以在本地應包含mysql客戶端,即10.211.55.41持偏、10.211.55.45要有mysql客戶端
4驼卖、check_salve.py是python腳本,對格式對齊要求非常嚴格鸿秆,編輯時需仔細酌畜,且需要安裝python連接mysql的module和mysql libs,yum install MySQL-python mysql-lib*
mysql主從復制與lvs+keepalived實現(xiàn)負載高可用
目錄
1卿叽、前言?? ?4
2桥胞、原理?? ?4
2.1、概要介紹?? ?4
2.2考婴、工作原理?? ?4
2.3贩虾、實際作用?? ?4
3方案?? ?4
3.1、環(huán)境?? ?4
3.2沥阱、架構圖?? ?5
3.3缎罢、設計原理?? ?6
4、相關軟件安裝?? ?6
4考杉、配置mysql的主從?? ?7
5屁使、通過lvs+keepalived實現(xiàn)負載與熱備,并實現(xiàn)讀寫分離?? ?8
1奔则、前言
最近研究了下高可用的東西蛮寂,這里總結一下mysql主從復制讀寫分離度的高可用方案,可以提高服務器的使用效率易茬,也可以提高提高維護效率酬蹋。同時應用的效率也會有一定的提升,如果改造需要應用修改讀取的ip地址與寫入的ip地址抽莱,改造起來還算容易范抓。
2、原理???? ?
2.1食铐、概要介紹
如果將TCP/IP劃分為5層匕垫,則Keepalived就是一個類似于3~5層交換機制的軟件,具有3~5層交換功能虐呻,其主要作用是檢測web服務器的狀 態(tài)象泵,如果某臺web服務器故障寞秃,Keepalived將檢測到并將其從系統(tǒng)中剔除,當該web服務器工作正常后Keepalived自動將其加入到服務器 群中偶惠,這些工作全部自動完成春寿,而不需要人工干預,只需要人工修復故障的web服務器即可忽孽。
2.2绑改、工作原理
Keepalived基于VRRP協(xié)議來實現(xiàn)高可用解決方案,利用其避免單點故障兄一,通常這個解決方案中厘线,至少有2臺服務器運行Keepalived,即一 臺為MASTER出革,另一臺為BACKUP皆的,但對外表現(xiàn)為一個虛擬IP,MASTER會發(fā)送特定消息給BACKUP蹋盆,當BACKUP收不到該消息時费薄,則認為 MASTER故障了,BACKUP會接管虛擬IP栖雾,繼續(xù)提供服務楞抡,從而保證了高可用性,3層機理是發(fā)送ICMP數(shù)據(jù)包即PING給某臺服務器析藕,如果不痛召廷,則認為其故障,并從服務器群中剔除账胧。4層機理是檢測TCP端口號狀態(tài)來判斷某臺服務器是否故障竞慢,如果故障,則從服務器群中剔除治泥。5層機理是根據(jù)用戶的設定檢查某個服務器應用程序是否正常運行筹煮,如果不正常,則從服務器群中剔除居夹。3败潦、
2.3、實際作用?
Keepalived+lvs主要用作RealServer的健康檢查准脂,以及負載均衡設備MASTER和BACKUP之間failover的實現(xiàn)劫扒。
3方案
本案例先使用兩臺linux做雙機MASTER-SLAVE高可用,實現(xiàn)都寫分離,用于提高查詢性能),采用MYSQL5.6.x的半同步實現(xiàn)數(shù)據(jù)復制和同步狸膏,使用keepalived來監(jiān)控MYSQL和提供讀寫VIP浮動沟饥。Keepalived在這里主要用作RealServer的健康狀態(tài)檢查以及LoadBalance主機和BackUP主機之間failover的實現(xiàn)
任何一臺主機宕機都不會影響對外提供服務(讀寫vip可以浮動),保持服務的高可用。
3.1贤旷、環(huán)境
主機A:192.168.150.171
主機B:192.168.150.172
W-VIP:192.168.150.173? (負責寫入)
R-VIP:192.168.150.174?? (負責讀裙懔稀)
Client:任意,只要能訪問以上三個IP即可
3.2遮晚、架構圖
具體架構圖如下:
3.3、設計原理(異常情況)
1拦止、?? ?服務器A和B县遣,通過mysql的slave進程是用binlog同步數(shù)據(jù)。
2汹族、?? ?通過keepalived啟用兩個虛IP:W-VIP/R-VIP萧求,一個負責寫入,一個負責讀取顶瞒,實現(xiàn)讀寫分離夸政。
3、?? ?A和B都存在時榴徐,W-VIP下將請求轉發(fā)至主機A守问,R-VIP將請求轉發(fā)給A和B,實現(xiàn)負載均衡坑资。
4耗帕、?? ?當主機A異常時,B接管服務袱贮,W-VIP/R-VIP此時漂到了主機B上仿便,此時這兩個虛IP下都是主機B,實現(xiàn)高可用
5攒巍、?? ?當主機B異常時嗽仪,R-VIP會將B踢出,其他不變
具體實現(xiàn)后的效果
正常狀態(tài)
Prot LocalAddress:Port Scheduler Flags
? -> RemoteAddress:Port?????????? Forward Weight ActiveConn InActConn
TCP? 192.168.150.173:3306 wrr persistent 60
? -> 192.168.150.171:3306?????????? Local?? 3????? 0????????? 0??????? ?
TCP? 192.168.150.174:3306 wrr persistent 60
? -> 192.168.150.172:3306?????????? Route?? 3????? 0????????? 0??????? ?
? -> 192.168.150.171:3306?????????? Local?? 1????? 0????????? 0??????? ?
A故障后柒莉,B的狀態(tài)
Prot LocalAddress:Port Scheduler Flags
? -> RemoteAddress:Port?????????? Forward Weight ActiveConn InActConn
TCP? 192.168.150.173:3306 wrr persistent 60
? -> 192.168.150.172:3306?????????? Local?? 3????? 0????????? 0??????? ?
TCP? 192.168.150.174:3306 wrr persistent 60
? -> 192.168.150.172:3306?????????? Local?? 3????? 0????????? 0 ?
架構圖
4闻坚、相關軟件安裝
1、?? ?mysql? 可以根據(jù)需要進行安裝兢孝,此處省略
2鲤氢、?? ?lvs+keepalived的安裝
關聯(lián)lvs與keepalived的ipvs所需的內核信息
ln -s /usr/src/kernels/2.6.18-194.el5-x86_64/ /usr/src/linux
安裝lvs
下載:wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.24.tar.gz
tar -zxvf ipvsadm-1.24.tar.gz
cd tar -zxvf ipvsadm-1.24
make
make install
yum install ipv* 安裝?
驗證
ipvsadm –v
ipvsadm v1.24 2003/06/07 (compiled with getopt_long and IPVS v1.2.0)說明安裝成功
安裝keepalived
tar –zxvf keepalived-1.2.12.tar.gz
cd keepalived-1.2.12
./configure --prefix=/usr/local/keepalived/
make
make install
ln -s /usr/local/keepalived/etc/keepalived /etc/
ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
ln -s /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
ln -s /usr/local/keepalived/bin/genhash /bin/
ln -s /usr/local/keepalived/sbin/keepalived /sbin/
configure時注意Use IPVS Framework、IPVS sync daemon support 西潘、Use VRRP Framework要返回yes卷玉,否則無法關聯(lián)ipvs功能
4、配置mysql的主從
Master(210.171)的配置
vi /etc/my.cnf
添加如下內容:
server-id = 1??? ##master ID
binlog-do-db = ppl? ##允許同步的庫
binlog-ignore-db = mysql? ##忽略同步的庫喷市,也就是不能同步的庫
##配置文件中還需開啟log-bin相种,例如log-bin = mysql-bin
mysql –uroot –p
以下內容在mysql中執(zhí)行
mysql> grant replication slave on *.* to ‘repdb01’@’%’ identified by '123456';
mysql>create database db01;
mysql>flush logs;
mysql>show master status;
mysql>use db01
mysql> create table test(name char);
返回一表格如下,記住File的內容,等下slave的配置中要用到
Slave的配置
vi /etc/my.cnf
添加如下內容:
server-id = 2? ##slave ID
master-host = 192.168.150.171? ##指定master的地址
master-user = repdb01??? ##同步所用的賬號
master-password = 123456?? ##同步所用的密碼
master-port = 3306???? ##master上mysql的端口
replicate-do-db = db01?? ##要同步的庫名
replicate-ignore-db = mysql? ##忽略的庫名
slave-skip-errors = 1062?? ##當同步異常時寝并,那些錯誤跳過箫措,本例為1062錯誤
#log-slave-updates? ##同步的同時,也記錄自己的binlog日志衬潦,如果還有臺slave是通過這臺機器進行同步斤蔓,那需要增加此項,
#skip-slave-start? ##啟動時不自動開啟slave進程
#read-only? ##將庫設為只讀模式镀岛,只能從master同步弦牡,不能直接寫入(避免自增鍵值沖突)
mysql –uroot –p
以下內容在mysql中執(zhí)行
mysql>create database db01;
mysql>change master to master_log_file=’mysql-bin.000007’,master_log=106;
mysql>slave start;
mysql>show slave status \G
在返回值中查看,如果slave_IO_Runing與slave_SQL_Runing的值都為Yes說明同步成功
5漂羊、通過lvs+keepalived實現(xiàn)負載與熱備驾锰,并實現(xiàn)讀寫分離
Master上的配置
vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
?? router_id MySQL-HA
}
vrrp_instance VI_1 {
??? state BACKUP
??? interface eth0
??? virtual_router_id 90
??? priority 100
??? advert_int 1
??? notify_master "/usr/local/mysql/bin/remove_slave.sh"
??? nopreempt
??? authentication {
??????? auth_type PASS
??????? auth_pass abcd1234
??? }
??? virtual_ipaddress {
??????? 192.168.150.173 label eth0:1
?? ???? 192.168.150.174 label eth0:2
??? }
}
virtual_server 192.168.150.173 3306 {
??? delay_loop 2
lb_algo wrr
lb_kind DR
??? persistence_timeout 60
??? protocol TCP
??? real_server 192.168.150.171 3306 {
??? weight 3
?? ?notify_down /usr/local/mysql/bin/mysql.sh
?? ?TCP_CHECK {
??????????? connect_timeout 10
??????????? nb_get_retry 3
??????????? delay_before_retry 3
?? ???? connect_port 3306
??????? }
??? }
}
virtual_server 192.168.150.174 3306 {
??? delay_loop 2
??? lb_algo wrr
??? lb_kind DR
??? persistence_timeout 60
??? protocol TCP
??? real_server 192.168.150.171 3306 {
??? weight 1
?? ?notify_down /usr/local/mysql/bin/mysql.sh
?? ?TCP_CHECK {
??????????? connect_timeout 10
??????????? nb_get_retry 3
??????????? delay_before_retry 3
?? ???? connect_port 3306
??????? }
??? }
??? real_server 192.168.150.172 3306 {
??? weight 3
?? ?TCP_CHECK {
??????????? connect_timeout 10
??????????? nb_get_retry 3
??????????? delay_before_retry 3
?? ???? connect_port 3306
??????? }
??? }
}
vi /usr/local/mysql/bin/remove_slave.sh
#!/bin/bash
user=root
password=123456
log=/root/mysqllog/remove_slave.log
#--------------------------------------------------------------------------------------
echo "`date`" >> $log
/usr/bin/mysql -u$user -p$password -e "set global read_only=OFF;reset master;stop slave;change master to master_host='localhost';" >> $log
/bin/sed -i 's#read-only#\#read-only#' /etc/my.cnf
chomd 755 /usr/local/mysql/bin/remove_slave.sh
vi /usr/local/mysql/bin/mysql.sh
#!/bin/bash
/etc/init.d/keepalived stop
Slave上的配置
vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
?? router_id MySQL-HA
}
vrrp_instance VI_1 {
??? state BACKUP
??? interface eth0
??? virtual_router_id 90
??? priority 99
??? advert_int 1
??? notify_master "/usr/local/mysql/bin/remove_slave.sh"
??? authentication {
??????? auth_type PASS
??????? auth_pass ppl.com
??? }
??? virtual_ipaddress {
??????? 192.168.150.173 label eth0:1
?? ???? 192.168.150.174 label eth0:2
??? }
}
virtual_server 192.168.150.173 3306 {
??? delay_loop 2
??? lb_algo wrr
??? lb_kind DR
??? persistence_timeout 60
??? protocol TCP
??? real_server 192.168.150.172 3306 {
??????? weight 3
?? ?notify_down /usr/local/mysql/bin/mysql.sh
?? ?TCP_CHECK {
??????????? connect_timeout 10
??????????? nb_get_retry 3
??????????? delay_before_retry 3
?? ???? connect_port 3306
??????? }
??? }
}
virtual_server 192.168.150.174 3306 {
??? delay_loop 2
??? lb_algo wrr
??? lb_kind DR
??? persistence_timeout 60
??? protocol TCP
??? real_server 192.168.150.172 3306 {
??????? weight 3
?? ?notify_down /usr/local/mysql/bin/mysql.sh
?? ?TCP_CHECK {
??????????? connect_timeout 10
??????????? nb_get_retry 3
??????????? delay_before_retry 3
?? ???? connect_port 3306
??????? }
??? }
#??? real_server 192.168.150.172 3306 {
#??????? weight 3
#??????? TCP_CHECK {
#??????????? connect_timeout 10
#??????????? nb_get_retry 3
#??????????? delay_before_retry 3
#??????????? connect_port 3306
#??????? }
#??? }
}
vi /usr/local/mysql/bin/remove_slave.sh
#!/bin/bash
user=root
password=123456
log=/root/mysqllog/remove_slave.log
#--------------------------------------------------------------------------------------
echo "`date`" >> $log
/usr/bin/mysql -u$user -p$password -e "set global read_only=OFF;reset master;stop slave;change master to master_host='localhost';" >> $log
/bin/sed -i 's#read-only#\#read-only#' /etc/my.cnf
chomd 755 /usr/local/mysql/bin/remove_slave.sh
vi /usr/local/mysql/bin/mysql.sh
#!/bin/bash
/etc/init.d/keepalived stop
vi /usr/local/keepalived/bin/lvs-rs.sh
#!/bin/bash
WEB_VIP=192.168.150.174
. /etc/rc.d/init.d/functions
case "$1" in
start)
?????? ifconfig lo:0 $WEB_VIP netmask 255.255.255.255 broadcast $WEB_VIP
?????? /sbin/route add -host $WEB_VIP dev lo:0
?????? echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
?????? echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
?????? echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
?????? echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
?????? sysctl -p >/dev/null 2>&1
?????? echo "RealServer Start OK"
?????? ;;
stop)
?????? ifconfig lo:0 down
?????? route del $WEB_VIP >/dev/null 2>&1
?????? echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
?????? echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
?????? echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
?????? echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
?????? echo "RealServer Stoped"
?????? ;;
status)
??????? # Status of LVS-DR real server.
??????? islothere=`/sbin/ifconfig lo:0 | grep $WEB_VIP`
??????? isrothere=`netstat -rn | grep "lo:0" | grep $web_VIP`
??????? if [ ! "$islothere" -o ! "isrothere" ];then
??????????? # Either the route or the lo:0 device
??????????? # not found.
??????????? echo "LVS-DR real server Stopped."
??????? else
??????????? echo "LVS-DR Running."
??????? fi
;;
*)
??????? # Invalid entry.
??????? echo "$0: Usage: $0 {start|status|stop}"
??????? exit 1
;;
esac
exit 0
chmod 755 /usr/local/keepalived/bin/lvs-rs.sh
echo “/usr/local/keepalived/bin/lvs-rs.sh start” >>/etc/rc.local
vi /etc/my.cnf
將這兩個參數(shù)前邊的 # 去掉,重啟mysql
#skip-slave-start ?
#read-only
登陸mysql走越,手動將slave進程啟動
mysql>slave start;
先啟動master上的keepalived椭豫,正常后再啟動slave上的。
啟動后 主庫可以查看ip a?
[root@rac3 ~]# ip a
1: lo: mtu 16436 qdisc noqueue?
??? link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
??? inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host?
?????? valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast qlen 1000
??? link/ether 00:50:56:95:06:1f brd ff:ff:ff:ff:ff:ff
??? inet 192.168.150.171.171/24 brd 192.168.0.255 scope global eth0
??? inet 192.168.150.173/32 scope global eth0:1
??? inet 192.168.150.174/32 scope global eth0:2
inet6 fe80::250:56ff:fe95:61f/64 scope link?
?????? valid_lft forever preferred_lft forever
3: sit0: mtu 1480 qdisc noop?
link/sit 0.0.0.0 brd 0.0.0.0
slave上查看?
[root@rac1 keepalive]# ip a
1: lo: mtu 16436 qdisc noqueue?
??? link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
??? inet 127.0.0.1/8 scope host lo
??? inet 192.168.150.174/32 brd 192.168.150.174 scope global lo:0
inet6 ::1/128 scope host?
?????? valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast qlen 1000
??? link/ether 00:50:56:95:5e:b4 brd ff:ff:ff:ff:ff:ff
??? inet 192.168.150.188/24 brd 192.168.0.255 scope global eth0
??? inet 192.168.150.252/24 brd 192.168.0.255 scope global secondary eth0:1
??? inet 192.168.150.186/24 brd 192.168.0.255 scope global secondary eth0:4
inet6 fe80::250:56ff:fe95:5eb4/64 scope link?
?????? valid_lft forever preferred_lft forever
3: eth1: mtu 1500 qdisc pfifo_fast qlen 1000
??? link/ether 00:50:56:95:11:ba brd ff:ff:ff:ff:ff:ff
??? inet 10.10.10.188/24 brd 10.10.10.255 scope global eth1
??? inet 169.254.157.163/16 brd 169.254.255.255 scope global eth1:1
inet6 fe80::250:56ff:fe95:11ba/64 scope link?
?????? valid_lft forever preferred_lft forever
4: sit0: mtu 1480 qdisc noop?
link/sit 0.0.0.0 brd 0.0.0.0
發(fā)現(xiàn)210.174 讀的vip 在主備機上都可以看到
210.173 寫入vip在主上才能看到
后續(xù)多臺實驗進行中旨指,敬請等待