一、背景
当前大多网站采用MYSQL+Linux+APACHE这种经典配置,如何防止单点失败造成的整个网站的不可用是网站管理者必须要考虑的问题,其中数据库的高可用性(Database server’s high availability)是重中之重。
对于数据库的高可用性,各商业软件的厂商都有各自的解决方案,比如Oracle OPS server和IBM DB2 (share-nothing architecture)。最近MYSQL AB也发布了MYSQL cluster 软件,使用与IBM DB2类似的技术。
MySQL cluster可能会是日后最理想的方案,但是从资源、可集成度方面考虑,给出一个简单实用的方案借鉴。本文介绍的是性价比比较高的一种: 使用Heartbeat 2.0配置Linux高可用性集群。
 
二、实现原理
通过Linux HA 软件 heartbeat 实现IP的自动漂移,即当一台服务器宕机后,浮动IP(整个cluster的对外IP )自动漂移到另外一台服务器。
1
通过Mysql自身的replication 实现不同机器上多个数据库的同步整体性能此方案将会降低MYSQL 1%左右的性能,可用性及数据安全性将大有提高,同时服务器的切换对终端使用者是透明的,终端应用不需要进行更改。
所需硬件
安装有双网卡的配置大致相同的服务器或工作机两台 一条交叉网线(用于双机对连的心跳线)
 
所需软件
 
Linux HA 软件 heartbeat (只支持两个节点),安装盘里集成的有这个软件的rpm包
Mysql软件
 
实现步骤
 
一、设置硬件环境:如下表:
2
primary和backup的eth0分别连接到你的交换机
primary和backup的eth1之间用心跳线直连起来,做心跳
浮动IP为192.168.0.8/255.255.255.0
 
二、安装MYSQL
在primary节点上安装mysql数据库
这里我开始都把它下载到本地了,所以这里我用软件把mysql包上传到服务器root目录下
1、在linux系统中添加运行Mysql的用户和组
[root@primary ~]# groupadd mysql
[root@primary ~]# useradd -g mysql mysql
2、解压缩源码包
[root@primary ~]# tar -zxvf mysql-5.0.22.tar.gz
[root@primary ~]# cd mysql-5.0.22
3、配置编译
配置mysql的安装目录,并制定数据库的存放位置
[root@primary mysql-5.0.22]# ./configure --prefix=/usr/local/mysql \
--localstatedir=/var/lib/mysql
4、编译并安装
[root@primary mysql-5.0.22]#make
[root@primary mysql-5.0.22]#make install
5、装载原始授权到数据库
[root@primary mysql-5.0.22]#./scripts/mysql_install_db
6、copy配置文件到/etc目录
[root@primary mysql-5.0.22]# cp support-files/my-medium.cnf /etc/my.cnf
7、copy启动脚本到资源目录
cp support-files/mysql.server /etc/rc.d/init.d/mysqld
8、添加mysql服务,让系统启动时自动启动mysql服务
[root@primary mysql-5.0.22]#chmod +x /etc/rc.d/init.d/mysqld
[root@primary mysql-5.0.22]#chkconfig --level 235 mysqld on
9、更改目录属主/var/lib/mysql
[root@primary mysql-5.0.22]#chown -R mysql.mysql /var/lib/mysql
10、启动mysql
[root@primary mysql-5.0.22]#service mysqld start
11、设置环境变量
[root@primary ~]# vi /etc/profile添加一行就 ,在运行mysql的时候就不用输入很长的路经了
export PATH=$PATH:/usr/local/mysql/bin
设置好之后,用下行命令是设置立即生效
# source /etc/profile
在backup服务器上安装mysql如同上面的步骤
在mysql数据库中创建一个库,用来同步数据和测试用,mysql安装完后有一个练习库test这里就不建了直接就用它了。在test库里面先建一个表
登陆mysql数据库
mysql -u root -p
(执行后提示输入密码,正确输入mysql root用户密码后,登入mysql,以下操作在mysql命令行下进行)
要使用test数据库,先用use命令选择该数据库:
mysql>use test
创建一个表
下面使用create table语句指定你要建的表的布局,下面只是用于一个测试的表。我就随便建了一个:
mysql> create table data(name VARCHAR(20), address VARCHAR(50), phone VARCHAR(20));
Query OK, 0 rows affected (0.11 sec)
在表中添加一条记录,用insert into语句:
mysql>insert into data(name,address,phone) values('jhone','beijing','138000000');
Query OK, 1 row affected (0.02 sec)
查看表中的记录
mysql> select * from data;
+-------+---------+-----------+
| name | address | phone |
+-------+---------+-----------+
| jhone | beijing | 138000000 |
+-------+---------+-----------+
1 row in set (0.05 sec)
 
