求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
MySQL-Nginx-Pacemaker-corosync(openais)-drbd active/passive cluster
 

作者:Cooper,发布于2011-10-24

 

系统:CentOS 5.4

IP分配:

HA1 eth0:192.168.0.66 eth1:192.168.10.1

HA2 eth0:192.168.0.69 eth1:192.168.10.2

VIP 192.168.0.120

DRBD(Distributed Replicated Block Device),DRBD 号称是 “网络 RAID”,开源软件,由LINBIT 公司开发。DRBD实际上是一种块设备的实现,主要被用于Linux平台下的高可用(HA)方案之中。他有内核模块和相关程序而组成,通过网络通信来同步镜像整个设备,有点类似于一个网络RAID-1的功能。也就是说当你将数据写入本地的DRBD设备上的文件系统时,数据会同时被发送到网络中的另外一台主机之上,并以完全相同的形式记录在文件系统中。本地节点与远程节点的数据可以保证实时的同步,并保证IO的一致性。所以当本地节点的主机出现故障时,远程节点的主机上还会保留有一份完全相同的数据,可以继续使用,以达到高可用的目的。

一、安装DRBD

在HA1和HA2上安装DRBD。

wget http://oss.linbit.com/drbd/8.3/drbd-8.3.5.tar.gz

[root@HA1 ~]# tar xzvf drbd-8.3.5.tar.gz

[root@HA1 ~]# cd drbd-8.3.5

[root@HA1 drbd-8.3.5]# make clean all

[root@HA1 drbd-8.3.5]# make install

[root@HA1 drbd-8.3.5]# cd

[root@HA1 ~]# vi /etc/drbd.conf

global {

         usage-count yes; # 是否参加使用者统计,yes为参加

        }

common {

syncer { rate 100M; } # 设置网络同步速率,建议改为实际网络速率

       }

# 一个DRBD设备(即:/dev/drbdX),叫做一个"资源"。

resource "r0" {

protocol C; # 数据同步协议,C表示收到远程主机的写入确认后才认为写入完成

startup {

       }

disk {

         on-io-error detach;

       }

handlers {

         split-brain "/usr/lib/drbd/notify-split-brain.sh root"; # 自动修复脑裂问题

       }

net {

      # 设置主备机之间通信使用的信息算法.

       cram-hmac-alg sha1;

      shared-secret "FooFunFactory";

      # 自动修复脑裂问题

      after-sb-0pri discard-zero-changes;

      after-sb-1pri discard-secondary;

      after-sb-2pri disconnect;

    }

syncer {

    }

# 每个主机的说明以"on"开头,后面是主机名

on HA1 {

      device /dev/drbd0;

       disk /dev/sdb;

       # 设置DRBD的监听端口,用于与另一台主机通信

       address 192.168.0.66:7789;

       # metadata的存放位置

      # internal表示将metadata存放到drbd挂在的磁盘分区的最后的位置上

       meta-disk internal;

     }

on HA2 {

       device /dev/drbd0;

       disk /dev/sdb;

      address 192.168.0.69:7789;

       meta-disk internal;

     }

}

DRBD将数据的各种信息块保存在一个专用的区域里,这些metadata包括了

a,DRBD设备的大小

b,产生的标识

c,活动日志

d,快速同步的位图

metadata的存储方式有内部和外部两种方式,使用哪种配置都是在资源配置中定义的

内部metadata:内部metadata存放在同一块硬盘或分区的最后的位置上

优点:metadata和数据是紧密联系在一起的,如果硬盘损坏,metadata同样就没有了,同样在恢复的时候,metadata也会一起被恢复回来

缺点:metadata和数据在同一块硬盘上,对于写操作的吞吐量会带来负面的影响,因为应用程序的写请求会触发metadata的更新,这样写操作就会造成两次额外的磁头读写移动。

外部metadata:外部的metadata存放在和数据磁盘分开的独立的块设备上

优点:对于一些写操作可以对一些潜在的行为提供一些改进

缺点:metadata和数据不是联系在一起的,所以如果数据盘出现故障,在更换新盘的时候就需要人为的干预操作来进行现有node对心硬盘的同步了

[root@HA1 ~]# scp /etc/drbd.conf HA2:/etc/

初始化并启动两个系统上的 DRBD 服务:

