高可用集群是指以减少服务中断时间为目的的服务器集群技术。它通过保护用户的业务程序对外不间断提供的服务,把因软件/硬件/人为造成的故障对业务的影响降低到最小程度。高可用集群的应用系统有多样化发展趋势,用途也越来越多样化,同时带来了配置及可操作性方面的复杂性,因此选择好的高可用软件至关重要。本文章实现用corosync+pacemaker实现mysql的高可用,并且通过配置一台NFS服务器专门用来存储mysql的数据,从而实现mysql读取写入数据的一致性。

一,配置NFS服务器

二,配置mysql服务器,并为配置HA做准备工作:

三,安装corosync+pacemakershix实现基于mysql的高可用

实验拓扑;

 

集群:corosync+pacemaker实现mysql服务高可用_第1张图片

一,配置NFS服务器(172.16.30.5)
由于我们的NFS服务器要作为一个共享存储介质,存放mysql的数据文件,为了使数据存放目录的所有者是mysql用户和组,我们在NFS和两台mysql服务器上都要创建相同uid,gid的mysql用户和组,因为NFS是通过识别UID来区分用户的,通过这样的方式可以实现我们mysql服务器用mysql身份访问共享存储介质的mydata目录时,被NFS识别为文件的属主和属主。
创建mysql组和用户:
# groupadd -g 306  -r mysql
# useradd -g mysql -u 306 -s /sbin/nologin mysql
 
我们要建立一个逻辑卷用于存放mysql数据的文件:
首先进行分区,用作物理卷的分区的id为8e,大小为10G,我们这里以创建分区/dev/sda3为例:
#fdisk /dev/sda
 
让kernel识别新建的分区:
#partprobe /dev/sda
 
创建物理卷:
#pvcreate /dev/sda3
 
创建卷组:
#vgcreate myvg /dev/sda3
 
创建逻辑卷;
#lvcreate -L 5G -n lv_mydata myvg
 
格式化逻辑卷:
#mke2fs -j /dev/myvg/lv_mydata
 
# mkdir /mydata
 
#vim /etc/fstab
添加如下行:
/dev/myvg/lv_mydata     /mydata    ext3    defaults        0 0
 
#mount -a
查看是否挂载成功:
# ls /mydata
lost+found
 
查看nfs的软件包是否安装,如果没有安装要安装此软件包:
# rpm -q nfs-utils
查看portmap服务的状态(要开启portmap服务):
#service portmap status 
打开NFS的配置文件进行编辑:
# service nfs start
#vim /etc/exports
添加要把哪个文件共享给mysql服务器,这个文件是用于存放mysql数据的目录:
/mydata  172.16.30.4(rw,no_root_squash) 172.16.30.6(rw,no_root_squash)
把/etc/exports定义的内容生效,导出文件系统:
# exportfs -arv
更改mydata目录的属主属组:
# chown -R mysql.mysql /mydata
 
 
二,配置mysql服务器,并为配置HA做准备工作:
为了配置一台Linux主机成为HA的节点,通常需要做出如下的准备工作:
注意:要保证两台server的系统时间一致
 
1)所有节点的主机名称和对应的IP地址解析服务可以正常工作,且每个节点的主机名称需要跟"uname -n“命令的结果保持一致;因此,需要保证两个节点上的/etc/hosts文件均为下面的内容:
172.16.30.4 node1.magedu.com node1
172.16.30.6 node2.magedu.com node2
 
为了使得重新启动系统后仍能保持如上的主机名称,还分别需要在各节点执行类似如下的命令:
 
Node1:
# sed -i 's@\(HOSTNAME=\).*@\1node1.magedu.com@g'  /etc/sysconfig/network
# hostname node1.magedu.com
 
Node2:
# sed -i 's@\(HOSTNAME=\).*@\1node2.magedu.com@g' /etc/sysconfig/network
# hostname node2.magedu.com
 
2)设定两个节点可以基于密钥进行ssh通信,这可以通过类似如下的命令实现:
Node1:
# ssh-keygen -t rsa
# ssh-copy-id -i ~/.ssh/id_rsa.pub root@node2
Node2:
# ssh-keygen -t rsa
# ssh-copy-id -i ~/.ssh/id_rsa.pub root@node1
 
 
172.16.30.4上的配置:
# groupadd -g 306 -r mysql
# useradd -u 306 -g mysql -r   mysql
# mkdir /mydata
 