三、设置Mysql Replication
3.1、在primary主机上mysql的设置
1)增加一用于数据库同步的用户replicate
mysql -u root -p
(执行后提示输入密码,正确输入mysql root用户密码后,登入mysql,以下操作在mysql命令行下进行)
mysql>GRANT REPLICATION SLAVE,REPLICATION CLIENT,RELOAD,SUPER ON *.* TO 'replicate'@'10.1.1.2' IDENTIFIED BY 'you password';
(授与从10.0.0.2主机上登录用户replicate数据复制权限,4.02版本以前用:GRANT FILE ON *.* TO replicate@10.0.0.1 IDENTIFIED BY 'password';)
mysql>flush privileges;
使权限生效,这步可不做,因为过会要重启mysql)
mysql> exit
(退出mysql命令行界面)
2) 停止mysql服务
service mysqld stop
3)建立用于更新日志的目录,并给于mysql的权限
[root@primary ~]# mkdir /var/log/mysql
[root@primary ~]# chown mysql.mysql /var/log/mysql/
4)更改Mysql配置文件/etc/my.cnf 没有的添加上去
vi /etc/my.cnf
3
5)将要进行复制的数据库打包传到server服务器上
[root@primary mysql]# tar -zcvf /root/db.tar test/ (将要进行复制的test数据库打包)
[root@primary ~]# scp db.tar root@10.1.1.2:/var/lib/mysql/ (将.tar复制到server的/var/lib/mysql/目录)
6)启动Mysql
service mysqld start
至此,primary上的Mysql设置完毕,
3.2、在backup主机上mysql的配置
1)增加一用于数据库同步的用户replicate
mysql -u root -p (执行后提示输入密码,正确输入mysql root用户密码后,登入mysql,以下操作在mysql命令行下进行)
GRANT REPLICATION SLAVE,REPLICATION CLIENT,RELOAD,SUPER ON *.* TO 'replicate'@'10.1.1.1' IDENTIFIED BY 'you password';
(授与从10.0.0.1主机上登录用户replicate数据复制权限,4.02版本以前用:GRANT FILE ON *.* TO replicate@10.0.0.1 IDENTIFIED BY 'password';)
mysql>flush privileges; (使权限生效,这步可不做,因为过会要重启mysql)
mysql> exit (退出mysql命令行界面)
2)停止mysql服务
service mysqld stop
3)更改Mysql配置文件/etc/my.cnf
vi /etc/my.cnf
4
4)将先前从primary上发过来的数据库的打包文件解压并替换掉原有文件,并确保属主及权限正确
cd /var/lib/mysql
tar -xvf /db.tar
chown -R mysql.mysql test
chmod 700 test
chmod 660 test
5)启动Mysql服务
service mysqld start
至此server服务器上的Mysql设置完毕
3.3、查询配置
Show Slave status:此处Slave_IO_Running ,Slave_SQL_Running 都应该是yes,表示从库的I/O,Slave_SQL线程都正确开启.
在Mysql中可通过以下命令来查看主从状态
show master status 查看master状态
show slave status 查看slave状态
show processlist G 查看当前进程
stop slave 暂时停止slave进程
start slave 开始slave进程
在primary服务器上 MySQL命令符下输入:
mysql>show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| updatelog.000001 | 614 | test | mysql |
+------------------+----------+--------------+------------------+
显示(不同主机结果不同)
show slave status\G;  看一下从服务器的同步情况
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
主要是看这两行,如果都是yes,那代表已经在同步
更多详细信息以及参数设置,请参考MySQL 5.0 Manual手册.
 