[root@HA1 ~]# drbdadm create-md r0

[root@HA1 ~]# service drbd start

Starting DRBD resources: [ d(r0) s(r0) n(r0) ].

将 HA1 配置为主节点:

[root@HA1 ~]# drbdadm --overwrite-data-of-peer primary r0

两个设备开始同步数据:

[root@HA2 ~]# service drbd status

drbd driver loaded OK; device status:

version: 8.3.5 (api:88/proto:86-91)

GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29

m:res cs ro ds p mounted fstype

… sync’ed: 0.6% (6108/6140)M

0:r0 SyncTarget Secondary/Primary Inconsistent/UpToDate C

………

[root@HA2 ~]# service drbd status

drbd driver loaded OK; device status:

version: 8.3.5 (api:88/proto:86-91)

GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29

m:res cs ro ds p mounted fstype

… sync’ed: 45.6% (3344/6140)M

0:r0 SyncTarget Secondary/Primary Inconsistent/UpToDate C

………

同步数据完成:

[root@HA2 ~]# service drbd status

drbd driver loaded OK; device status:

version: 8.3.5 (api:88/proto:86-91)

GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29

m:res cs ro ds p mounted fstype

… sync’ed:100.0% (4/6140)M

0:r0 SyncTarget Secondary/Primary Inconsistent/UpToDate C

[root@HA2 ~]# service drbd status

drbd driver loaded OK; device status:

version: 8.3.5 (api:88/proto:86-91)

GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29

m:res cs ro ds p mounted fstype

0:r0 Connected Secondary/Primary UpToDate/UpToDate C

[root@HA1 ~]# cat /proc/drbd

version: 8.3.5 (api:88/proto:86-91)

GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA1, 2009-11-13 01:53:51

0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r—-

ns:6291228 nr:0 dw:0 dr:6291228 al:0 bm:384 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

两个节点上的块设备都完全同步之后,使用诸如ext3的文件系统格式化主节点上的 DRBD 设备。

[root@HA1 ~]# mkfs.ext3 /dev/drbd0

测试DRBD服务:

手动挂载DRBD设备,并测试写入文件。

[root@HA1 ~]# mount -o rw /dev/drbd0 /data/

[root@HA1 ~]# echo “This is a test line.” > /data/test.txt

卸载DRBD设备并将HA1设置为从设备。

[root@HA1 ~]# umount /data/

[root@HA1 ~]# drbdadm secondary r0

将HA2设置为主设备。

[root@HA2 ~]# drbdadm primary r0

[root@HA2 ~]# service drbd status

drbd driver loaded OK; device status:

version: 8.3.5 (api:88/proto:86-91)

GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29

m:res cs ro ds p mounted fstype

0:r0 Connected Primary/Secondary UpToDate/UpToDate C

挂载DRBD设备并验证能够读出在HA1上写入的文件。

[root@HA2 ~]# mount -o rw /dev/drbd0 /data/

[root@HA2 ~]# cat /data/test.txt

This is a test line.

卸载DRBD设备并将HA2设置为从设备。

[root@HA2 ~]# umount /data/

[root@HA2 ~]# drbdadm secondary r0

将HA1设置为主设备。

[root@HA1 ~]# drbdadm primary r0

查看HA2的DRDB状态:

[root@HA2 ~]# service drbd status

drbd driver loaded OK; device status:

version: 8.3.5 (api:88/proto:86-91)

GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@HA2, 2009-11-13 01:58:29

m:res cs ro ds p mounted fstype

0:r0 Connected Secondary/Primary UpToDate/UpToDate C

在HA1和HA2上配置hosts

[root@HA1 ~]# cat /etc/hosts

# Do not remove the following line, or various programs

# that require network functionality will fail.

127.0.0.1 vpc localhost.localdomain localhost

::1 localhost6.localdomain6 localhost6

192.168.10.1 HA1

192.168.10.2 HA2

在HA1和HA2上配置时间同步:

[root@HA1 ~]# crontab -e

*/5 * * * * /usr/sbin/ntpdate ntp.api.bz

二、在HA1和HA2安装MySQL和Nginx并将数据迁移到/data目录

[root@HA1 ~]# yum install -y mysql-server

[root@HA1 ~]# cat /etc/my.cnf

[mysqld]

datadir=/data/mysql