挂载NFS文件系统:
# mount -t nfs 172.16.30.5:/mydata /mydata
# ls /mydata
以mysql用户的身份创建要存放mysql数据文件的目录:
$ su - mysql
$ cd /mydata
$ mkdir data
$ exit
 
172.16.30.6上也要进行配置,但配置与此相同(不用以mysql用户身份创建data目录)。
 
172.16.30.4的配置:
mysql的安装;
# tar xf mysql-5.5.20-linux2.6-i686.tar.gz -C /usr/local
# cd /usr/local/
# ln -sv mysql-5.5.20-linux2.6-i686  mysql
# cd mysql 
 
# chown -R mysql:mysql  .
 
初始化mysql数据库:
# scripts/mysql_install_db --user=mysql --datadir=/mydata/data
# chown -R root  .
 
为mysql提供主配置文件
# cp support-files/my-large.cnf  /etc/my.cnf
 
并修改此文件中thread_concurrency的值为你的CPU个数乘以2,比如这里使用如下行:
# vim /etc/my.cnf
thread_concurrency = 2
 
另外还需要添加如下行指定mysql数据文件的存放位置:
datadir = /mydata/data
 
172.16.30.6上的配置文件和此相同,故直接复制过去:
# scp /etc/my.cnf node2:/etc/my.cnf
 
为mysql提供sysv服务脚本,使其能使用service命令:
# cp support-files/mysql.server  /etc/rc.d/init.d/mysqld
 
添加至服务列表:
# chkconfig --add mysqld
确保开机不能自动启动,我们要用CRM控制:
# chkconfig mysqld off
 
而后就可以启动服务测试使用了:
#service mysqld start
测试之后关闭服务:
# service mysqld stop
 
为了使用mysql的安装符合系统使用规范,并将其开发组件导出给系统使用,这里还需要进行如下步骤:
 
输出mysql的man手册至man命令的查找路径:
 
vim /etc/man.config
添加如下行即可:
MANPATH  /usr/local/mysql/man
 
输出mysql的头文件至系统头文件路径/usr/include:
 
这可以通过简单的创建链接实现:
# ln -sv /usr/local/mysql/include  /usr/include/mysql
 
输出mysql的库文件给系统库查找路径:
文件只要是在/etc/ld.so.conf.d/下并且后缀是.conf就可以
# echo '/usr/local/mysql/lib' > /etc/ld.so.conf.d/mysql.conf
 
而后让系统重新载入系统库:
# ldconfig
 
修改PATH环境变量,让系统所有用户可以直接使用mysql的相关命令:
#vim /etc/profile
PATH=$PATH:/usr/local/mysql/bin  (重新登录系统即可生效)
 
 
172.16.30.6上的配置:
mysql的安装;
# tar xf mysql-5.5.20-linux2.6-i686.tar.gz -C /usr/local
# cd /usr/local/
# ln -sv mysql-5.5.20-linux2.6-i686  mysql
# cd mysql 
 
不能对数据库进行初始化,因为我们在172.16.30.4上已经初始化了:
# chown -R root:mysql  .
 
mysql配置文件已经复制过来了,不用改。但要为mysql提供sysv服务脚本,使其能使用service命令:
# cp support-files/mysql.server  /etc/rc.d/init.d/mysqld
 
添加至服务列表:
# chkconfig --add mysqld
确保开机不能自动启动,我们要用CRM控制:
# chkconfig mysqld off
 
而后就可以启动服务测试使用了:(只有172.16.30.4的mysql服务停了才能进行测试)
#service mysqld start
然后关闭服务:
# service mysqld stop
 
为了使用mysql的安装符合系统使用规范,并将其开发组件导出给系统使用,这里还需要进行如下步骤:
 
输出mysql的man手册至man命令的查找路径:
vim /etc/man.config
添加如下行即可:
MANPATH  /usr/local/mysql/man
 
输出mysql的头文件至系统头文件路径/usr/include:
 
这可以通过简单的创建链接实现:
# ln -sv /usr/local/mysql/include  /usr/include/mysql
 
输出mysql的库文件给系统库查找路径:
文件只要是在/etc/ld.so.conf.d/下并且后缀是.conf就可以
# echo '/usr/local/mysql/lib' > /etc/ld.so.conf.d/mysql.conf
 
