A:Async,异步:本地写成功后立即返回,数据放在发送buffer中,可能丢失,但传输性能好。
B:Semi sync,半同步:对方接收到数据后,但还没有落盘前返回。
C:Sync,同步:本地和对方写成功落盘确认后返回,数据可靠性高,生产系统一般都采用这种方式。
资源名称:可以是除了空白字符外的任意ACSII码字符。
DRBD设备:在双方节点上,此DRBD设备的设备文件,一般为/dev/drbdN,其主设备号147。
磁盘:在双方节点上,各自提供的存储设备。
网络配置:双方数据同步时所使用的网络属性。
drbdadm:高级管理工具,管理/etc/drbd.conf,向drbdsetup和drbdmeta发送指令。
drbdsetup:配置装载进kernel的DRBD模块,平时很少直接用。
drbdmeta:管理META数据结构,平时很少直接用。
[root@node1~]#cat /etc/sysconfig/network-scripts/ifcfg-ens32
# Generated by dracut initrd
NAME="ens32"
DEVICE="ens32"
ONBOOT=yes
NETBOOT=yes
UUID="adb62466-2361-405e-ada9-b48fe7c09546"
IPV6INIT=yes
BOOTPROTO=static
TYPE=Ethernet
IPADDR=172.16.1.125
NETMASK=255.255.255.0
GATEWAY=172.16.1.254
DNS1=172.16.1.10
service network restart
[root@node1~]#cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.16.1.125 node1
172.16.1.126 node2
编辑/etc/selinux/config文件,设置SELINUX=disabled。
执行下面的命令禁用防火墙:
ssh-keygen -t rsa
ssh-copy-id 172.16.1.126
ssh-keygen -t rsa
ssh-copy-id 172.16.1.125
yum install ntp
systemctl enable ntpd.service
service ntpd start
# 导入GPG-KEY,用于验证签名
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
# 安装yum源
yum install https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
# 安装drbd和内核相关软件包
yum install -y drbd90-utils kmod-drbd90 kernel*
# 因为升级了内核,需要重启系统
reboot
[root@node2~]#modprobe drbd
[root@node2~]#lsmod | grep drbd
drbd_transport_tcp 22144 1
drbd 568697 3 drbd_transport_tcp
libcrc32c 12644 4 xfs,drbd,ip_vs,nf_conntrack
[root@node2~]#
[root@node1~]#cat /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";
[root@node1~]#
[root@node1~]#cat /etc/drbd.d/global_common.conf
global {
usage-count no; # 不让官方统计drbd的使用情况
}
common {
protocol C; # 使用DRBD的同步协议,数据可靠性高
disk {
on-io-error detach; # 配置I/O错误处理策略为分离
}
}
detach:这是默认和推荐的选项,如果在节点上发生底层的硬盘I/O错误,它会将设备运行在Diskless无盘模式下。
pass_on:DRBD会将I/O错误报告到上层,在主节点上,它会将其报告给挂载的文件系统。
local-in-error:调用本地磁盘I/O处理程序定义的命令。这需要有相应的local-io-error调用的资源处理程序,给管理员有足够自由的权力调用local-io-error处理I/O错误。
[root@node1 ~]# cat /etc/drbd.d/mysql.res
resource mysql { # 资源名称
disk /dev/sdb; # 磁盘分区
device /dev/drbd0; # DRBD设备
meta-disk internal; # 元数据存储方式
on node1 {
device /dev/drbd0;
disk /dev/sdb;
address 172.16.1.125:7789; # 节点1地址
}
on node2 {
device /dev/drbd0;
disk /dev/sdb;
address 172.16.1.126:7789; # 节点2地址
}
}
scp -rp /etc/drbd.d/* node2:/etc/drbd.d/
drbdadm create-md mysql
drbdadm up mysql
[root@node1~]#drbdadm role mysql
Secondary
[root@node1~]#drbdadm --force primary mysql
[root@node1~]#drbdadm role mysql
Primary
[root@node1~]#mkfs.xfs /dev/drbd0
meta-data=/dev/drbd0 isize=512 agcount=4, agsize=327668 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=1310671, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
mount /dev/drbd0 /mnt
[root@node1/mnt]#drbdadm dstate mysql
UpToDate/UpToDate
[root@node1/mnt]#drbdadm cstate mysql
Connected
Diskless:本地没有块设备分配给DRBD使用,这表示没有可用的设备,或者使用drbdadm命令手工分离或是底层的I/O错误导致自动分离。
Attaching:读取无数据时候的瞬间状态。
Failed:本地块设备报告I/O错误的状态,其下一个状态为Diskless无盘。
Negotiating:在已经连接的DRBD设置进行Attach读取无数据前的瞬间状态。
Inconsistent:数据是不一致的,在两个节点上(初始的完全同步前)这种状态出现后立即创建一个新的资源。此外,在同步期间在同步目标节点上出现这种状态。
Outdated:数据资源是一致的,但是已经过时。
DUnknown:当对等节点网络连接不可用时出现这种状态。
Consistent:一个没有连接的节点数据一致。当建立连接时,它决定数据是UpToDate或是Outdated。
UpToDate:一致的最新的数据状态,这个状态为正常状态。
StandAlone:网络配置不可用,资源还没有被连接或是被管理断开(使用 drbdadm disconnect 命令),或是由于出现认证失败或是脑裂的情况。
Disconnecting:断开只是临时状态,下一个状态是StandAlone独立的。
Unconnected:是尝试连接前的临时状态,可能下一个状态为WFconnection和WFReportParams。
Timeout:与对等节点连接超时,也是临时状态,下一个状态为Unconected。
BrokerPipe:与对等节点连接丢失,也是临时状态,下一个状态为Unconected。
NetworkFailure:与对等节点推动连接后的临时状态,下一个状态为Unconected。
ProtocolError:与对等节点推动连接后的临时状态,下一个状态为Unconected。
TearDown:临时状态,对等节点关闭,下一个状态为Unconected。
WFConnection:等待和对等节点建立网络连接。
WFReportParams:已经建立TCP连接,本节点等待从对等节点传来的第一个网络包。
Connected:DRBD已经建立连接,数据镜像现在可用,节点处于正常状态。
StartingSyncS:完全同步,有管理员发起的刚刚开始同步,未来可能的状态为SyncSource或PausedSyncS。
StartingSyncT:完全同步,有管理员发起的刚刚开始同步,下一状态为WFSyncUUID。
WFBitMapS:部分同步刚刚开始,下一步可能的状态为SyncSource或PausedSyncS。
WFBitMapT:部分同步刚刚开始,下一步可能的状态为WFSyncUUID。
WFSyncUUID:同步即将开始,下一步可能的状态为SyncTarget或PausedSyncT。
SyncSource:以本节点为同步源的同步正在进行。
SyncTarget:以本节点为同步目标的同步正在进行。
PausedSyncS:以本地节点是一个持续同步的源,但是目前同步已经暂停,可能是因为另外一个同步正在进行或是使用命令(drbdadm pause-sync)暂停了同步。
PausedSyncT:以本地节点为持续同步的目标,但是目前同步已经暂停,这可以是因为另外一个同步正在进行或是使用命令(drbdadm pause-sync)暂停了同步。
VerifyS:以本地节点为验证源的线上设备验证正在执行。
VerifyT:以本地节点为验证目标的线上设备验证正在执行。
datadir = /mnt/
# 停止mysql服务
service mysql stop
# 将数据目录拷贝到挂载点
cp -r /data/* /mnt/
# 将数据目录的属主改为MySQL
chown -R mysql:mysql /mnt/
# 启动mysql服务
service mysql start
create database db1;
use db1;
create table t1 (a int);
insert into t1 select 1;
commit;
service mysql stop
umount /mnt
drbdadm secondary mysql
drbdadm primary mysql
mount /dev/drbd0 /mnt
chown -R mysql:mysql /mnt
service mysql start
mysql> select * from db1.t1;
+------+
| a |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
[root@node1 ~]# cat /usr/local/heartbeat/etc/ha.d/ha.cf
debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility local0
keepalive 1
deadtime 30
warntime 10
initdead 120
udpport 694
bcast ens32
ucast ens32 172.16.1.126
auto_failback off
node node1
node node2
ping 172.16.1.254
respawn hacluster /usr/local/heartbeat/libexec/heartbeat/ipfail
apiauth ipfail gid=haclient uid=hacluster
[root@node1 ~]#
ucast ens32 172.16.1.125
[root@node1 ~]# cat /usr/local/heartbeat/etc/ha.d/authkeys
auth 1
1 crc
[root@node1 ~]# cat /usr/local/heartbeat/etc/ha.d/haresources
node1 IPaddr::172.16.1.101/24/ens32 drbddisk::mysql Filesystem::/dev/drbd0::/mnt::xfs mysql
cd /usr/local/heartbeat/etc/ha.d
chmod 600 authkeys
ln -svf /usr/local/heartbeat/lib64/heartbeat/plugins/RAExec/* /usr/local/heartbeat/lib/heartbeat/plugins/RAExec/
ln -svf /usr/local/heartbeat/lib64/heartbeat/plugins/* /usr/local/heartbeat/lib/heartbeat/plugins/
cp /etc/ha.d/resource.d/drbddisk /usr/local/heartbeat/etc/ha.d/resource.d/
[root@node1 ~]# more /usr/local/heartbeat/etc/ha.d/resource.d/mysql
chown -R mysql:mysql /mnt/
service mysql start
[root@node1 ~]# more /home/mysql/mysql_check.sh
#!/bin/bash
. /home/mysql/.bashrc
count=1
while true
do
mysql -uroot -p123456 -S /data/mysql.sock -e "show status;" > /dev/null 2>&1
i=$?
ps aux | grep mysqld | grep -v grep > /dev/null 2>&1
j=$?
if [ $i = 0 ] && [ $j = 0 ]
then
sleep 3
else
if [ $i = 1 ] && [ $j = 0 ]
then
sleep 3
else
if [ $count -gt 5 ]
then
break
fi
let count++
continue
fi
fi
done
/etc/init.d/heartbeat stop
systemctl start heartbeat
systemctl enable heartbeat
systemctl status heartbeat
C:\Users\wxy>mysql -h172.16.1.101 -uroot -p123456 -e "select * from db1.t1"
mysql: [Warning] Using a password on the command line interface can be insecure.
+------+
| a |
+------+
| 1 |
+------+
# 首先启动mysql检测脚本,因为heartheat不检查服务的可用性,需要通过自定义脚本实现
nohup /home/mysql/mysql_check.sh &
# 停止mysqld
service mysql stop
# 先启动node1的heartheat
systemctl start heartbeat
# 停止node2的heartheat,也可以使用 iptables -I INPUT -p icmp -j DROP 禁用 ping
systemctl stop heartbeat
# 先启动node2的heartheat
systemctl start heartbeat
# node1重启
reboot
# 停止node1的heartbeat服务
systemctl stop heartbeat
# 停止node2的heartbeat服务
systemctl stop heartbeat
# 在node1上添加防火墙策略,拒绝node2的广播包
iptables -A INPUT -i ens32 -p udp -s 172.16.1.126 --dport 694 -j DROP
# 在node2上添加防火墙策略,拒绝node1的广播包
iptables -A INPUT -i ens32 -p udp -s 172.16.1.125 --dport 694 -j DROP
# 启动node1的heartbeat服务
systemctl start heartbeat
# 启动node2的heartbeat服务
systemctl start heartbeat
节点对之间心跳线路故障,导致无法正常的通信。
节点对上开启了防火墙阻挡了心跳消息的传输。
节点对上的心跳网卡地址等信息配置的不正确,导致发送心跳失败。
其它服务配置不当等原因,如心跳的方式不同,心跳广播冲突,软件出现了BUG等。
同时使用串行电缆和以太网电缆连接,同时用两条心跳线路,这样一条线路坏了,另一个线路还是好的,依然能传送消息,这是最简单的一个方案,也是推荐的防脑裂方法。
检测到裂脑的时候强行的关闭一个心跳节点(需要特殊的节点支持,如stonith,fence),相当于程序上备节点发现心跳线故障,发送关机命令到主节点。
做好对裂脑的监控报警,如邮件以及手机短信等,在问题发生的时候能够人为的介入到仲裁,降低损失。当然,在实施高可用方案的时候,要根据业务的实际需求确定是否能够容忍这样的损失。对于一般的网站业务,这个损失是可控的。
启用磁盘锁。正在服务一方锁住共享磁盘,脑裂发生的时候,让对方完全抢不走共享的磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的乙方不主动解锁,另一方就永远得不到共享磁盘。现实中介入服务节点突然死机或者崩溃,另一方就永远不可能执行解锁命令。后备节点也就截关不了共享的资和应用服务。于是有人在HA中设计了“智能”锁,正在服务的一方只在发现心跳线全部断开时才启用磁盘锁,平时就不上锁。
报警报在服务器接管之前,给人员处理留足够的时间就是1分钟内报警了,但是服务器不接管,而是5分钟之后接管,接管的时间较长。数据不会丢失,但就是会导致用户无法写数据。
报警后,不直接自动服务器接管,而是由人员接管。
增加仲裁的机制,确定谁该获得资源,这里面有几个参考的思路:增加一个仲裁机制。例如设置参考的IP,当心跳完全断开的时候,2个节点各自都ping一下参考的IP,不同则表明断点就出现在本段,这样就主动放弃竞争,让能够ping通参考IP的一端去接管服务。或者通过第三方软件仲裁谁该获得资源。
DRBD详解 及 DRBD+Mysql应用:https://www.cnblogs.com/chenghuan/articles/7531984.html
CentOS 7下DRBD数据同步部署:https://www.linuxidc.com/Linux/2017-12/149268.htm
heartbeat心跳检测和裂脑:https://blog.51cto.com/xxr007/1912518?utm_source=oschina-app
热 文 推 荐
☞马云穿布鞋演讲,任正非打的出行,盘点科技大佬们令人发指的节俭生活
点击阅读原文,即刻参加!