socket=/data/mysql/mysql.sock

user=mysql

bind-address=192.168.0.120

[root@HA1 ~]# cp -r /var/lib/mysql/ /data/

[root@HA1 ~]# cd /data/

[root@HA1 data]# chown -R mysql.mysql mysql/

[root@HA1 data]# service mysqld start

Starting MySQL: [ OK ]

[root@HA1 data]# service mysqld stop

Stopping MySQL: [ OK ]

注意:数据迁移只需在HA1上做。

安装Nginx略,具体见Nginx 0.7.x + PHP 5.2.8(FastCGI)搭建胜过Apache十倍的Web服务器(http://blog.s135.com/post/366/)

[root@HA1 ~]# chkconfig --level 2345 mysqld off

[root@HA2 ~]# chkconfig --level 2345 mysqld off

注意:不要在外部启动HA使用的资源,一切让HA去控制。

编写nginx lsb资源代理脚本(注意nginx安装路径):

[root@HA1 ~]# cat /etc/init.d/nginxd

#!/bin/sh

# source function library

. /etc/rc.d/init.d/functions

# Source networking configuration.

. /etc/sysconfig/network

# Check that networking is up.

[ ${NETWORKING} = "no" ] && exit 0

RETVAL=0

prog="nginx"

nginxDir=/usr/local/nginx

nginxd=$nginxDir/sbin/nginx

nginxConf=$nginxDir/conf/nginx.conf

nginxPid=$nginxDir/nginx.pid

nginx_check()

{

      if [[ -e $nginxPid ]]; then

      ps aux |grep -v grep |grep -q nginx

      if (( $? == 0 )); then

       echo "$prog already running..."

       exit 1

      else

      rm -rf $nginxPid &> /dev/null

       fi

       fi

  }

start()

{

       nginx_check

       if (( $? != 0 )); then

       true

       else

       echo -n $"Starting $prog:"

       daemon $nginxd -c $nginxConf

       RETVAL=$?

       echo

       [ $RETVAL = 0 ] && touch /var/lock/subsys/nginx

       return $RETVAL

       fi

}

stop()

{

       echo -n $"Stopping $prog:"

       killproc $nginxd

       RETVAL=$?

       echo

       [ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx        $nginxPid

}

reload()

{

       echo -n $"Reloading $prog:"

       killproc $nginxd -HUP

       RETVAL=$?

       echo

}

case "$1" in

start)

start

;;

stop)

stop

;;

restart)

stop

start

;;

reload)

reload

;;

status)

status $prog

RETVAL=$?

;;

*)

echo $"Usage: $0 {start|stop|restart|reload|status}"

RETVAL=1

esac

exit $RETVAL

[root@HA1 ~]# chmod +x /etc/init.d/nginxd

[root@HA1 ~]# scp /etc/init.d/nginxd HA2: /etc/init.d/nginxd

三、安装配置corosync和pacemaker

corosync是基于OpenAIS构建的集群引擎,可替代heartbeat进行心跳检测。

The Corosync Cluster Engine is an open source project Licensed under the BSD License derived from the OpenAIS project. OpenAIS uses a UDP multicast based communication protocol to periodically check for node availability.

[root@HA1 ~]# wget -O /etc/yum.repos.d/pacemaker.repo http://clusterlabs.org/rpm/epel-5/clusterlabs.repo

[root@HA1 ~]# wget ftp://ftp.pbone.net/mirror/centos.karan.org/el5/extras/testing/i386/RPMS/libesmtp-1.0.4-6.el5.kb.i386.rpm

[root@HA1 ~]# rpm -ivh libesmtp-1.0.4-6.el5.kb.i386.rpm

[root@HA1 ~]# yum install -y pacemaker corosync

[root@HA1 ~]# corosync-keygen

Corosync Cluster Engine Authentication key generator.

Gathering 1024 bits for key from /dev/random.

Press keys on your keyboard to generate entropy.

Writing corosync key to /etc/corosync/authkey.

[root@HA1 ~]# scp /etc/corosync/authkey HA2:/etc/corosync/