而后让系统重新载入系统库:
# ldconfig
 
修改PATH环境变量,让系统所有用户可以直接使用mysql的相关命令:
#vim /etc/profile
PATH=$PATH:/usr/local/mysql/bin  (重新登录系统即可生效)
 
 
三,安装corosync+pacemakershix实现基于mysql的高可用
1,在两个节点上执行操作,去掉mysql的挂载目录,我们要实现把nfs定义为资源,可以实现自动挂载:
# umount /mydata
 
2,安装corosync和pacemaker,首先下载所需要如下软件包至本地某专用目录(这里为/root/cluster):
cluster-glue
cluster-glue-libs
heartbeat
resource-agents
corosync
heartbeat-libs
pacemaker
corosynclib
libesmtp
pacemaker-libs
openais   (这个两个包做如下的实验没有用,可以不装)
openaislib
 
下载地址:http://clusterlabs.org/rpm/。请根据硬件平台及操作系统类型选择对应的软件包;这里建议每个软件包都使用目前最新的版本。
 
3,使用如下命令安装:
# cd /root/cluster
# yum -y --nogpgcheck localinstall *.rpm  (配置好yum源为系统光盘,会对系统光盘中的软件包有依赖关系)
注意:两个节点都要进行软件包的安装
 
4、配置corosync:(以下命令在node1.magedu.com上执行)
 
# cd /etc/corosync
# cp corosync.conf.example corosync.conf
 
接着编辑corosync.conf,添加如下内容:
service {
ver:  0
name: pacemaker
use_mgmtd: yes
}
 
aisexec {
user: root
group:  root
}
 
开启安全验证功能,当有节点加入集群需要有验证密码串:
secauth: on
 
并设定此配置文件中 bindnetaddr后面的IP地址为你的网卡所在网络的网络地址,我们这里的两个节点在172.16.0.0网络,因此这里将其设定为172.16.0.0,如下(也可以是ip地址):
bindnetaddr: 172.16.0.0
 
设定多播地址,从224.0.0.0到239.255.255.255都可以设定:
mcastaddr: 229.94.1.1
 
生成节点间通信时用到的认证密钥文件:
# corosync-keygen
 
将corosync和authkey复制至node2:
# scp -p corosync.conf authkey  node2:/etc/corosync/
 
分别为两个节点创建corosync生成的日志所在的目录:
# mkdir /var/log/cluster
# ssh node2  'mkdir /var/log/cluster'
 
5、尝试启动,(以下命令在node1上执行):
 
# /etc/init.d/corosync start
 
