ホームページ  >  記事  >  データベース  >  MySQL高可用之keepalivd+互为主从_MySQL

MySQL高可用之keepalivd+互为主从_MySQL

WBOY
WBOYオリジナル
2016-06-01 13:01:471240ブラウズ

目标:配置一个keepalived双机热备架构,并配置主从复制

规划:
master1 zlm177 192.168.17.177
master2 zlm188 192.168.17.188
vip 192.168.17.166

环境: Red Hat Enterprise Linux 6.4
Percona Server 5.6.15

一、软件安装

可以去官网http://www.keepalived.org/software/下载最新版本的keepalived,目前最新的是1.2.13版,如下:
keepalived-1.2.13.tar

cp keepalived-1.2.13.tar /usr/local/src
cd /usr/local/src
tar zxvf keepalived-1.2.13.tar -C /opt/
cd /opt/keepalived-1.2.13
./configure --prefix=/usr/local/keepalived
make;makeinstall 或 make && makeinstall

注意,在编译过程中会提示缺少gcc和openssl包,用yum install装一下就可以了
RHEL6.4也可以配置CentOS的yum,具体方法这里就不讲了
yum install gcc
yum install openssl openssl-devel
还会提示xxx依赖包也需要安装,一并装上,用yum的好处就是安装方便,让系统自动判断需要哪些包,自动下载并安装,完成编译以后,软件安装就结束了

二、配置软件参数(VRRP)

装完软件后,默认会配置文件的路径为:
/usr/local/keepalived/etc/keepalived/keepalived.conf

在主端打开该配置文件,把原有内容清空,再添加以下内容:

! Configuration File for keepalived

global_defs { --全局配置
notification_email {
aaron8219@xxx.xxx --接收通知的邮箱
}
router_id aaron8219 --可以用字母,也可以使数字,可以一致,也可以不一致,只是一个标识
}

vrrp_instance my_177 {
state BACKUP --BACKUP从端模式
interface eth0
virtual_router_id 88 --默认为51,取值范围在1~255的整数,主从两端必须一致,才表示是同一个组
priority 90
advert_int 1 --检查间隔,默认1s
nopreempt --设置非抢占模式,
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress { --指定vip,
192.168.17.166
}
}

##关于vip的说明:vip随着state的变化而增加删除,当state为master的时候就添加,当state为backup的时候删除,主要是由优先级来决定的,和state设置的值没有多大关系(state相同的情况下),至于vip到底在主端还是从端,还和nopreempt有关,这里vip可以设置多个IP地址

##关于nopreempt的说明:只能设置在state为backup的节点上,且这个节点的优先级必须比另外的高