[root@HA1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf

[root@HA1 ~]# vi !$

# Please read the corosync.conf.5 manual page

compatibility: whitetank

totem {

       version: 2

       secauth: off

       threads: 0

       interface {

              ringnumber: 0

              bindnetaddr: 192.168.10.0

              mcastaddr: 226.94.1.1

              mcastport: 5405

              }

}

logging {

       fileline: off

       to_stderr: yes

       to_logfile: yes

       to_syslog: yes

       logfile: /var/log/corosync.log

       debug: off

       timestamp: on

       logger_subsys {

                     subsys: AMF

                     debug: off

              }

}

amf {

       mode: disabled

}

service {

       # Load the Pacemaker Cluster Resource Manager

       ver: 0

       name: pacemaker

       use_mgmtd: yes

       }

[root@HA1 ~]# scp /etc/corosync/corosync.conf HA2:/etc/corosync/corosync.conf

[root@HA1 ~]# service corosync start

Starting Corosync Cluster Engine (corosync): [ OK ]

[root@HA1 ~]# chkconfig --level 2345 corosync on

在HA2上执行:

[root@HA2 ~]# chown root:root /etc/corosync/authkey

[root@HA2 ~]# chmod 400 /etc/corosync/authkey

[root@HA2 ~]# service corosync start

Starting Corosync Cluster Engine (corosync): [ OK ]

[root@HA2 ~]# chkconfig --level 2345 corosync on

四、配置CRM资源

[root@HA1 ~]# crm

crm(live)# configure

crm(live)configure# node HA1

crm(live)configure# node HA2

# 配置drbd原始资源

crm(live)configure# primitive drbd ocf:linbit:drbd \

params drbd_resource="r0" \

meta migration-threshold="10"

# 配置drbd资源监控

crm(live)configure# monitor drbd 30s:20s

# 配置文件系统原始资源

crm(live)configure# primitive fs ocf:heartbeat:Filesystem \

params device="/dev/drbd0" directory="/data" fstype="ext3"

# 配置mysql原始资源,使用lsb代理

crm(live)configure# primitive mysqld lsb:mysqld

# 配置nginx原始资源,使用lsb代理

crm(live)configure# primitive nginxd lsb:nginxd

# 配置共享IP原始资源

crm(live)configure# primitive vip ocf:heartbeat:IPaddr2 \

params ip="192.168.0.120" nic="eth0:0"

# 创建资源组保障资源在某一节点上按顺序启动和停止

crm(live)configure# group mysql-group fs vip mysqld nginxd

# 配置drbd主资源约束

crm(live)configure# ms ms-drbd-mysql drbd \

meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"

# 配置资源位置约束,保证mysql-group资源组启动在drbd主资源上

crm(live)configure# colocation mysql-on-drbd inf: mysql-group ms-drbd-mysql:Master

# 配置资源启动顺序约束,保证drbd启动后启动mysql-group资源组

crm(live)configure# order mysql-after-drbd inf: ms-drbd-mysql:promote mysql-group:start

crm(live)configure# property $id="cib-bootstrap-options" \

expected-quorum-votes="2" \

stonith-enabled="false" \

no-quorum-policy="ignore" \

start-failure-is-fatal="false"

crm(live)configure# commit

crm(live)configure# end

crm(live)#

五、测试

[root@HA1 ~]# crm status

============

Last updated: Fri Nov 20 22:47:51 2009

Stack: openais

Current DC: HA2 -- partition with quorum

Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06

2 Nodes configured, 2 expected votes

2 Resources configured.

============

Online: [ HA1 HA2 ]

Master/Slave Set: ms-drbd-mysql

Masters: [ HA1 ]

Slaves: [ HA2 ]

Resource Group: mysql-group

fs (ocf::heartbeat:Filesystem): Started HA1

vip (ocf::heartbeat:IPaddr2): Started HA1

mysqld (lsb:mysqld): Started HA1

nginxd (lsb:nginxd): Started HA1

关闭HA1,在HA2上查看HA状态:

[root@HA2 ~]# crm_mon -i1

============

Last updated: Sat Nov 21 01:31:13 2009

Stack: openais

Current DC: HA2 - partition WITHOUT quorum

Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06

2 Nodes configured, 2 expected votes

2 Resources configured.

============

Online: [ HA2 ]

OFFLINE: [ HA1 ]

Master/Slave Set: ms-drbd-mysql

Masters: [ HA2 ]

Stopped: [ drbd:1 ]

Resource Group: mysql-group

fs (ocf::heartbeat:Filesystem): Started HA2

vip (ocf::heartbeat:IPaddr2): Started HA2

mysqld (lsb:mysqld): Started HA2

nginxd (lsb:nginxd): Started HA2

启动HA1,资源自动迁移到HA1:

[root@HA1 ~]# crm_mon -i1

============

Last updated: Mon Nov 23 15:42:52 2009

Stack: openais

Current DC: HA2 - partition with quorum

Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06

2 Nodes configured, 2 expected votes

2 Resources configured.

============

Online: [ HA1 HA2 ]

Master/Slave Set: ms-drbd-mysql

Masters: [ HA1 ]

Slaves: [ HA2 ]

Resource Group: mysql-group

fs (ocf::heartbeat:Filesystem): Started HA1

vip (ocf::heartbeat:IPaddr2): Started HA1

mysqld (lsb:mysqld): Started HA1

nginxd (lsb:nginxd): Started HA1

手动迁移资源到HA2

[root@HA1 ~]# crm resource migrate mysql-group HA2

[root@HA2 ~]# crm_mon -i1

============

Last updated: Mon Nov 23 15:43:42 2009

Stack: openais

Current DC: HA2 - partition with quorum

Version: 1.0.6-f709c638237cdff7556cb6ab615f32826c0f8c06

2 Nodes configured, 2 expected votes

2 Resources configured.

============

Online: [ HA1 HA2 ]

Master/Slave Set: ms-drbd-mysql

Masters: [ HA2 ]

Slaves: [ HA1 ]

Resource Group: mysql-group

fs (ocf::heartbeat:Filesystem): Started HA2

vip (ocf::heartbeat:IPaddr2): Started HA2

mysqld (lsb:mysqld): Started HA2

nginxd (lsb:nginxd): Started HA2

六、解决脑裂(split brain)问题:

在“双机热备”高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体、动作协调的HA系统,就分裂成为2个独立的个体。由于相互失去了联系,都以为是对方出了故障,2个节点上的HA软件像“裂脑人”一样,“本能”地争抢“共享资源”、争起“应用服务”,就会发生严重后果:或者共享资源被瓜分、2边“服务”都起不来了;或者2边“服务”都起来了,但同时读写“共享存储”,导致数据损坏(常见如数据库轮询着的联机日志出错)。

对付HA系统“裂脑”的对策大概有以下几条:

1)添加冗余的心跳线,例如双线跳线。尽量减少“裂脑”发生机会。