查看corosync引擎是否正常启动:
# grep -e "Corosync Cluster Engine" -e "configuration file" /var/log/messages
Jun 14 19:02:08 node1 corosync[5103]:   [MAIN  ] Corosync Cluster Engine ('1.2.7'): started and ready to provide service.
Jun 14 19:02:08 node1 corosync[5103]:   [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'.
Jun 14 19:02:08 node1 corosync[5103]:   [MAIN  ] Corosync Cluster Engine exiting with status 8 at main.c:1397.
Jun 14 19:03:49 node1 corosync[5120]:   [MAIN  ] Corosync Cluster Engine ('1.2.7'): started and ready to provide service.
Jun 14 19:03:49 node1 corosync[5120]:   [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'.
 
查看初始化成员节点通知是否正常发出:
# grep  TOTEM  /var/log/messages
Jun 14 19:03:49 node1 corosync[5120]:   [TOTEM ] Initializing transport (UDP/IP).
Jun 14 19:03:49 node1 corosync[5120]:   [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).
Jun 14 19:03:50 node1 corosync[5120]:   [TOTEM ] The network interface [172.16.100.11] is now up.
Jun 14 19:03:50 node1 corosync[5120]:   [TOTEM ] A processor joined or left the membership and a new membership was formed.
 
检查启动过程中是否有错误产生:
# grep ERROR: /var/log/messages | grep -v unpack_resources
 
查看pacemaker是否正常启动:
# grep pcmk_startup /var/log/messages
Jun 14 19:03:50 node1 corosync[5120]:   [pcmk  ] info: pcmk_startup: CRM: Initialized
Jun 14 19:03:50 node1 corosync[5120]:   [pcmk  ] Logging: Initialized pcmk_startup
Jun 14 19:03:50 node1 corosync[5120]:   [pcmk  ] info: pcmk_startup: Maximum core file size is: 4294967295
Jun 14 19:03:50 node1 corosync[5120]:   [pcmk  ] info: pcmk_startup: Service: 9
Jun 14 19:03:50 node1 corosync[5120]:   [pcmk  ] info: pcmk_startup: Local hostname: node1.magedu.com
 
如果上面命令执行均没有问题,接着可以执行如下命令启动node2上的corosync
# ssh node2 -- /etc/init.d/corosync start
注意:启动node2需要在node1上使用如上命令进行,不要在node2节点上直接启动;
 
使用如下命令查看集群节点的启动状态:
# crm status
============
Last updated: Tue Jun 14 19:07:06 2011
Stack: openais
Current DC: node1.magedu.com - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, 2 expected votes
0 Resources configured.
============
 
Online: [ node1.magedu.com node2.magedu.com ]
 
从上面的信息可以看出两个节点都已经正常启动,并且集群已经处于正常工作状态。
 
6、配置集群的工作属性,禁用stonith
 
corosync默认启用了stonith,而当前集群并没有相应的stonith设备,因此此默认配置目前尚不可用,这可以通过如下命令验正:
 
# crm_verify -L 
crm_verify[5202]: 2011/06/14_19:10:38 ERROR: unpack_resources: Resource start-up disabled since no STONITH resources have been defined
crm_verify[5202]: 2011/06/14_19:10:38 ERROR: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option
crm_verify[5202]: 2011/06/14_19:10:38 ERROR: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity
Errors found during check: config not valid
  -V may provide more details
 
我们里可以通过如下命令先禁用stonith:
# crm configure property stonith-enabled=false
 
使用如下命令查看当前的配置信息:
# crm configure show
node node1.magedu.com
node node2.magedu.com
property $id="cib-bootstrap-options" \
dc-version="1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87" \
cluster-infrastructure="openais" \
expected-quorum-votes="2" \
stonith-enabled="false"
从中可以看出stonith已经被禁用。
 
上面的crm,crm_verify命令是1.0后的版本的pacemaker提供的基于命令行的集群管理工具;可以在集群中的任何一个节点上执行。
 
7、为集群添加集群资源
corosync支持heartbeat,LSB和ocf等类型的资源代理,目前较为常用的类型为LSB和OCF两类,stonith类专为配置stonith设备而用;
 
可以通过如下命令查看当前集群系统所支持的类型:
 
# crm ra classes 
heartbeat
lsb
ocf / heartbeat pacemaker
stonith
 
如果想要查看某种类别下的所用资源代理的列表,可以使用类似如下命令实现:
# crm ra list lsb
# crm ra list ocf heartbeat
# crm ra list ocf pacemaker
# crm ra list stonith
 
# crm ra info [class:[provider:]]resource_agent
例如:
# crm ra info ocf:heartbeat:IPaddr
 
8、接下来要创建的mysql集群创建一个IP地址资源,以在通过集群提供服务时使用;这可以通过如下方式实现:
# crm configure primitive myip ocf:heartbeat:IPaddr params ip=172.16.30.1
 
通过如下的命令执行结果可以看出此资源已经在node1.magedu.com上启动:
# crm status
============
Last updated: Wed Apr 18 00:52:46 2012
Stack: openais
Current DC: node1.magedu.com - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, 2 expected votes
1 Resources configured.
============
 
Online: [ node1.magedu.com node2.magedu.com ]
 
 myip (ocf::heartbeat:IPaddr): Started node1.magedu.com
 
当然,也可以在node1上执行ifconfig命令看到此地址已经在eth0的别名上生效:
# ifconfig 
eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:98:73:47  
          inet addr:172.16.30.1  Bcast:172.16.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:67 Base address:0x2000          
 
对于双节点的集群来说,我们要配置此选项来忽略quorum,即这时候票数不起作用,一个节点也能运行:
# crm configure property no-quorum-policy=ignore
 
把NFS配置成高可用资源:
# crm configure primitive mynfs ocf:heartbeat:Filesystem params device="172.16.30.1:/mydata" directory="/mydata" fstype="nfs" op start timeout=60s op stop timeout=60s
 
把node2作为备用节点:
# crm node standby
# crm status
============
Last updated: Tue Apr 17 22:35:05 2012
Stack: openais
Current DC: node1.magedu.com - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, 2 expected votes
2 Resources configured.
============
 
Node node2.magedu.com: standby
Online: [ node1.magedu.com ]
 
 myip (ocf::heartbeat:IPaddr): Started node1.magedu.com
 mynfs (ocf::heartbeat:Filesystem): Started node1.magedu.com
 
然后我们可以在node1节点上看mydata目录是否会被自动挂载;
# ls /mydata
data lost+found 
 
配置mysqld服务为高可用资源:
# crm configure primitive mysqld lsb:mysqld
# crm status
============
Last updated: Tue Apr 17 22:37:07 2012
Stack: openais
Current DC: node1.magedu.com - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, 2 expected votes
3 Resources configured.
============
 
Node node2.magedu.com: standby
Online: [ node1.magedu.com ]
 
 myip (ocf::heartbeat:IPaddr): Started node1.magedu.com
 mynfs (ocf::heartbeat:Filesystem): Started node1.magedu.com
 mysqld (lsb:mysqld): Started node1.magedu.com
 
在node1上查看mysqld运行状态:
# service mysqld status
MySQL running (19795)                                      [  OK  ]
 
把mysqld,mynfs,myip资源绑定在一起,他们只能同时处在一个节点上:
# crm configure colocation mysqld_and_mynfs inf: mysqld mynfs myip
 
接着,我们还得确保mysqld在某节点启动之前得先启动myip和mynfs,这可以使用如下命令实现:
# crm configure order mysqld-after-mynfs mandatory: mynfs mysqld:start
# crm configure order mysqld-after-myip  mandatory: myip mysqld
查看我们的配置:
# crm configure show
node node1.magedu.com \
attributes standby="on"
node node2.magedu.com \
attributes standby="off"
primitive myip ocf:heartbeat:IPaddr \
params ip="172.16.30.1"
primitive mynfs ocf:heartbeat:Filesystem \
params device="172.16.30.5:/mydata" directory="/mydata" fstype="nfs" \
op start interval="0" timeout="60s" \
op stop interval="0" timeout="60s"
primitive mysqld lsb:mysqld
colocation mysqld_and_mynfs inf: mysqld mynfs myip
order mysqld-after-myip inf: myip mysqld
order mysqld-after-mynfs inf: mynfs mysqld:start
property $id="cib-bootstrap-options" \
dc-version="1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87" \
cluster-infrastructure="openais" \
expected-quorum-votes="2" \
stonith-enabled="false" \
no-quorum-policy="ignore"
# crm status
============
Last updated: Tue Apr 17 22:47:06 2012
Stack: openais
Current DC: node1.magedu.com - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, 2 expected votes
3 Resources configured.
============
 
Node node2.magedu.com: standby
Online: [ node1.magedu.com ]
 
 myip (ocf::heartbeat:IPaddr): Started node1.magedu.com
 mynfs (ocf::heartbeat:Filesystem): Started node1.magedu.com
 mysqld (lsb:mysqld): Started node1.magedu.com
 
当我们把node2节点上线,然后把node1节点作为备用节点的话,资源会立即切换到node2上:
在node1上操作:
# crm node standby
# crm status
============
Last updated: Tue Apr 17 22:43:19 2012
Stack: openais
Current DC: node1.magedu.com - partition with quorum
Version: 1.0.11-1554a83db0d3c3e546cfd3aaff6af1184f79ee87
2 Nodes configured, 2 expected votes
3 Resources configured.
============
 
Node node1.magedu.com: standby
Online: [ node2.magedu.com ]
 
 myip (ocf::heartbeat:IPaddr): Started node2.magedu.com
 mynfs (ocf::heartbeat:Filesystem): Started node2.magedu.com
 mysqld (lsb:mysqld): Started node2.magedu.com
 
在node2上创建一个远程登录用户:
# /usr/local/mysql/bin/mysql
mysql> grant all privileges on *.* to jia@'172.16.%.%' identified by '13456';
Query OK, 0 rows affected (0.01 sec)
 
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
 
我们通过172.16.30.1这个ip地址提供服务,然后我们通过172.16.0.0网段的另一台主机即可登录:
# mysql -ujia -h172.16.30.1 -p123456