1.简介
MySQL+heartbeat+DRBD+LVS是一套成熟的集群解决方案,通过heartbeat+DRBD完成MySQL的主节点写操作的高可用性,而通过MySQL+LVS实现MySQL数据库主从复制和MySQL读操作的负载均衡。整个方案在读写方面进行分离,融合写操作的高可用和读操作的负载均衡,是一个完美又廉价的企业应用解决方案。
mysql高可用性解决方案:
1.mysql的复制功能90.000%
2.mysql的复制功能+集群软件 95.000%
3.mysql+heartbeat+DRBD 99.900%
4.共享存储+mysql的复制功能 99.990%
5.mysql cluster的标准版和电信版 99.999%
2.heartbeat+DRBD高可用性实现原理
DRBD的英文全程为DistributedReplicated Block Device(分布式块设备复制),是Linux内核的存储层的一个分布式存储系统,可利用DRBD在两台Linux服务器之间共享块设备、文件系统和数据,类似于一个网络RAID1的功能。DRBD的架构如图所示。
当将数据写入到本地主节点的文件系统时,这些数据会通过网络发送到另一台主节点上,本地主节点和远程主节点数据通过TCP/IP协议保持同步,主节点故障时,远程节点保存着相同的数据库,可以接替主节点继续提供数据,两个节点之间使用heartbeat来检测对方是否存活。
同步过程如下:
1)在NODE1上写操作被提交时,然后通过内核传给DRBD模块。
2)DRBD发送写操作到NODE2
3)在NODE2上的DRBD发送写操作给本地磁盘。
4)在NODE2上的DRBD向NODE1发确认信息,确认已经收到写操作并发送给本地磁盘。
5)在NODE1上的DRBD发送写操作给本地磁盘。
6)在NODE1的内核回应写操作完成。
此同步过程还依赖于DRBD的3种同步协议:
Protocol A,写I/O到达本地磁盘和本地的TCP发送缓存区之后,返回操作成功。
Protocol B,写I/O到达本地磁盘和远程节点的缓存区之后,返回操作成功。
Protocol C,写I/O到达本地磁盘和远程节点的磁盘之后,返回操作成功。
3.MySQL高可用性集群部署
企业级MySQL集群具备高可用性、可扩展、易管理、低成本的特点,通常采用MySQL读写分离的办法,而读写之间的数据同步采用MySQL的单向或双向复制技术实现。MySQL写操作一般采用heartbeat+DRBD+MySQL搭建高可用集群的方案,而读操作普遍采用keepalived搭建高可用可扩展集群的方案。
3.1集群规划
一个MySQL集群中主机的IP地址信息及用途:
主机名 IP地址 用途
dbm133 172.19.19.133 Heartbeat+DRBD+MySQL的primary节点
dbm134 172.19.19.134 Heartbeat+DRBD+MySQL的secondary节点
dbs135 172.19.19.135 slave(master_host=172.19.19.222)
dbs136 172.19.19.136 slave(master_host=172.19.19.222)
dbs137 172.19.19.137 slave(master_host=172.19.19.222)
LVS1 172.19.19.144 LVS+keepalived
LVS2 172.19.19.145 LVS+keepalived
heartbeat+DRBD方案中的IP信息
heartbeat使用的VIP heartbeat的主备节点
172.19.19.222 172.19.19.133
172.19.19.134
LVS+keepalived上的VIP和realserverIP信息
VIP realserver
172.19.19.223 172.19.19.135
172.19.19.136
172.19.19.137
3.2配置之前的准备
3.2.1设置hostname及解析
首先要给需要配置DRBD的两台主机配置hostname,设置之后通过uname –a检查是否成功,建议不要将hostname设置成全称域名(例如,dbm133.example.com、dbm134.example.com),设置短标识比较好(例如,dbm133、dbm134),因为这个短标识在以后的配置中会用到,较短的标识可以减少后期配置的复杂度,并避免出现问题。同时要求这两台主机的hostname能分别解析到两台机器的内网IP(即两台主机互相通信时使用的网络地址)。
编辑/etc/hosts文件,添加如下内容:
172.19.19.133 dbm133
172.19.19.134 dbm134
3.2.2磁盘分区规划
根据当前DB文件的大小及后期的增长划分出一个分区,用于存放所有可变数据文件,例如。整个MySQL的datadir目录、binlog文件、relaylog文件、my.cnf文件,还包括所有表的ibd文件(单独表空间)、ibdata文件和id_logfile文件。两台主机节点分区最好大小一样,至少要保证secondray节点分区尺寸大雨primary节点分区尺寸,以避免后期因空间不足而出现难以预见的问题。
3.2.3熟悉网络环境
确定利用DRBD进行同步的网络状况是够良好。DRBD同步操作对网络环境要求很高,特别是在写入数据量特别大、需要同步的数据很多时尤为重要。网络环境越好,同步的速度越快。可以考虑把DB对外提供服务的网络和DRBD网络同步分开,这样可以使业务对DB的访问请求和DRBD同步互不影响,但也会带来一些成本的增加。规划两台主机之间的心跳线为两根以上,这样能保证不会因为某一线路故障而产生的切换工作。在高可用性方案中,一般要求用三个以上的心跳线进行心跳检测,以此来减少误切换和“脑裂”问题,同时要确认上层交换机是够禁止ARP广播。
3.3DRBD部署
从官方网站下载源码包来编译或者直接使用yum来安装。
通过yum来安装
[root@dbm133 ~] yum install kmod-drbd84drbd84
检查是否安装成功
[root@dbm133 ~] modprode –l|grep -i drbd
[root@dbm133 ~] lsmod |grep –I drbd
安装完成之后,在/sbin目录下有drbdadm、drdbmeta、drbdsetup命令,以及/etc/init.d/drbd启动脚本。
3.3.1DRBD配置
3.3.1.1DRBD使用的磁盘分区
使用尺寸相同的单独分区,同时考虑DB的大小和未来的增长量,也可以使用LVM进行分区。只有保证两台机器型号或性能一样,才能保证在切换到secondary节点能完成原来primary节点承担的业务负载。这里分配大小为145GB的/data分区给数据库使用,两台机器完全一样。
dbm133
[root@dbm133 ~]df –h |grep data
dbm134
[root@dbm133 ~]df –h |grep data
3.3.1.2drbd.conf配置文件
DRBD运行需要读取/etc/drbd.conf配置文件,可以通过如下命令重建这个配置文件,该文件中描述了DRBD设备与硬盘分区的映射关系和DRBD的一些配置参数。
cp /usr/share/doc/drbd83-8.3.8/drbd.conf/etc/drbd.conf
两台主机节点的相关信息如表所示。
节点角色 主机名 IP地址 DRBD分区
primary节点 dbm133 172.19.19.133 /dev/sda3
secondary节点 dbm134 172.19.19.134 /dev/sda3
修改配置文件/etc/drbd.conf
---------------------------------------------------------------------------------------------------------------------------------
global {
minor-count 64;
usage-count yes;
#minor-count dialog-refresh disable-ip-verification
}
common {
syncer { rate 1000M; }
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";
fence-peer "/usr/lib/drbd/crm-fence-peer.sh";
pri-lost "/usr/local/drbd/lib/drbd/notify-pri-lost.sh;/usr/local/drbd/lib/drbd/notify-emergency-reboot.sh; echo b>/proc/sysrq-trigger ; reboot -f";
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
wfc-timeout 60;
degr-wfc-timeout 120;
outdated-wfc-timeout 2;
}
options {
# cpu-mask on-no-data-accessible
}
disk {
# size max-bio-bvecs on-io-error fencingdisk-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
on-io-error detach;
fencing resource-only;
}
net {
# 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
protocol C;
}
}
resource r0 {
on dbm133 {
device /dev/drbd0;
disk /dev/sda3;
address 172.19.19.133:7788;
meta-disk internal;
}
on dbm134 {
device /dev/drbd0;
disk /dev/sda3;
address 172.19.19.134:7788;
meta-disk internal;
}
}
---------------------------------------------------------------------------------------------------------------------------------
将上面的drbd.conf文件分别复制到两台主机的/etc目录下。drbd.conf的配置参数很多,有兴趣可以使用man drbd.conf来了解更多的参数说明。
3.3.1.3DRBD的启动
启动DRBD服务器之前,首先分别在两台主机的/dev/sda3分区上创建DRBD元数据库信息。执行的命令如下:
[root@dbm133 ~]# drbdadm create-md all
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfullycreated.
[root@dbm134 ~]# drbdadm create-md all
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfullycreated.
这里也可以用drbdadm create-md r0代替dedbadm create-md all。r0是在drbd.conf中定义的资源名称。现在我们可以启动DRBD了,分别在两台主机上执行启动操作。这一步操作有可能出现创建不成功的情况。
[root@dbm133 ~]# drbdadm create-md all
md_offset 268431319040
al_offset 268431286272
bm_offset 268423094272
Found ext3 filesystem
262139964 kB data area apparently used
262131928 kB left usable by current configuration
Device size would be truncated, which
would corrupt data and result in
'access beyond end of device' errors.
You need to either
*use external meta data (recommended)
*shrink that filesystem first
*zero out the device (destroy the filesystem)
Operation refused.
Command 'drbdmeta 0 v08 /dev/sda3 internalcreate-md' terminated with exit code 40
这时需要使用如下命令覆盖文件系统中的设备块信息,操作时确认此分区上的数据已经备份过。
dd if=/dev/zero of=/dev/sda3 bs=1Mcount=128
执行完“dd”命令后,再次执行“debdadm create-md all”命令。
启动DRBD服务,设置主节点后,格式化主节点的DRBD分区。
[root@dbm133 ~]# /etc/init.d/drbd start
Starting DRBD resources:
--== Thank you for participatingin the global usage survey ==--
the server's response is:
[
adjust disk: r0
adjust net: r0
]
degr-wfc-timeout has to be shorter thanwfc-timeout
degr-wfc-timeout implicitly set towfc-timeout (60s)
..........
***************************************************************
DRBD's startup script waits for the peernode(s) to appear.
- Ifthis node was already a degraded cluster before the
reboot, the timeout is 120 seconds. [degr-wfc-timeout]
- Ifthe peer was available before the reboot, the timeout
is60 seconds. [wfc-timeout]
(These values are for resource 'r0'; 0 sec -> wait forever)
Toabort waiting enter 'yes' [ -- ]: [ 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]:[ 44]:[ 45]:[ 46]:[ 47]:[ 48]:[ 49]:[ 50]:[ 51]:[ 52]:[ 53]:[ 54]:[ 55]:[ 56]:[ 57]:[ 58]:[ 59]:
.
WARN: nothing stacked for this host(dbm133), nothing to do in stacked mode!
[root@dbm134 ~]# /etc/init.d/drbd start
Starting DRBD resources:
--== Thank you for participatingin the global usage survey ==--
The server's response is:
[
adjust disk: r0
adjust net: r0
]
degr-wfc-timeout has to be shorter thanwfc-timeout
degr-wfc-timeout implicitly set towfc-timeout (60s)
.
WARN: nothing stacked for this host(dbm134), nothing to do in stacked mode!
查看drbd:
[root@dbm133 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash:833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R6, 2015-04-0914:35:00
0:cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r---b-
ns:0 nr:0 dw:0dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:262131928
[root@dbm134 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash:833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R6, 2015-04-0914:35:00
0:cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r---b-
ns:0 nr:0 dw:0dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:262131928
设置主节点:
[root@dbm133 ~]# drbdadm ----overwrite-data-of-peer primary r0
查看状态:
[root@dbm133 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash:833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R6, 2015-04-0914:35:00
0:cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r---a-
ns:118724 nr:0 dw:0 dr:120480 al:0 bm:0 lo:0 pe:10 ua:2 ap:0 ep:1 wo:foos:262023384
[>....................] sync'ed: 0.1% (255880/255988)M
finish: 60:39:12 speed: 1,196 (968) K/sec
[root@dbm134 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash:833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R6, 2015-04-0914:35:00
0:cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r---b-
ns:0 nr:514048 dw:505856 dr:0 al:0 bm:0 lo:8 pe:0 ua:8 ap:0 ep:1 wo:foos:261626072
[>....................] sync'ed: 0.2% (255492/255988)M
finish: 59:57:21 speed: 1,208 (984) want:102,400 K/sec
从输出状态可知,主、备状态分别是Primiary和Secondary,主机磁盘状态是UpToDate,备机磁盘状态是Inconsistent。从加粗代码性可以看到,数据正在同步中,即主机正在将磁盘上的数据传到备用机上。现在同步的速率是100Mbit/s,进度为0.2%。
同步完成之后,再次查看DRBD状态,显示信息如下:
主节点:
[root@dbm133 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash:833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R6, 2015-04-0914:35:00
0:cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r-----
ns:211850456 nr:0 dw:0 dr:211850456 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1wo:f oos:0
备节点:
[root@dbm134 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70build by phil@Build64R6, 2015-04-09 14:35:00
0:cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r-----
ns:0nr:211850456 dw:211850456 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
从输出信息可知,磁盘状态都是”UpToDate“,表示数据同步完成了。
输出中的一些参数的含义如下:
ro 是角色信息,Primary/Secondary说明了当前主机是Primary节点,另一台是Secondary节点。
ds是磁盘状态,显示数据是否一致(如果显示UpToDate/UpToDate表示同步没有延时)。
ns是网络发送的数据包,以K字节计算。
dw是磁盘写操作。
dr是磁盘读操作。
3.3.2DRBD的维护和管理
挂载DRBD分区之前,首先要确认当前主机的DRBD分区是primary状态,可以从”cat/proc/drbd”命令中查询节点状态。例如:
其中“ro:Primary/Sencondary”表示dbm133主机处于Primary状态,可以执行挂载操作。如果显示”ro:Secondary/Primary“,则说明当前主机为Secondary状态,处于这个状态的主机不能对DRBD设备进行挂载操作。
如果当前是Secondary状态,额可以通过命令”drdbadm primary all”把当前主机更改为Primary状态。Drdbamin命令是DRBD的管理命令,它的很多参数可以用来管理DRBD同步或停止、网络断开或者连接等各种状态的转化。
3.3.2.1格式化文件系统
只需要在主节点执行即可
[root@dbm133 etc]# mkfs.ext4 /dev/drbd0
3.3.2.2挂载DRBP磁盘分区到/data
挂载DRBD分区到/data目录
[root@dbm133 ~]#mount /dev/drbd0 /data
[root@dbm133 ~]# df –h | grep data
3.3.2.3DRBD设备角色切换
DRBD设备在进行角色切换操作前,需要现在主节点执行umount命令,去掉对DRBD设备的挂载,然后在另一台主机上把DRBD角色改为Primary,最后再执行挂载。操作如下:
主节点:
[root@dbm133 ~]#df –h | grep data
[root@dbm133 ~]#umount /data
[root@dbm133 ~]#drbdadm secondary all
从节点:
[root@dbm134 ~]# drbdadm primary all
[root@dbm134 ~]# mount /dev/drbd0 /data
还有一种切换策略
主节点:
[root@dbm133 ~]# /etc/init.d/drbd stop
从节点:
[root@dbm134 ~]# drbdadm ----overwrite-data-of-peer primary all
[root@dbm134 ~]# mount /dev/drbd0 /data
3.3.3DRBD性能优化
3.3.3.1网络环境
使用千兆网卡的不要使用百兆网卡。当前主流机器都是使用千兆网卡,交换机也不例外。同时,DRBD的数据同步使用的网络最后和提供服务的网卡分开,尽量独立出来。例如两块网卡上直接连接一个网线,用作DRBD的数据同步。
3.3.3.2做DRBD分区的磁盘性能
用作DRBD分区的磁盘性能要尽量好,例如可以考虑用不少于6块的SAS盘作为RAID10或者RAID0(最后用BBU),以提供I/O性能。在网络环境很好的情况下,DRBD分区可能会由于I/O的写性能而成为瓶颈。
3.3.3.3更新系统
尽量把系统更新成最新的内核以及64位的系统,同时使用最新版本的DRBD。
3.3.3.4注意syncer参数设置
syncer主要用来设置同步相关参数。可以设置“重新”同步(re-syncronization)的速率(rate),当节点间出现不一致的block时,DRBD就需要执行re-synchronization动作,而syncer中的参数rate就是用来设置同步的速率的,rate的设置与网络和磁盘的I/O能力密切相关。
千兆网络的同步速率大约是125Mbit/s,百兆网络的同步速率大约是11Mbit/s,用这个同步速率和磁盘写入速率中最小者的30%带库来这是re-synchronization是白酒合适的,这也是官方给出的建议。
例如,同步速率为125Mbit/s,磁盘写入速度为110Mbit/s,应该设置rate为不能超过33Mbit/s。这样设置的原因是:DRBD同步由两个不同的进程来负责:一个replication进程用来同步block的更新,这个值受限于参数设置:一个synchronization进程用来同步元数据信息,这个值不受参数设置限制。如果写入量非常大,设置的参数超过磁盘的写入速率,元数据的同步速率就会受干扰,传输速度变慢,导致机器负载非常高,性能下降的非常厉害,所以这个值应该根据实际环境来进行设置,如果设置的太大,就会把所有的带宽占满了,导致replication进程没有可用带宽,最终可能导致I/O停止。出现同步不正常的情况。
3.3.3.5注意al-extents参数设置
al-extents控制着一次向磁盘写入多少个4MB的数据块。增大这个参数有以下的几个好处:
可以减少更新元数据到DRBD设备的频率
降低同步数据时对I/O流的中断数量。
提高修改DRBD设备的速度。
但同时也存在一个风险:当主节点出现宕机时,所有活动的数据(al-extends的值x 4M的数据块)需要在同步连接建立后重新同步,即主节点出现宕机时,备用节点出现数据不一致的情况。因此不建议在HA部署上调整这个参数,可以在某些情况下调整这个参数来提高性能。
3.4heartbeat部署
Heartbeat源码安装
3.4.1安装依赖包
[root@dbm133 ~]# yum install gcc gcc-c++autoconf automake libtool glib2-devel libxml2-devel bzip2-devel e2fsprogs-devellibxslt-devel libtool-ltdl-devel make wget docbook-dtds docbook-style-xsl
3.4.2添加用户
添加 Haclient 组和 Hacluster 账户。这个用户主要用来配置respawn的。
[root@dbm133 ~]# groupadd haclient
[root@dbm133 ~]# useradd -g haclienthacluster -M -s /sbin/nologin
3.4.3安装libaio
cluster-glue依赖的库。libaio是Linux下的一个异步非阻塞接口,它提供了以异步非阻塞方式来读写文件的方式,读写效率比较高。
[root@dbm133 ~]# yum install libaio-devel
3.4.4安装cluster-glue
glue(胶水的意思)是用来粘合Heartbeat、Pacemake以及Resource Agent的一系列类库、工具的集合。
[root@dbm133 ~]# wgethttp://hg.linux-ha.org/glue/archive/glue-1.0.9.tar.bz2
[root@dbm133 ~]# tar jxvfglue-1.0.9.tar.bz2
[root@dbm133 ~]# cdReusable-Cluster-Components-glue--glue-1.0.9/
[root@dbm133 ~]# ./autogen.sh
[root@dbm133 ~]# ./configure--prefix=/usr/local/heartbeat --sysconfdir=/etc/heartbeatlibdir=/usr/local/heartbeat/lib64 LIBS='/lib64/libuuid.so.1'
[root@dbm133 ~]# make && makeinstall l
3.4.5安装ResourceAgents
resource-agents为集群资源的访问提供了一系列标准的接口。
[root@dbm133 ~]# wgethttps://codeload.github.com/ClusterLabs/resource-agents/zip/v3.9.2
[root@dbm133 ~]# unzip v3.9.2
[root@dbm133 ~]# cd resource-agents-3.9.2/
[root@dbm133 ~]# ./autogen.sh
[root@dbm133 ~]# ./configure--prefix=/usr/local/heartbeat --sysconfdir=/etc/heartbeatlibdir=/usr/local/heartbeat/lib64 CFLAGS=-I/usr/local/heartbeat/includeLDFLAGS=-L/usr/local/heartbeat/lib64 LIBS='/lib64/libuuid.so.1'
//建立一个软连接,避免编译时找不到所需要的包
[root@dbm133 ~]# ln -s /usr/local/heartbeat/lib64/*/lib64/
[root@dbm133 ~]# make && makeinstall
注意:LDFLAGS的空格,否则configure时不会报错但make时报错。
3.4.6安装Heartbeat
[root@dbm133 ~]#wget
http://hg.linux-ha.org/heartbeat-STABLE_3_0/archive/7e3a82377fa8.tar.bz2
[root@dbm133 ~]# tar jxvf 7e3a82377fa8.tar.bz2
[root@dbm133 ~]# cdHeartbeat-3-0-7e3a82377fa8/
[root@dbm133 ~]# ./bootstrap
[root@dbm133 ~]# ./configure--prefix=/usr/local/heartbeat --sysconfdir=/etc/heartbeatCFLAGS=-I/usr/local/heartbeat/include LDFLAGS=-L/usr/local/heartbeat/lib64 LIBS='/lib64/libuuid.so.1'
[root@dbm133 ~]#vi /usr/local/heartbeat/include/heartbeat/glue_config.h
// 删除glue_config.h 最后一行定义的配置文件路径,避免编译时产生的路径重复定义错误,Shift+g 跳到末行,dd删除
[root@dbm133 ~]# make && makeinstall
make 报错
/usr/local/heartbeat/include/heartbeat/glue_config.h:105:1:error: "HA_HBCONF_DIR" redefined
解决:vim /usr/local/heartbeat/include/heartbeat/glue_config.h
// 删除 glue_config.h 最后一行定义的配置文件路径,避免编译时产生的路径重复定义错误,Shift+g 跳到末行,dd删除
报错:
ucast.c: In function ‘HB_make_send_sock’:
ucast.c:468: error: conflicting types for‘i’
ucast.c:465: note: previous declaration of‘i’ was here
ucast.c:502: error: request for member‘ifr_ifrn’ in something not a structure or union
ucast.c:508: error: request for member‘ifr_ifrn’ in something not a structure or union
ucast.c:513: error: request for member‘ifr_ifrn’ in something not a structure or union
解决:vim lib/plugins/HBcomm/ucast.c +468
这个文件有问题,删除468行int i = 1;就能继续make了
3.4.7复制配置文件
cp /usr/local/heartbeat/share/doc/heartbeat/authkeys/etc/heartbeat/ha.d/
cp/usr/local/heartbeat/share/doc/heartbeat/haresources /etc/heartbeat/ha.d/
cp/usr/local/heartbeat/share/doc/heartbeat/ha.cf /etc/heartbeat/ha.d/
chkconfig --add heartbeat
chkconfig heartbeat on
3.4.8配置
chmod 600 /etc/heartbeat/ha.d/authkeys
修改/etc/heartbeat/ha.d/ha.cf
debugfile /var/log/ha-debug # 打开错误日志报告
keepalive 1 # 1秒检测一次心跳线连接
deadtime 15 # 15秒测试不到 主节点心跳线就认为有问题
warntime 5 # 警告时间(建议在2-10之间)
initdead 30 # 初始化启动时 30秒无连接视为正常,或指定heartbeat在启动时,
#另一台主机节点eth1的IP地址,通过两个不同网络来保证心跳的可用性,也可以加上串口的检测
或者在机器之间连线
udpport 694 # 用udp的694端口连接
ucast eth1 172.19.19.133 # 单播方式连接(主、从都是写对方的IP连接
#当primary节点切换到secondary节点之后,primary节点恢复正常,不进行切回操作,因为切换一次
#MySQL master的成本很高
auto_failback off
#定义两个节点的主机名,一行写一个
node dbm133 # 声明主节点(uname-n)
node dbm134 # 声明次节点(uname-n)
respawn hacluster/usr/local/heartbeat/lib64/heartbeat/ipfail #监控ipfail进程是否挂掉,否则重启它
#开启dopd功能
respawn hacluster /usr/local/heartbeat/lib64/heartbeat/dopd
apiauth ipfail gid=haclient uid=hacluster
apiauth dop gid=haclient uid=hacluster
修改/etc/heartbeat/ha.d/authkeys
auth 1
1 shal HA_JACKBILLON #使用shal验证;密码:HA_JACKBILLON
修改/etc/heartbeat/ha.d/haresource
dbm133 IPaddr::172.19.19.222/24/eth1
3.4.9heartbeat测试
3.4.9.1启动heartbeat
dbm133,dbm134上都启动heartbeat
[root@dbm133 ~]# service heartbeat start
[root@dbm134 ~]# service heartbeat start
[root@dbm133 ~]# ip a
[root@dbm134 ~]# ip a
观察vip172.19.19.222是否绑定到主节点dbm133上
3.4.9.2停止主节点heartbeat,观察vip
[root@dbm133 ~]# service heartbeat stop
[root@dbm133 ~]# ip a
[root@dbm134 ~]# ip a
观察vip172.19.19.222是否漂移到备节点dbm134上
3.4.9.3停止备节点heartbeat,观察vip
[root@dbm133 ~]# ip a
[root@dbm134 ~]# ip a
观察vip172.19.19.222是否回切,在本例中配置不回切,修改ha.cf 中auto_failback on,开启自动回切,因为切换master的成本比较高,视具体情况而定。
3.5MySQL部署
3.5.1MySQL安装
安装mysql有多种方法,这里仅利用rpm安装MySQL为例进行说明。
安装约定,mysql软件采用默认路径,数据文件、配置文件存在/data/mysql下
[root@dbm133 ~]# rpm -ivhMySQL-server-advanced-5.6.18-1.el6.x86_64.rpm
[root@dbm133 ~]# rpm -ivhMySQL-client-advanced-5.6.18-1.el6.x86_64.rpm
[root@dbm133 ~]# rpm -ivhMySQL-devel-advanced-5.6.18-1.el6.x86_64.rpm
[root@dbm133 ~]# cp –r /var/lib64/mysql/data/mysql
[root@dbm133 ~]# cp –r /usr/my.cnf/data/mysql/
[root@dbm133 ~]# chown -R mysql:mysql/data/mysql
[root@dbm133 ~]# chkconfig mysql off
修改my.cnf位置
vi /etc/init.d/mysql +214
conf=/data/mysql/my.cnf
修改配置文件/data/my.cnf,设置数据库文件路径
datadir=/data/mysql
3.5.2heartbeat+DRBD+MySQL配置
Heartbeat+DRBD+MySQL配置主节点的高可用性,即master-master-slave
3.5.2.1拷贝数据库
dbm133上:
[root@dbm133 ~]# service mysql stop
[root@dbm133 ~]# cd /data/
[root@dbm133 ~]# tar –zcvf mysql.tar.gzmysql
[root@dbm133 ~]# scp –r mysq.tar.gz root@172.19.19.134:/data/
dbm134上:
[root@dbm134 ~]# cd /data/
[root@dbm134 ~]# tar –zxvf mysq.tar.gz
[root@dbm133 ~]#
3.5.2.2配置heartbeat
[root@dbm133 ~]# vi/etc/heartbeat/ha.d/haresource
dbm133 IPaddr::172.19.19.222/24/eth1drbddisk::r0 Filesystem::/dev/drbd0::/data mysql
172.19.19.222是vip,在两台主机之间漂移
drbddisk是一个管理DRBD的脚本,heartbeat默认提供这个脚本文件,
可以在/etc/heartbeat/ha.d/resource.d目录下找到。R0是一个启动资源,在drbd配置文件中定义,通过“drbddisk::r0”可以切换drbd主机为primary节点或secondary节点,只有状态为primary的主机才能挂载DRBD分区。Drbddisk主机为primary节点或者secondary节点,只有状态为primary的主机才能挂载DRBD分区。drbddisk脚本相当于执行”drdbadm primary r0”或“drbdadm secondary r0”操作,表示把DRBD资源的角色进行变更。
Filesystem::/dev/drbd0::/data表示把/dev/drbd0设备挂载到/data分区下。
mysql表示启动mysql,应该在系统启动中关闭mysql开机自启动,统一通过heartbeat配置。
在heartbeat资源脚本目录中创建mysql启动脚本的软连接
在dbm133,dbm134上都执行
[root@dbm133 ~]# ln -s /etc/init.d/mysql/etc/heartbeat/ha.d/resource.d/mysql
[root@dbm134 ~]# ln -s /etc/init.d/mysql/etc/heartbeat/ha.d/resource.d/mysql
3.5.2.3测试资源切换
停掉主节点上的heartbeat模拟主节点宕机
[root@dbm133 ~]# service heartbeat stop
[root@dbm133 ~]# tail –f /var/log/ha-debug
[root@dbm134 ~]# tail –f /var/log/ha-debug
查看日志,备节点上是否启动资源 drbd和mysql
如果配置heartbeat自动回切,重新启动主节点heartbeat,看备节点的资源是否重新切回到主节点。
在主节点上启动heartbeat,创建数据库
[root@dbm133 ~]# mysql –u root –p
mysql>create database mydb character setutf8;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.03 sec)mysql>exit;
停止主节点heartbeat
[root@dbm133 ~]#service heartbeat stop
[root@dbm134 ~]#mysql –u root –p
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.03 sec)
可以看到在备节点上有新建的数据库mydb
3.5.2.4特别说明
Heartbeat+DRBD+MySQL,配置heartbeat可以虚拟出一个虚拟IP,在主节点和备用节点上跳转,对外提供服务,DRBD提供数据文件的拷贝。
3.5.3MySQL主从复制的配置
MySQL的复制(replication)是异步复制,即从一个MySQL实例或者端口(称之为Master)复制到另一个MySQL实例或者端口(称之为Slave)。复制操作由三个进程完成,其中两个进程(SQL进程和I/O进程)在Salve上,另外一个进程在Master(binlog dump)上。
要实现复制,必须打开Master端的二进制日志(log-bin)功能。这是因为整个复制过程实际上就是Slave从Master端获取该更新操作的日志,将其传输到本地并写到本地文件中,然后再读取本地文件内容执行日志中的锁记录的更新操作,如图所示。
主从复制,可以实现mysql的读写分离,写操作在master节点,读操作在slave节点
3.5.3.1在master上建立同步用户
每个同步服务器都必须设定一个唯一的编号,修改my.cnf,增加或修改如下两行:
server-id = 1 #相同端口必须唯一
log-bin #开启记录二进制日志功能
在Master(这里为dbm157机器)上增加一个用户复制的帐号:
mysql>GRANT REPLICATION SLAVE ON *.* TO ‘repl_user’@’slave_ip’IDENTIFIEDBY ‘repl_password’;
在本例中:
mysql> GRANT REPLICATION SLAVE ON *.* TO ' repl_user’'@'172.19.19.*' identified BY ' repl_password ';
mysql>FLUSH TABLES WITH READ LOCK;
mysql>reset master;
不要退出终端,否则这个锁就失效了。在不退出终端的情况,再开启一个终端直接打包压缩数据文件或者使用mysqldump工具来导出数据。
[root@dbm133 ~]# cd /var/lib
[root@dbm133 ~]# tar –zcvf mysql.tar.gzmysql
[root@dbm133 ~]#scp –r mysql.tar.gz root@172.19.19.134:/var/lib
用scp命令把打包的数据传输到其他几台Slave机器上。
数据传输完成后,在执行FLUSH TABLES WITH READ LOCK命令的终端上执行如下命令:
mysql>UNLOCK TABLES;
注意修改/data/mysql/auto.cnf,因为是从主机上直接拷贝的,修改为不一致即可。
3.5.3.2设置slave主机
修改my.cnf的server-id,如下:
server-id = 2
其他slave上依此类推,保证server-id全局唯一。
3.5.3.3开启master和slave同步
在Slave上执行如下命令;
mysql>CHANGE MASTER TO MASTER_HOST='172.19.19.133',
MASTER_USER='repl_user',
MASTER_PASSWORD='repl_password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=0;
查看slave状态
mysql> show slave status\G;
*************************** 1. row***************************
Slave_IO_State:
Master_Host: 172.19.19.133
Master_User: repl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 4
Relay_Log_File: mysql-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: No
Slave_SQL_Running: No
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: 4
Relay_Log_Space: 120
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: NULL
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: 0
Master_UUID:
Master_Info_File: /data/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
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
1 row in set (0.00 sec)
表明slave还没有开始复制过程。日志的位置为4而不是0,这是因为0只是日志文件的开始位置,并不是日志位置。实际上,MySQL知道的第一个事件的位置是4。
mysql> start slave;
再次查看slave状态
mysql> show slave status\G;
*************************** 1. row***************************
Slave_IO_State: Waiting formaster to send event
Master_Host: 172.19.19.133
Master_User: repl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 120
Relay_Log_File:mysql-relay-bin.000003
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000001
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: 120
Relay_Log_Space: 456
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: 1
Master_UUID:678b3daa-7150-11e5-b06d-005056973e24
Master_Info_File: /data/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for theslave 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
1 row in set (0.00 sec)
Slave_IO_Running和Slave_SQL_Running:都为Yes,表示slave的I/O和SQL线程都已经开始运行,而且Seconds_Behind_Master不再是NULL。日志的位置增加了,意味着一些事件被获取并执行了。如果你在master上进行修改,你可以在slave上看到各种日志文件的位置的变化,同样,你也可以看到数据库中数据的变化。
可查看master和slave上线程的状态。在master上,你可以看到slave的I/O线程创建的连接:
在master上输入showprocesslist\G;
mysql> show processlist\G;
*************************** 1. row***************************
Id: 5
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: init
Info: show processlist
*************************** 2. row***************************
Id: 7
User: repl_user
Host: dbm134:57784
db: NULL
Command: Binlog Dump
Time: 459
State: Master has sent all binlog to slave; waiting for binlog to beupdated
Info: NULL
2 rows in set (0.00 sec)
在slave服务器上运行该语句:
mysql> show processlist\G;
*************************** 1. row***************************
Id: 1
User: system user
Host:
db: NULL
Command: Connect
Time: 548
State: Waiting for master to send event
Info: NULL
*************************** 2. row***************************
Id: 2
User: system user
Host:
db: NULL
Command: Connect
Time: 547
State: Slave has read all relay log; waiting for the slave I/O thread toupdate it
Info: NULL
*************************** 3. row***************************
Id: 3
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: init
Info: show processlist
3 rows in set (0.00 sec)
3.5.3.4添加新的slave节点
假如master已经运行很久了,想对新安装的slave进行数据同步,甚至它没有master的数据。
此时,有几种方法可以使slave从另一个服务开始,例如,从master拷贝数据,从另一个slave克隆,从最近的备份开始一个slave。Slave与master同步时,需要三样东西:
(1)master的某个时刻的数据快照;
(2)master当前的日志文件、以及生成快照时的字节偏移。这两个值可以叫做日志文件坐标(log filecoordinate),因为它们确定了一个二进制日志的位置,你可以用SHOW MASTER STATUS命令找到日志文件的坐标;
(3)master的二进制日志文件。
可以通过以下几中方法来克隆一个slave:
(1) 冷拷贝(coldcopy)
停止master,将master的文件拷贝到slave;然后重启master。缺点很明显。
(2) 热拷贝(warmcopy)
如果你仅使用MyISAM表,你可以使用mysqlhotcopy拷贝,即使服务器正在运行。
(3) 使用mysqldump
使用mysqldump来得到一个数据快照可分为以下几步:
<1>锁表:如果你还没有锁表,你应该对表加锁,防止其它连接修改数据库,否则,你得到的数据可以是不一致的。如下:
mysql> FLUSH TABLES WITH READ LOCK;
<2>在另一个连接用mysqldump创建一个你想进行复制的数据库的转储:
shell> mysqldump --all-databases --lock-all-tables>dbdump.db
<3>对表释放锁。
mysql> UNLOCK TABLES;
3.5.4需要注意的问题
如果在my.cnf中定义了log-bin、relay-log参数,那么要保证这些定义与主机名无关,因为uruguo这两类log的文件名与主机名有关,切换过程中会导致Slave主机不能继续同步,例如可以如下设置:
log-bin= mysql-bin
relay-bin= mysql-relay-bin
保证在两台主机上两个文件的名字一样。
2)最好把my.cnf文件也放入DRBD分区的数据目录中,这样进行配置变更时,另一台也保持同步,避免由于修改文件导致切换后的配置不一样。要把my.cnf文件放入DRBD分区的数据目录中,需要修改/etc/init.d/mysql启动脚本中的my.cnf文件的路径。
3)如果不是通过rpm安装MySQL,要保证MySQL启动脚本能接收start、top、startus三个参数。默认heartbeat采用LSB(LinuxStandard Base)风格,返回值包含OK或running则表示资源正常,返回值包含stopped或No则表示资源不正常。其他资源脚本的情况类似。
4)不要设置mysql在机器重启动时自动启动,mysql服务作为heartbeat的一项资源会统一管理。
3.6.搭建slave集群
3.6.1slave集群
Heartbeat+DRBD解决了MySQL的master的高可用性问题,在master出现故障时能达到快速切换,slave也可以用这种方案来实现高可用性,但是这样部署的成本会比较高。在读操作多而写操作比较少的互联网应用中,一台机器很难承受不断增长的读操作,此时,就需要进行读写分离,一台master承担写操作,多台slave提供读操作。如果仍采用heartbeat+DRBD来实现slave的高可用性,搭建成本讲无法承受,在大多数公司中,都是一组5x8的工作人员来维护着一个365x7x24的在线业务,要求一台slave出现故障不会影响业务的正常运行,同时可以不及时处理故障。这就要求slave也具有比较高的可用性,也就是说,当一台slave出现故障时,可以自动关闭对外提供服务,这个过程不需要认为干预。
LVS+keepalived能很好地实现上述功能,他可以完成负载均衡功能,同事通过自定义检测脚本,保证在一台slave出现故障时,自动从LVS的realserver列表中剔除故障节点,不在对外提供服务,保证了slave的高可用性,同时成本也很低。
当前很多公司使用DNS解析的轮询去实现多台slave的负载均衡,这种方式存在两个问题:第一,不能实现很好的负载均衡:第二,需要第三方监控来更新DNS以实现slave的故障切换,因为更新解析的TTL问题不能达到很高的可用性。
下面详细介绍LVS+keepalived的配置过程。
3.6.2LVS+keepalived
3.6.2.1安装keepalived
yum安装:
[root@dbm144 ~]# yum install -y keepalived
[root@dbm145 ~]# yum install -y keepalived
源码安装:
cd /usr/local/
tar zxvfkeepalived-1.2.12.tar.gz
cd keepalived-1.2.12
./configure --prefix=/usr/local/keepalived
make
make install
cp/usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
cp/usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp/usr/local/keepalived/sbin/keepalived /usr/sbin/
mkdir -p /etc/keepalived/
cp/usr/local/keepalived/etc/keepalived/keepalived.conf/etc/keepalived/keepalived.conf
chkconfig --add keepalived
chkconfig --level 123456 keepalived on
service keepalivedstart|stop
3.6.2.2配置keepalived
Master
---------------------------------------------------------------------------------------------------------------------------------
! Configuration File forkeepalived
global_defs {
notification_email {
acassen@firewall.loc #设置报警邮件地址,可以设置多个,每行1个
failover@firewall.loc #需开启邮件报警及本机的Sendmail服务。
sysadmin@firewall.loc
}
notification_email_fromAlexandre.Cassen@firewall.loc
smtp_server 127.0.0.1 #设置SMTPServer地址;
smtp_connect_timeout 30
router_id LVS_DEVEL
}
########VRRPInstance########
vrrp_instance VI_1 {
state MASTER #指定Keepalived的角色,MASTER为主机服务器,BACKUP为备用服务器
interface eth1 #BACKUP为备用服务器
virtual_router_id 51
priority 100 #定义优先级,数字越大,优先级越高,主机器必须大于备机。
advert_int 1
authentication {
auth_type PASS #设置验证类型,主要有PASS和AH两种
auth_pass 1111 #设置验证密码
}
virtual_ipaddress {
172.19.19.223 #设置主DR的虚拟IP地址(virtualIP),可多设,但必须每行1个
}
}
########VirtualServer########
virtual_server172.19.19.223 3306 { #注意IP地址与端口号之间用空格隔开
delay_loop 6 #设置健康检查时间,单位是秒
lb_algo lc #设置负载调度算法,默认为rr,即轮询算法,最优秀是wlc算法,这里使用的是最小链接算法
lb_kind DR #设置LVS实现LB机制,有NAT、TUNN和DR三个模式可选
#nat_mask 255.255.255.0
#persistence_timeout 50 #会话保持时间,单位为秒
protocol TCP #指定转发协议类型,有TCP和UDP两种
real_server 172.19.19.135 3306 {
weight 1 #配置节点权值,数字越大权值越高
TCP_CHECK {
connect_timeout 3 #表示3秒无响应,则超时
nb_get_retry 3 #表示重试次数
delay_before_retry 3 #表示重试间隔
}
}
real_server 172.19.19.136 3306 { #配置服务器节点,即RealServer2的public IP
weight 3 #配置节点权值,数字越大权值越高
TCP_CHECK {
connect_timeout 3 #表示3秒无响应,则超时
nb_get_retry 3 #表示重试次数
delay_before_retry 3 #表示重试间隔
}
}
real_server 172.19.19.137 3306 { #配置服务器节点,即RealServer2的public IP
weight 3 #配置节点权值,数字越大权值越高
TCP_CHECK {
connect_timeout 3 #表示3秒无响应,则超时
nb_get_retry 3 #表示重试次数
delay_before_retry 3 #表示重试间隔
}
}
}
---------------------------------------------------------------------------------------------------------------------------
Slave
! Configuration File forkeepalived
global_defs {
notification_email {
acassen@firewall.loc #设置报警邮件地址,可以设置多个,每行1个
failover@firewall.loc #需开启邮件报警及本机的Sendmail服务。
sysadmin@firewall.loc
}
notification_email_fromAlexandre.Cassen@firewall.loc
smtp_server 127.0.0.1 #设置SMTPServer地址;
smtp_connect_timeout 30
router_id LVS_DEVEL
}
########VRRPInstance########
vrrp_instance VI_1 {
state BACKUP #指定Keepalived的角色,MASTER为主机服务器,BACKUP为备用服务器
interface eth1 #BACKUP为备用服务器
virtual_router_id 51
priority 99 #定义优先级,数字越大,优先级越高,主机器必须大于备机。
advert_int 1
authentication {
auth_type PASS #设置验证类型,主要有PASS和AH两种
auth_pass 1111 #设置验证密码
}
virtual_ipaddress {
172.19.19.223 #设置主DR的虚拟IP地址(virtualIP),可多设,但必须每行1个
}
}
########Virtual Server########
virtual_server172.19.19.223 3306 { #注意IP地址与端口号之间用空格隔开
delay_loop 6 #设置健康检查时间,单位是秒
lb_algo lc #设置负载调度算法,默认为rr,即轮询算法,最优秀是wlc算法,这里使用的是最小链接算法
lb_kind DR #设置LVS实现LB机制,有NAT、TUNN和DR三个模式可选
#nat_mask 255.255.255.0
#persistence_timeout 50 #会话保持时间,单位为秒
protocol TCP #指定转发协议类型,有TCP和UDP两种
real_server 172.19.19.135 3306 {
weight 1 #配置节点权值,数字越大权值越高
TCP_CHECK {
connect_timeout 3 #表示3秒无响应,则超时
nb_get_retry 3 #表示重试次数
delay_before_retry 3 #表示重试间隔
}
}
real_server 172.19.19.136 3306 { #配置服务器节点,即RealServer2的public IP
weight 3 #配置节点权值,数字越大权值越高
TCP_CHECK {
connect_timeout 3 #表示3秒无响应,则超时
nb_get_retry 3 #表示重试次数
delay_before_retry 3 #表示重试间隔
}
}
real_server 172.19.19.137 3306 { #配置服务器节点,即RealServer2的public IP
weight 3 #配置节点权值,数字越大权值越高
TCP_CHECK {
connect_timeout 3 #表示3秒无响应,则超时
nb_get_retry 3 #表示重试次数
delay_before_retry 3 #表示重试间隔
}
}
}
---------------------------------------------------------------------------------------------------------------------------
备注:
可以讲两台LVS的keepalived的状态设置成BUCKUP,即主节点恢复之后,VIP不回切,将坏掉的节点修复之后做成备节点。
部署完成后在LVS机器上执行如下命令:
[root@LVS1 ~]# yum install–y ipvsadm
[root@LVS1 ~]# ipvsadm –Ln
IP Virtual Server version1.2.1 (size=4096)
Prot LocalAddress:PortScheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.19.19.223:3306 rr persistent 120
-> 172.19.19.135:3306 Route 125 0 0
-> 172.19.19.136:3306 Route 125 0 0
-> 172.19.19.137:3306 Route 125 0 0
使用LVS的DR模式,把VIP绑定到lo:1上。
[root@LVS1 ~]# vi/etc/sysctl.conf
net.ipv4.conf.all.arp_ignore= 1
net.ipv4.conf.all.arp_announce= 2
net.ipv4.conf.lo.arp_ignore= 1
net.ipv4.conf.lo.arp_announce= 2
[root@LVS1 ~]# sysctl –p
配置LVS1,LVS2上的realserver,绑定vip到lo:0
[root@LVS1 ~]# vi/etc/init.d/realserver
---------------------------------------------------------------------------------------------------------------------------
#!/bin/bash
VIP=172.19.19.223
source/etc/rc.d/init.d/functions
case "$1" in
start)
ifconfig lo:0 $VIP netmask255.255.255.255 broadcast $VIP
ifconfig lo:0 $VIP netmask255.255.255.255 broadcast $VIP
/sbin/route add -host $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
echo "RealServer Start OK"
;;
stop)
ifconfig lo:0 down
route del $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"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0
---------------------------------------------------------------------------------------------------------------------------
[root@LVS1 ~]# chmod u+x/etc/init.d/realserver
[root@LVS1 ~]# chmod u+x/etc/rc.d/init.d/functions
[root@LVS1 ~]# /etc/init.d/realserverstart
[root@LVS2 ~]# chmod u+x/etc/init.d/realserver
[root@LVS2 ~]#chmod u+x/etc/rc.d/init.d/functions
[root@LVS2 ~]# /etc/init.d/realserverstart
至此Slave集群搭建完成,业务可通过访问VIP(172.19.19.233)进行查询操作。
3.6.3Slave集群注意事项
LVS有很多中负载均衡算法,采用不同的算法使后端的Slave主机达到更好的负载均衡效果。
当Slave节点增加很多时,超过10台以上建议通过垂直拆分来解决压力问题,因为检测脚本是自定义的,性能问题会导致LVS汲取负载过高。
目前DR模式在一个IDC中部署,不能实现过IDC容灾问题,IDC容灾问题需要另行考虑。
4.MySQL集群注意事项
MySQL集群满足了企业级的需求,但也并非完美的解决方案。没一个方案都有有点也有缺点,次方案也不例外,在部署的过程中需要考虑以下几个问题。
Heartbeat+DRBD+MySQL这方案本身不能达到毫秒级的切换速度,它的切换速度主要受两个因素影响:文件系统和表的恢复需要的时间。这里需要说明的是,MyISAM引擎不适合HA,因为MyISAM类型的表在宕机厚需要很长的修复时间,这违背了HA的初衷,所以把除系统表之外的所有表类型都修改为innodb引擎。
如果对可靠性要求比较高,写入的并发量非常大,建议在my.cnf中修改“innodb_flush_log_at_trx_commit =1”,以保证失误的安全性。但这会对I/O提出挑战,如果抉择,最终需要根据具体情况做出权衡。
如果写入量不大,可以考虑在my.cnf中假如“sync_binlog = 0”来避免在某种特殊情况下Master突然宕机,出现Slave上的关于Master的binlog位置(master_log_pos)点超过Master宕机时写入的binlog点的情况。这对I/O很有挑战性。
在Slave上变更主库连接信息时最好指定“master_connect_retry”的值为一个合适的数值。在出现VIP漂移时,Slave可以更快地去重新连接VIP,减少因为切换造成的同步延时问题。
要为my.cnf中的“innodb_log_file_size”和“innodb_log_buffer_size”参数设置合适的值,设置太大会导致恢复时间比较长,降低故障切换的速度。
建议在ha.cnf中使用“auto_failback off”选项,如果使用“on”选项会导致在主、备之间来回切换,增加成本。在必须执行主、备切换的情况下,无故障执行即可。
使用dopd保证在数据不一致时不进行切换,需要人工干预,同时要对DOPD的同步进行监控,不同步时报警通知DBA。
如果OS是64位的,建议一台主机部署一个DRBD分区、一个端口。这样做对资源有一定的浪费,但是管理成本很低。不建议在一台主机上部署多个DRBD分区和搭建多个MySQL,例如/dev/drbd0(primary/secondary)、/dev/drbd1/(secondary/primary),这种模式减少了机器成本,但增加了管理成本和复杂度,同事违背了这个方案的初衷。
HA也有自己适用的场合,不能利用它解决所有的问题(因为HA并不能监控MySQL的服务状态,当MySQL主节点的连接端口宕机时,HA默认监控不到),这时需要考虑通过heartbeat的crm模式来实现对MySQL端口或者服务的监控。
MySQL部署完成后,定期检测系统是否运行正常是很有必要的。小概率事件是导致大故障的根源。
5.小节
以上主要讲述了MySQL高可用集群在企业中的搭建和应用,MySQL通过复制功能实现多台MySQL的数据同步,heartbeat实现了MySQL写操作的高可用性,DRBD实现了MySQL主节点数据块的实时同步,而LVS实现了MySQL读操作的负载均衡。
目前,MySQL+heartbeat+DRBD+LVS组合已经是一套成熟的集群解决方案。首先,通过heartbeat+DRBD完成了MySQL的主节点写操作可高可用性,然后通过MySQL+LVS组合实现了MySQL数据库的主从复制,同时实现了和MySQL读操作的负载均衡。从应用方面来看,这个方案实现了读写的分离,并且融合了写操作的高可用性和读操作的负载均衡,因此,作为企业应用平台,这样的方案应该是首选。
上面的文档,大部分采用《高性能Linux服务器构建实战》章节,
参考了http://agenge.com/2015/05/27/drbdheartbeatmysqlgao-ke-yong-pei-zhi/
涉及到版权问题,无意冒犯,只是纯粹的资料分享,如果有不足之处,欢迎大家批评指正。