2)启用磁盘锁。正在服务一方锁住共享磁盘,“裂脑”发生时,让对方完全“抢不走”共享磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的一方不主动“解锁”,另一方就永远得不到共享磁盘。现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。于是有人在HA中设计了“智能”锁。即,正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁。平时就不上锁了。

3)设置仲裁机制。例如设置参考IP(如网关IP),当心跳线完全断开时,2个节点都各自ping一下 参考IP,不通则表明断点就出在本端,不仅“心跳”、还兼对外“服务”的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够ping通参考IP的一端去起服务。更保险一些,ping不通参考IP的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。

手动解决DRBD脑裂问题:

[root@HA2 ~]# drbdadm down all

[root@HA2 ~]# drbdadm create-md all


相关文章

企业架构、TOGAF与ArchiMate概览
架构师之路-如何做好业务建模?
大型网站电商网站架构案例和技术架构的示例
完整的Archimate视点指南(包括示例)
相关文档

数据中台技术架构方法论与实践
适用ArchiMate、EA 和 iSpace进行企业架构建模
Zachman企业架构框架简介
企业架构让SOA落地
相关课程

云平台与微服务架构设计
中台战略、中台建设与数字商业
亿级用户高并发、高可用系统架构
高可用分布式架构设计与实践

 
分享到
 
 
     



专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS



面向应用的架构设计实践
单元测试+重构+设计模式
软件架构师—高级实践
软件架构设计方法、案例与实践
嵌入式软件架构设计—高级实践
SOA体系结构实践



锐安科技 软件架构设计方法
成都 嵌入式软件架构设计
上海汽车 嵌入式软件架构设计
北京 软件架构设计
上海 软件架构设计案例与实践
北京 架构设计方法案例与实践
深圳 架构设计方法案例与实践
嵌入式软件架构设计—高级实践
更多...