四、安装配置Linux HA软件heartbeat
在每个节点上分别安装heartbeat
1、安装支持包(linux-ha.org站点提供下载)
Linux的版本不同,RPM文件名可能会不同,请选择相应版本的RPM
rpm -iUvh libnet-*
rpm -iUvh perl-Parse-RecDescent-*
rpm -iUvh perl-Mail-IMAPClient-*
rpm -iUvh perl-Net-SSLeay-*
rpm -iUvh perl-Digest-SHA1-*
rpm -iUvh perl-Digest-HMAC-*
rpm -iUvh perl-Authen-SASL-*
rpm -iUvh perl-Convert-ASN1-*
rpm -iUvh perl-IO-Socket-SSL-*
rpm -iUvh perl-XML-NamespaceSupport-*
rpm -iUvh perl-XML-SAX-*
rpm -iUvh perl-ldap-*
2、按装heartbeat
以RPM方式按装(推荐),Linux的版本不同,RPM文件名可能会不同,请选择相应版本的RPM
rpm -iUvh heartbeat-pils-2.1.3-1.rh.el.3.0.i386.rpm
rpm -iUvh heartbeat-stonith-2.1.3-1.rh.el.3.0.i386.rpm
rpm -iUvh heartbeat-ldirectord-2.1.3-1.rh.el.3.0.i386.rpm
rpm -iUvh heartbeat-2.1.3-1.rh.el.3.0.i386.rpm
3、Copy配置文件到/etc/ha.d目录 (只在一个节点上做即可,所有配置完成后copy到其它节点)
cp /usr/share/doc/heartbeat-2.1.3 /ha.cf /etc/ha.d/
cp /usr/share/doc/heartbeat-2.1.3/haresources /etc/ha.d/
cp /usr/share/doc/heartbeat-2.1.3/authkeys /etc/ha.d/
3.Copy配置文件到/etc/ha.d目录 (只在一个节点上做即可,所有配置完成后copy到其它节点)
cp /usr/share/doc/heartbeat-2.1.3/ha.cf /etc/ha.d/
cp /usr/share/doc/heartbeat-2.1.3/haresources /etc/ha.d/
cp /usr/share/doc/heartbeat-2.1.3/authkeys /etc/ha.d/
安装好HA之后就开始配置
4、配置/etc/ha.d/ha.cf (只在一个节点上配即可,配好后copy到其它节点)
vi /etc/ha.d/ha.cf
按如下内容进行修改(文件中#开头的行为注释行,更多的选项及选项的详细说明请参考文件中的注释及相关文档)
5
5、配置/etc/ha.d/haresources (只在一个节点上配即可,配好后copy到其它节点)
按如下内容进行修改(文件中#开头的行为注释行,更多的选项及选项的详细说明请参考文件中的注释及相关文档)
vi /etc/ha.d/haresources在配置文件中添加如下一行
primary 192.168.0.8 mysqld #设置heartbeat管理的资源或服务
#格式为:主节点主机名或域名 浮动IP 服务名
#主节点主机名或域名为ha.cf中node行中指定的任一节点
#浮动IP 为对外提供访问的IP,主节点失败后会自动漂移到其它节点,继续对外提供服务.
#服务名 为 heartbeat管理的服务
#注意,此文件内容所有节点必须保持一致。
6、配置/etc/ha.d/authkeys (只在一个节点上配即可,配好后copy到其它节点)
vi /etc/ha.d/authkeys
按如下内容进行修改(文件中#开头的行为注释行,更多的选项及选项的详细说明请参考文件中的注释及相关文档)
6
#sha1和md5都需要提供认证KEY,即用来加密的KEY
#注意,此文件权限必须设置为600。如果不权限不是600HA将不能正常启动。
7、copy配置文件到backup服务器上
#/scp /etc/ha.d/ha.cf /etc/ha.d/haresources /etc/ha.d/authkeys root@10.1.1.2:/etc/ha.d/
8、分别设置各节点/etc/ha.d/authkeys文件权限
#/chmod 600 /etc/ha.d/authkeys (文件权限必须设置为600,否则heartbeat不能正常启动)
9、设置主服务器和备份服务器时间同步
虽然Heartbeat不要求在两个服务器上使系统钟同步主要和备份服务器,但是系统时钟应该在的几十秒之内,否则在高可用性服务的环境下会产生故障。 在在两个系统启动Heartbeat之前,你应该人工检查并且放置系统时间(使用date命令)。 关于一种更好的长期的解决的方法你应该在两个系统上使用NTP软件同步钟。     
10、在每个节点上启动heartbeat
#/service heartbeat start 或者 #/etc/init.d/heartbeat start
 
五、测试
1、 主服务器的mysql服务应该被heartbeat启动,同时heartbeat为主节点设置IP地址192.168.0.8。使用ifconfig eth0:0可以看到如下信息
Eth0:0 Link encap:Ethernet HWaddr 00:0C:29:22:7E:15
inet addr:192.168.0.8 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe22:7e15/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:324 errors:0 dropped:0 overruns:0 frame:0
TX packets:34 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:43369 (42.3 KiB) TX bytes:7878 (7.6 KiB)
2、 查看主服务器日志信息
可以使用命令查看日志文件:
#tail -f /var/log/messages
此时会发现出现如下信息:   
primary heartbeat[2886]: info: Heartbeat restart on node backup
primary heartbeat[2886]: info: Link backup:eth1 up.
primary heartbeat[2886]: info: Node backup: status up
primary heartbeat: info: Running /etc/ha.d/rc.d/status status
primary heartbeat: info: Running /etc/ha.d/rc.d/ifstat ifstat
primary heartbeat[2886]: info: Node backup: status active
primary heartbeat: info: Running /etc/ha.d/rc.d/status status
可以使用tcpdump命令查看心跳广播是否到达两个服务器节点。
#tcpdump -i all -n -p udp port 694
3、 停止主服务器的Heartbeat
停止主服务器的Heartbeat,使用命令:
#/etc/init.d/heartbeat stop 或者 #service heartbeat stop
现在使用ifconfig eth0:0可以看到如下信息:
eth0:0 Link encap:Ethernet HWaddr 00:0C:29:E1:14:84
inet addr:192.168.0.8 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fee1:1484/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:73 errors:0 dropped:0 overruns:0 frame:0
TX packets:39 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:8218 (8.0 KiB) TX bytes:8147 (7.9 KiB)
这说明浮动IP已经切换到backup服务器上了。
此时可以使用命令查看backup服务器日志文件:
#tail -f /var/log/messages
此时会发现出现如下信息:
backup heartbeat[4950]: WARN: node primary: is dead
backup heartbeat[4950]: info: Link primary:eth1dead.
backup heartbeat: info: Running /etc/ha.d/rc.d/status status
backup heartbeat: info: Running /etc/ha.d/rc.d/ifstat ifstat
backup heartbeat: info: Taking over resource group test
*** /etc/ha.d/resource.d/test called with status
backup heartbeat: info: Acquiring resource group:
primary.
com test
backup heartbeat: info: Running /etc/ha.d/resource.d/test start
*** /etc/ha.d/resource.d/test called with start
backup heartbeat: info: mach_down takeover complete.
在这个过程中,使用ping命令进行不间断监测,可以发现集群IP地址一直处于可通状态,并没有产生任何阻塞或延迟,所以,在关闭处于激活状态的heartbeat的情况下,双机系统可以实现无缝切换。