virtual_server 192.168.17.166 3306 { --虚拟服务器ip和端口
delay_loop 2
lb_algo wrr --带有权重的轮询
lb_kind DR
persistence_timeout 60
protocol TCP

real_server 192.168.17.177 3306 { --真实服务器ip和端口
weight 3 --权重为3
notify_down /opt/mysql/mysql.sh --指定自杀脚本的路径
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
}

从端的配置文件大同小异,只要把IP和实例名改成自己的就可以了,并且设置从端的priority为90,而主端为100
有一点要注意的是,主从两端的state,都配置成了backup,因为使用了nopreempt,即非抢占模式

举个例子,当主端先启动mysql实例和keepalived后,如果此时从端也启动了mysql实例和keepalived,那么vip不会跳到从端上去,即使它的优先级为100,要大于主端的90
而如果不设置nopreempt,那么这个时候,又分2种情况:

1.state相同,即都是master或都是backup
优先级高的,会占有vip,和角色无关

2.state不同,即master->backup或backup->master
优先级高的,会占有vip,和角色无关

前提不同,结果都是一样的,即优先级是主导,谁的优先级高,vip就漂到谁那里

创建一个自杀脚本来判断mysql进程是否启动
touch /opt/mysql/mysql.sh
添加以下内容:
#!/bin.sh
pkill keepalived --表示kill掉keepalived进程

三、运行测试

/usr/local/keepalived/sbin/keepalived -f /usr/local/keepalived/etc/keepalived/keepalived.conf -D

-f 指定keepalived的参数文件
-D 表示在操作系统日志里显示详细记录


判断keepalived进程是否正常启动,只要查看/var/log/messages里的日志就可以了
tail -30f /var/log/message
注意,如果没有启动mysql而先启动了keepalived,那么之前notify_down参数中指定的脚本就会被执行,表示没有找到mysql进程,把keeplied自己的进程给kill掉。


Jul 25 02:51:22 zlm188 Keepalived[3440]: Starting Keepalived v1.2.13 (07/22,2014)
Jul 25 02:51:22 zlm188 Keepalived[3441]: Starting Healthcheck child process, pid=3442
Jul 25 02:51:22 zlm188 Keepalived[3441]: Starting VRRP child process, pid=3443
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Netlink reflector reports IP 192.168.17.188 added
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Netlink reflector reports IP 192.168.17.188 added
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Netlink reflector reports IP fe80::a00:27ff:fe71:6b7b added
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Registering Kernel netlink reflector
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Netlink reflector reports IP fe80::a00:27ff:fe71:6b7b added
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Registering Kernel netlink command channel
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Registering Kernel netlink reflector
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Registering Kernel netlink command channel
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Registering gratuitous ARP shared channel
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Opening file '/usr/local/keepalived/etc/keepalived/keepalived.conf'.
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Opening file '/usr/local/keepalived/etc/keepalived/keepalived.conf'.
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Configuration is using : 11566 Bytes
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Configuration is using : 62964 Bytes
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: Using LinkWatch kernel netlink reflector...
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: VRRP_Instance(my_178) Entering BACKUP STATE
Jul 25 02:51:22 zlm188 Keepalived_vrrp[3443]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Using LinkWatch kernel netlink reflector...
Jul 25 02:51:22 zlm188 Keepalived_healthcheckers[3442]: Activating healthchecker for service [192.168.17.188]:3306
Jul 25 02:51:25 zlm188 Keepalived_healthcheckers[3442]: TCP connection to [192.168.17.188]:3306 failed !!!
Jul 25 02:51:25 zlm188 Keepalived_healthcheckers[3442]: Removing service [192.168.17.188]:3306 from VS [192.168.17.166]:3306
Jul 25 02:51:25 zlm188 Keepalived_healthcheckers[3442]: Executing [/opt/mysql/mysql.sh] for service [192.168.17.188]:3306 in VS [192.168.17.166]:3306
Jul 25 02:51:25 zlm188 Keepalived_healthcheckers[3442]: Lost quorum 1-0=1 > 0 for VS [192.168.17.166]:3306
Jul 25 02:51:25 zlm188 Keepalived[3441]: Stopping Keepalived v1.2.13 (07/22,2014)

在从端启动keepalived,跟踪日志文件可以发现,跑了一遍以后自动stopping了,这也说明,之前的配置是ok的了,否则就要检查一下,哪里配置有误,尤其要注意virtual_route_id必须保持一致,而route_id则不强行要求一致,实例名也不要重复

1.检验vip的情况
#ip address show或ip a show

2.用vip登录mysql数据库(前提是已开启了mysqld和keepalived进程)
#mysql -h192.168.17.166 -uaaron8219 -pzlm

3.关闭某一端网卡后,测试vip的去向,以及是否能通过vip正常登陆
#ifdown eth0
#ip a show
#mysql -h192.168.17.166 -uaaron8219 -pzlm

4.重启某一端(主机模拟主机故障),测试vip的去向,以及是否能通过vip正常登陆
#init 6
#ip a show
#mysql -h192.168.17.166 -uaaron8219 -pzlm

5.直接kill掉keepalived进程,测试vip的去向,以及是否能通过vip正常登陆
#pkill keepalived
#ip a show
#mysql -h192.168.17.166 -uaaron8219 -pzlm

四、配置数据库同步

安装完keepalived,只是保证了mysql数据库的高可用性,但是要真正做到互为主从,还需要配置MySQL主从复制模式,使数据库可以达到一致性状态

1.两端配置同步所需参数
确保server-id与slave不一致,通常server-id的格式可以设置成ip末尾2-3位+端口号
比如我的环境master的ip是192.168.17.177,端口是3306
那么server-id可以设置成1773306,相应地,slave就设置成1883306
以下参数都是在/etc/my.cnf文件中配置
server-id=1773306
log-bin=percona-bin --启用binlog
set-variable=binlog-ignore-db=mysql --不记录数据库mysql的更新日志,避免了Master上的权限设置等被同步到Slave上

2.两端添加复制用户
mysql> grant repliecation slave on *.* to 'rep'@'192.168.17.%' identified by 'rep';

如果想要在Slave上有权限执行 "LOAD TABLE FROM MASTER" 或 "LOAD DATA FROM MASTER" 语句的话,必须授予全局的 FILE 和 Select 权限:
mysql> GRANT FILE,Select,REPLICATION SLAVE ON *.* TO 'rep'@'%' IDENTIFIED BY 'rep';

3.设置同步
如果是新库,两边直接重置master的binlog
mysql> reset master;

(否则,需要把master的库用mysqldump导出(或直接打包压缩),再复制到从库主机,大致步骤如下:

①mysql> flush tables with read lock;
②mysql> mysqldump -uroot -p --all-databases -l -F >full_db.sql
scp full_db.sql root@192.168.17.188:/data/mysql/percona_3306/data

②cd /data/mysql/percona_3306
tar zcvf data.tar.gz ./data
scp data.tar.gz root@192.168.17.188

③mysql> unlock tables;
从库导入主库的数据库
mysql> mysql -uroot -p /mysql/percona_3306/data/full_db.sql

mysql> source /data/mysql/percona_3306/data/full_db.sql
)

4.主库查询日志状态
mysql> show master status\G

5.从库根据主库的binlog位置和position来执行同步

mysql> change master to master_host='192.168.17.177',master_user='rep',master_password='rep',

master_log_file='percona-bin.000001',master_log_pos='120';
6.启动slave
mysql> start slave;

启动后报错
Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work. Error_code: 1593

因为从库是直接通过虚拟机拷贝镜像的方式创建的,所以UUID重复了,UUID是存放在
/data/mysql/percona_3306/data/auto.cnf文件中的

可以把这个文件直接删除,或者编辑该文件,修改里面的UUID和主库不同即可,正常以后,应该是以下的状态:

(testing)root@localhost [(none)]> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.17.177
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: percona-bin.000011
Read_Master_Log_Pos: 540
Relay_Log_File: node78-relay-bin.000018
Relay_Log_Pos: 285
Relay_Master_Log_File: percona-bin.000011
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:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 540
Relay_Log_Space: 459
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:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 773306
Master_UUID: 917ecbfc-10dc-11e4-b624-080027267b03
Master_Info_File: /data/mysql/percona_3306/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0

7.测试
主库测试数据库zlm的tb_zlm表中执行插入一行数据:

(testing)root@localhost [(none)]> select * from zlm.tb_zlm;
+------+-----------+
| id | name |
+------+-----------+
| 1 | aaron8219 |
| 2 | zlm |
| 3 | abc |
+------+-----------+
3 rows in set (0.00 sec)

(testing)root@localhost [(none)]> insert into zlm.tb_zlm values(4,'def');
Query OK, 1 row affected (0.03 sec)

从库查询zlm.tb_zlm表:

(testing)root@localhost [(none)]> select * from zlm.tb_zlm;
+------+-----------+
| id | name |
+------+-----------+
| 1 | aaron8219 |
| 2 | zlm |
| 3 | abc |
| 4 | def |
+------+-----------+
4 rows in set (0.00 sec)

从库上也进行同样的配置,即可完成互为主从,只要从相应的master的binlog的pos位置开始change maseter就可以了

结论:只要配置的VRRP组里面有一台机器开启了mysqld和keepalived进程,任何通过vip实现的数据库连接访问,都是正常的,这样无论是哪个节点down掉了,都不会影响mysql数据库的可用性,是一个最简单的mysql高可用架构。自此,通过keepalived来实现互为主从的双机热备架构就完成了,如果再复杂一点,安装lvpsadm来实现虚拟服务器的配置,那么就是一个经典的keepalived+lvs架构
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。