HA集群之DRBD实现MySQL高可用
一、前言
本篇博文只是实现Corosync + Pacemaker + DRBD + MySQL,实现MySQL的高可用。更多的基础知识在前几篇博文中已有涉猎,故更多的理论细节将不再此篇中详述。
若想了解高可用基础知识,请参考:http://hoolee.blog.51cto.com/7934938/1406951
若想了解Corosync + Pacemaker,请参考:http://hoolee.blog.51cto.com/7934938/1409395
若想了解DRBD,请参考:http://hoolee.blog.51cto.com/7934938/1410121
二、实现方式
双节点实现:
node1: 172.16.1.11 node1.hoo.com
node2: 172.16.1.12 node2.hoo.com
vip: 172.16.1.100
三、Corosync + Pacemaker搭建集群环境
1.配置主机名
节点名称很关键,集群每个节的名称都得能互相解析。/etc/hosts中的主机名配置结果必须跟”uname -n”的解析的结果一致。
node1/node2都添加:
1 2 3 4 5 6 7 8 9 | node1示例: # vim /etc/hosts 172.16.1.11 node1.hoo.com node1 172.16.1.12 node2.hoo.com node2 # ifconfig eth0 172.16.1.11 up # hostname node1.hoo.com # uname -n # vim /etc/sysconfig/network //重启才生效,source也不生效 hostname =node1.hoo.com |
2.配置node之间SSH互信
1 2 3 4 5 6 7 8 | node1: #ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ‘‘ # ssh-copy-id -i .ssh/id_rsa.pub root@node2.hoo.com node1: #ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ‘‘ # ssh-copy-id -i .ssh/id_rsa.pub root@node1.hoo.com node1:测试 # ssh node2.hoo.com ‘date’;date |
3.同步时间
# crontab -e */5* * * * /usr/sbin/ntpdate172.16.0.1 &> /dev/null
4.安装corosync和pacemaker
所有节点均安装
1 2 3 4 5 | # yum install corosync pacemaker -y # rpm -ql corosync
// 配置目录: /etc/corosync
// 配置模板: /etc/corosync/corosync .conf.example
// 服务器脚本: /etc/rc .d /init .d /corosync
|
5.安装资源管理器客户端命令接口工具crmsh
从pacemaker 1.1.8开始,crmsh发展成了一个独立项目,叫crmsh。pacemaker默认不提供命令接口工具,需要单独安装crmsh。
1 2 3 | //crmsh 依赖pssh # yum -y install pssh-2.3.1-2.el6.x86_64.rpm # yum -y install crmsh-1.2.6-4.el6.x86_64.rpm |
6.配置主配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | [root@node1 ~] # cd /etc/corosync/ [root@node1 corosync] # cp corosync.conf.example corosync.conf [root@node1 corosync] # vi corosync.conf compatibility: whitetank #表示是否兼容0.8之前的版本 totem { #图腾,定义集群中各节点中通信机制以及参数
version: 2 #图腾的协议版本号,不修改
secauth: on #安全认证功能是否启用,当使用aisexec时,会非常消耗CPU
threads: 0 #实现认证时的并行线程数,0表示默认配置
interface { # 指定在哪个接口发心跳信息,子模块
ringnumber: 0 #冗余环号,节点有多个网卡是可定义,避免心跳信息成环。
bindnetaddr: 192.168.1.0 #绑定心跳网段
mcastaddr: 226.94.8.8 #心跳组播地址
mcastport: 5405 #心跳组播使用端口
ttl: 1 #表示只向外播一次
} } logging { # 跟日志相关
fileline: off #指定要打印的行
to_stderr: no #是否发送到标准错误输出,即屏幕
to_logfile: yes #记录到日志文件
to_syslog: no #记录到系统日志syslog
logfile: /var/log/cluster/corosync .log #日志文件路径
debug: off #是否启动调试
timestamp: on #是否打印时间戳
logger_subsys { #日志的子系统
subsys: AMF
debug: off
} } service {
ver: 0
name: pacemaker #定义corosync启动时同时启动pacemaker
# use_mgmtd: yes }
aisexec { #表示启动ais的功能时,以哪个用户的身份运行
#这个块可不定义,corosync默认就是以root身份运行的
user: root
group: root } amf { # 跟编程接口相关的
mode: disabled }
|
7.生成认证key
用corosync-keygen生成key时,由于要使用/dev/random生成随机数,因此如果新装的系统操作不多,如果没有足够的熵,狂敲键盘即可,随意敲,敲够即可。(关于random使用键盘敲击产生随机数的原理可自行google)
实验演示没有足够的熵,这里将采用投机的方式,生产环境,切切不可。
1 2 3 4 5 6 | // 投机的认证方式 # mv /dev/random /dev/lala # ln /dev/urandom /dev/random //将随机数生成器链接至伪随机数生成器 # corosync-keygen //生成密钥文件,用于节点通信,会生成authkey文件 # rm -rf /dev/random //删除链接 # mv /dev/lala /dev/random //还原随机数生成器 |
8.copy配置给node2
1 | [root@node1 corosync] # scp authkey corosync.conf node2:/etc/corosync/ |
9.启动corosync
1 2 | [root@node1 corosync] # service corosync start [root@node1 corosync] # ssh node2 "service corosync start" |
10.检查启动情况
1 2 3 4 5 6 7 8 | // 查看corosync引擎是否正常启动 [root@node1 corosync] # grep -e "Corosync Cluster Engine" -e "configuration file" /var/log/messages // 查看初始化节点通知是否正常发出 [root@node1 corosync] # grep TOTEM /var/log/messages // 检查启动过程中是否有错误产生 [root@node1 corosync] # grep ERROR: /var/log/messages | grep -v unpack_resources // 查看pacemaker是否正常启动 [root@node1 corosync] # grep pcmk_startup /var/log/messages |
四、安装配置DRBD
1.安装DRBD
node1/node2均安装
1 2 3 4 | // 确定内核版本 # uname -r // 安装与版本对应的内核模块和用户空间管理工具 # yum -y install drbd-8.4.3-33.el6.x86_64.rpm drbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64.rpm |
2.配置DRBD
node1
1 2 3 4 | [root@node1 ~] # vim /etc/drbd.conf //查看主配置文件 # You can find an example in /usr/share/doc/drbd.../drbd.conf.example include "drbd.d/global_common.conf" ; include "drbd.d/*.res" ; |
//修改全局配置文件 # vim /etc/drbd.d/global_common.conf global { //全局配置 usage-count no; #让linbit公司收集目前drbd的使用情况,yes为参加,我们这里不参加设置为no # minor-count dialog-refresh disable-ip-verification } common { handlers { #处理器 # These are EXAMPLE handlers only. # They may have severe implications, # like hard resetting the node under certain circumstances. # Be careful when chosing your poison. pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f"; // 定义了如果主节点降级了怎么处理的 pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f"; //这个定义了如果有脑裂了之后找不到主节点怎么处理的 local-io-error "/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; halt -f"; //定义了一旦本地节点发生IO错误时应该怎么处理 # fence-peer "/usr/lib/drbd/crm-fence-peer.sh"; # split-brain "/usr/lib/drbd/notify-split-brain.sh root"; # out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root"; # before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k"; # after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh; } startup { //定义一个节点启动时另一个节点应该怎么做 # wfc-timeout //等待另一个节点上线的超时时长 # degr-wfc-timeout //等待超时后做降级处理 # outdated-wfc-timeout //过期的等待超时 # wait-after-sb //脑裂之后等待多长时长 } options { # cpu-mask on-no-data-accessible } disk { on-io-error detach; #同步错误的做法是分离 # size max-bio-bvecs on-io-error fencing disk-barrier disk-flushes # disk-drain md-flushes resync-rate resync-after al-extents # c-plan-ahead c-delay-target c-fill-target c-max-rate # c-min-rate disk-timeout } net { protocol C; cram-hmac-alg "sha1"; #设置加密算法sha1 shared-secret "mydrbd"; #设置加密key # protocol timeout max-epoch-size max-buffers unplug-watermark # connect-int ping-int sndbuf-size rcvbuf-size ko-count # allow-two-primaries cram-hmac-alg shared-secret after-sb-0pri # after-sb-1pri after-sb-2pri always-asbp rr-conflict # ping-timeout data-integrity-alg tcp-cork on-congestion # congestion-fill congestion-extents csums-alg verify-alg # use-rle } syncer { # 同步相关的设置 rate 1000M; #设置重新同步(re-synchronization)速度 #re-synchronization时候,如果有大量不一致的数据, #我们不可能将所有带宽都分配给drbd做re- synchronization, #这样会影响对外提提供服务。rate的设置需要考虑IO能力。 #一般来说,设置网络IO能力和磁盘IO能力中最小者的30%的带宽给re- synchronization是比较合适的(官方说明) # drbd还提供了一个临时的rate更改命令,可以临时性的更改syncer的rate 值: #drbdsetup /dev/drbd0 syncer -r 100M #这样就临时的设置为100M。 #结束之后,通过 #drbdadm adjust resource_name 来让drbd按照配置中的rate工作。 } } |
3.为节点准备磁盘分区
node1/node2都需要准备,分好区不需要格式化,系统能识别就行可
1 2 3 | # fdisk /dev/sda //具体不详述 # kpart -af /dev/sda # partx -a /dev/sda //一次识别不出来,可以多重复几次 |
4.定义资源
# cd /etc/drbd.d/ # vim mystore.res resource mystore { #定义一个资源,用关键字resource; on node1.hoo.com { #on说明在哪个节点上,跟uname -n保持一致 device /dev/drbd0; #在磁盘上表现的drbd叫什么名; disk /dev/sda5; #所使用的磁盘设备是哪个; address 172.16.1.11:7789; #监听的套接字,默认监听在7789端口上; meta-disk internal; #内部存放metadata } on node2.hoo.com { device /dev/drbd0; disk /dev/sda5; address 172.16.1.12:7789; meta-disk internal; } }
5.同步配置文件
1 | # scp global_common.conf mystore.res node2:/etc/drbd.d/ |
6.初始化资源
node1/node2均初始化
1 | # drbdadm create-md mystore |
7.启动DRBD服务
node1/node2均启动
1 | # service drbd start |
8.查看启动状态
1 2 3 4 5 | // 以下两种方式均可查看 # cat /proc/drbd 或 # drbd-overview // 初始化后,两个节点均处于Secondary状态 |
9.选择主节点
将node1提升为主节点
1 |
|
观察
1 2 | # drbd-overview
|
10.格式化并挂载
1 2 3 | [root@node1 ~] # mke2fs -t ext4 /dev/drbd0 [root@node1 ~] # mkdir /drbd [root@node1 ~] # mount /dev/drbd0 /drbd |
11.测试
1 2 3 4 5 6 7 8 9 10 11 12 | // 复制文件到DRBD设备 [root@node1 ~] # cd /drbd/ [root@node1 drbd] # cp /etc/inittab /drbd/ // 角色转换,将node1降级 [root@node1 ~] # drbdadm secondary mystore // 将node2提升为主 [root@node2 ~] # drbdadm primary mystore [root@node2 ~] # mkdir /drbd [root@node2 ~] # mount /dev/drbd0 /drbd [root@node2 ~] # cd /drbd [root@node2 ~] # ls
//inittab 文件存在 |
DRBD确定正常工作。
12.将node1的DRBD设置为主节点并挂载,设置MySQL数据目录
//将node2降级 [root@node2 ~]# mount /drbd [root@node2 ~]# drbdadm secondary mystore //将node1提升为主 [root@node1 ~]# drbdadm primary mystore
[root@node1 ~]# drbd-overview 0:web/0 Connected Primary/Secondary UpToDate/UpToDate C r----- [root@node1 ~]# mkdir /mydata [root@node1 ~]# mount /dev/drbd0 /mydata/ [root@node1 ~]# cd /mydata/ [root@node1 mydata]# mkdir data [root@node1 mydata]# chown -R mysql.mysql /mydata/data/
五、MySQL的安装配置
1.安装MySQL
node1/node2均安装
# tar xf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local/ # cd /usr/local/ # ln -sv mysql-5.5.33-linux2.6-x86_64 mysql # chown -R root:mysql /usr/local/mysql/*
2.创建mysql用户mysql组
node1/node2均配置
# groupadd -g 3306 mysql # useradd -u 3306 -g mysql -s /sbin/nologin -M mysql
3.提供配置文件
[root@node1 ~]# cp /usr/local/mysql/support-files/my-large.cnf /etc/my.cnf [root@node1 ~]# vim /etc/my.cnf #增加一行 datadir = /mydata/data
4.初始化MySQL
[root@node1 data]# /usr/local/mysql/scripts/mysql_install_db --datadir=/mydata/data/ --basedir=/usr/local/mysql --user=mysql
5.提供启动脚本
[root@node1 ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld [root@node1 ~]# chmod +x /etc/init.d/mysqld
6.启动并测试MySQL
[root@node1 data]# service mysqld start Starting MySQL..... SUCCESS! [root@node1 data]# /usr/local/mysql/bin/mysql //启动成功
7.将node1上mysql配置文件与启动脚本复制到node2上
[root@node1 ~]# scp /etc/my.cnf node2:/etc/ [root@node1 ~]# scp /etc/init.d/mysqld node2:/etc/init.d/
8.关闭mysql并设置开机不启动
[root@node1 ~]# service mysqld stop [root@node1 data]# chkconfig mysqld off [root@node1 data]# chkconfig mysqld --list
9.node2上启动并测试MySQL
node2设为主节点
[root@node1 ~]# umount /mydata/ [root@node1 ~]# drbdadm secondary web [root@node1 ~]# drbd-overview [root@node2 ~]# drbdadm primary web [root@node2 ~]# drbd-overview [root@node2 ~]# mkdir /mydata [root@node2 ~]# mount /dev/drbd0 /mydata/ [root@node2 ~]# cd /mydata/ [root@node2 mydata]# ll //data目录存在
启动测试MySQL
[root@node2 data]# service mysqld start [root@node2 data]# /usr/local/mysql/bin/mysql //成功
停止mysql,设置开机不启动
[root@node2 ~]# service mysqld stop [root@node2 ~]# chkconfig mysqld off [root@node2 ~]# chkconfig mysqld --list
六、实现高可用
1.关闭drbd并设置开机不启动
node1/node2均设置
1 2 3 | # service drbd stop # chkconfig drbd off # chkconfig drbd --list
|
2.添加brbd资源
[root@node1 ~]# crm crm(live)# configure crm(live)configure# property stonith-enabled=false //禁用stonith crm(live)configure# property no-quorum-policy=ignore //双节点设置忽略 crm(live)configure# verify crm(live)configure# commit crm(live)configure# show crm(live)configure# meta ocf:linbit:drbd //查看drbd的详细信息 crm(live)configure# primitive mysqlstore ocf:linbit:drbd params drbd_resource=mystore op monitor role=Master interval=30s timeout=20s op monitor role=Slave interval=60s timeout=20s op start timeout=240s op stop timeout=100s //定义资源 crm(live)configure# verify crm(live)configure# master ms_mysqlstore mysqlstore meta master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 notify=”True” //定义主资源 crm(live)configure# verify crm(live)configure# commit
2.添加文件系统资源
定义文件系统资源,让服务器切换时自动挂载
crm(live)configure# primitive drbdfs ocf:heartbeat:Filesystem params device=/dev/drbd0 directory=/mydata fstype=ext4 op monitor interval=30s timeout=40s on-fail-restart op start timeout=60 op stop timeout=60 crm(live)configure# verify crm(live)configure# commit //定义排列约束: crm(live)configure# collocation drbdfs_with_ms_mysqlstore_master inf: drbdfs ms_mysqlstore:Master //drbd与文件系统在一起 crm(live)configure# verify //定义顺序约束: crm(live)configure# order drbdfs_after_ms_mysqlstore_master mandatory: ms_mysqlstore:promote drbdfs:start crm(live)configure# show crm(live)configure# commit
验证:
[root@node1 ~]# crm status
3.添加mysql资源
crm(live)# configure crm(live)configure# primitive mysqld lsb:mysqld //定义排列约束 crm(live)configure# colocation mysqld_with_mystore inf: mysqld mystore crm(live)configure# verify crm(live)configure# show crm(live)configure# commit //定义顺序约束 crm(live)configure# order mysqld_after_mystore mandatory: mystore mysqld crm(live)configure# verify crm(live)configure# show crm(live)configure# commit
验证:
[root@node1 ~]# crm status
4.添加vip资源
crm(live)# configure crm(live)configure# primitive vip ocf:heartbeat:IPaddr params ip=192.168.1.100 nic=eth0 cidr_netmask=255.255.255.0 //定义排列约束 crm(live)configure# colocation vip_with_ms_mysqldrbd inf: ms_mysqldrbd:Master vip crm(live)configure# verify crm(live)configure# show crm(live)configure# commit
验证:
[root@node1 ~]# crm status
七、测试使用
1.登录mysql
[root@node1 ~]# /usr/local/mysql/bin/mysql //正常
2.模拟故障
[root@node1 ~]# crm crm(live)# node standby node1.hoo.com crm(live)# show
验证:
[root@node2 ~]# crm status
登录测试:
[root@node2 ~]# /usr/local/mysql/bin/mysql //正常
本文出自 “潇洒哥是先知” 博客,请务必保留此出处http://hoolee.blog.51cto.com/7934938/1413023