August 2007 Archives
原文链接:http://www.entage.net/1/viewspace_1868.html
作者:九尾银狐
关于本文
本文给出了一个MYSQL HA的实列,简单说明了如何实现MYSQL的高可用性,方法并非仅此一种,感兴趣的朋友可参考相关资料。
背景
当前大多网站采用MYSQL+Linux+APACHE这种经典配置,如何防止单点失败造成的整个网站的不可用是网站管理者必须要考虑的问题,其中数据库的高可用性(Database server's high availability)是重中之重。
对于数据库的高可用性,各商业软件的厂商都有各自的解决方案,比如Oracle OPS server和IBM DB2 (share-nothing architecture)。最近MYSQL AB也发布了MYSQL cluster 软件,使用与IBM DB2类似的技术。
MySQL cluster可能会是日后最理想的方案,但是从资源、可集成度方面考虑,笔者将给出一个简单实用的方案供大家借鉴。
实现原理
通过Linux HA 软件 heartbeat 实现IP的自动漂移,即当一台服务器宕机后,浮动IP(整个cluster的对外IP )自动漂移到另外一台服务器。
通过Mysql自身的replication 实现不同机器上多个数据库的同步
整体性能
此方案将会降低MYSQL 1%左右的性能,可用性及数据安全性将大有提高,同时服务器的切换对终端使用者是透明的,终端应用不需要进行更改。
所需硬件
安装有双网卡的配置大致相同的服务器或工作机两台(测试而已,用Vmware虚拟吧)
一条交叉网线(用于双机对连的心跳线)
所需软件
Linux HA 软件 heartbeat (只支持两个节点)
软件主页:http://www.linux-ha.org/
Mysql
软件主页:www.mysql.com
实现步骤
一、设置硬件环境:
Node1:
计算机名:RHEL1
eth0 : 192.168.168.1/255.255.255.0
eth1 : 10.0.0.1/255.0.0.0 (用于心跳)
Node2:
计算机名:RHEL2
eth0 : 192.168.168.2/255.255.255.0
eth1 : 10.0.0.2/255.0.0.0 (用于心跳)
Node1和Node2的eth0分别连接到你的交换机
Node1和Node2的eth1之间用心跳线直连起来,做心跳
二、安装MYSQL
在每个节点上分别安装mysql,不会装的看下面安装步骤或是参考其它资料
1.获取软件源码包
wget
http://mysql.linuxforum.net/Downloads/MySQL-4.0/mysql-4.0.20.tar.gz
2.解压缩源码包
tar -zxvf mysql-4.0.20.tar.gz
cd mysql-4.0.20
3.在linux系统中添加运行Mysql的用户和组
groupadd mysql
useradd -g mysql -d /var/lib/mysql -s /sbin/nologin mysql
4.配置编译参数
./configure --prefix=/usr --localstatedir=/var/lib/mysql
5.编译并安装
make
make install
6.装载原始授权到数据库
./scripts/mysql_install_db
7.copy配置文件到/etc目录
cp ./support-files/my-small.cnf /etc/my.cnf
8.copy启动脚本到资源目录
cp ./support-files/mysql.server /etc/rc.d/init.d/mysqld
9.添加mysql服务
chmod +x /etc/rc.d/init.d/mysqld
chkconfig --add mysqld
(chkconfig --list mysqld 查看状态,默认在运行级2.3.4.5是ON的,如果运行级3是Off,则执行chkconfig --level 3 mysqld on)
10.更改目录属主
chown -R mysql.mysql /var/lib/mysql
11.启动mysql
service mysqld start
12.设置mysql root用户密码
mysql -u root (登入mysql,以下操作在mysql命令行下进行)
mysql>set password forroot@localhost=password('yourpassword'); (设置从本地主机登录的root用户密码)
mysql>use mysql;
mysql>delete from user where user='' ; (删除匿名用户)
mysql>delete from user where host<>'localhost' ; (只充许从localhost登录)
mysql>flush privileges ; (使更改生效)
mysql>\q (退出mysql命令行)
至此,Mysql基本安装完毕。
三、设置Mysql Replication
以下步骤在Node1上操作
1.增加一用于数据库同步的用户replicate
mysql -u root -p (执行后提示输入密码,正确输入mysql root用户密码后,登入mysql,以下操作在mysql命令行下进行)
mysql>GRANT REPLICATION SLAVE ON *.* TOreplicate@10.0.0.2IDENTIFIED BY 'password' ;
(授与从10.0.0.2主机上登录用户replicate数据复制权限,4.02版本以前用:GRANT FILE ON *.* TOreplicate@10.0.0.2IDENTIFIED BY 'password';)
mysql>flush privileges; (使权限生效,这步可不做,因为过会要重启mysql)
mysql>\q (退出mysql命令行界面)
2.停止mysql服务
service mysqld stop
3.更改Mysql配置文件/etc/my.cnf
vi /etc/my.cnf
在[mysqld]一节中增加以下内容
server-id=1 #服务器的标识 1~2^32-1,不同主机设为不同的值,否则可能会出现不可预料的错误
#以下内容为作为Master的配置,如果此服务器只作为Slave,注释掉以下各行
log-bin #允许二进制更新日志
binlog-do-db=dbname #指定做二进制更新日志的数据库,多个数据库用多条此语句,如,还有anotherdb,去掉下行的注释
#binlog-do-db=anotherdb
binlog-ignore-db=dbname #指明数据库dbname不做二进制更新日志,没有则注释掉此行,多个数据库用多条此语句,如,还有anotherigdb,去掉下行的注释
#binlog-ignore-db=anotherigdb
#以下内容为作为Slave的配置,如果此服务器只作为Master,注释掉以下各行
master-host=10.0.0.2 #Master服务器地址
master-user=replicate #Master服务器上用于replication的用户,必须有replication slave权限
master-password=replicatepass #Master服务器上用于replication的用户的密码
master-port=3306 #Master服务器的TCP端口
master-connect-retry=60 #如果连接Master服务器失败,重试连接的间隔,以秒为单位
replicate-do-db=dodbname #指明要复制的数据库,多个数据库用多条此语句,如,还有anotherdb,去掉下行的注释
#replicate-do-db=anotherdb
replicate-ignore-db=igdbname #指明不做复制的数据库,多个数据库用多条此语句,如,还有anotherigdb,去掉下行的注释
#replicate-ignore-db=anotherigdb
4.将要进行复制的数据库打包传到Node2
tar -cvf /tmp/mysql-thisdb-snapshot.tar /var/lib/mysql/thisdb (将要进行复制的thisdb数据库打包)
scp /tmp/mysql-thisdb-snapshot.tarroot@10.0.0.2:/tmp/ (将mysql-thisdb-snapshot.tar复制到Node2的/tmp目录)
5.启动Mysql
service mysqld start
至此,Node1上的Mysql设置完毕,以下操作在Node2上完成
1.增加一用于数据库同步的用户replicate
mysql -u root -p (执行后提示输入密码,正确输入mysql root用户密码后,登入mysql,以下操作在mysql命令行下进行)
mysql>GRANT REPLICATION SLAVE ON *.* TOreplicate@10.0.0.1IDENTIFIED BY 'password' ;
(授与从10.0.0.1主机上登录用户replicate数据复制权限,4.02版本以前用:GRANT FILE ON *.* TOreplicate@10.0.0.1IDENTIFIED BY 'password';)
mysql>flush privileges; (使权限生效,这步可不做,因为过会要重启mysql)
mysql>\q (退出mysql命令行界面)
2.停止mysql服务
service mysqld stop
3.更改Mysql配置文件/etc/my.cnf
vi /etc/my.cnf
在[mysqld]一节中增加以下内容
server-id=2 #服务器的标识 1~2^32-1,不同主机设为不同的值,否则可能会出现不可预料的错误
#以下内容为作为Master的配置,如果此服务器只作为Slave,注释掉以下各行
log-bin #允许二进制更新日志
binlog-do-db=dbname #指定做二进制更新日志的数据库,多个数据库用多条此语句,如,还有anotherdb,去掉下行的注释
#binlog-do-db=anotherdb
binlog-ignore-db=dbname #指明数据库dbname不做二进制更新日志,没有则注释掉此行,多个数据库用多条此语句,如,还有anotherigdb,去掉下行的注释
#binlog-ignore-db=anotherigdb
#以下内容为作为Slave的配置,如果此服务器只作为Master,注释掉以下各行
master-host=10.0.0.1 #Master服务器地址
master-user=replicate #Master服务器上用于replication的用户,必须有replication slave权限
master-password=replicatepass #Master服务器上用于replication的用户的密码
master-port=3306 #Master服务器的TCP端口
master-connect-retry=60 #如果连接Master服务器失败,重试连接的间隔,以秒为单位
replicate-do-db=dodbname #指明要复制的数据库,多个数据库用多条此语句,如,还有anotherdb,去掉下行的注释
#replicate-do-db=anotherdb
replicate-ignore-db=igdbname #指明不做复制的数据库,多个数据库用多条此语句,如,还有anotherigdb,去掉下行的注释
#replicate-ignore-db=anotherigdb
4.将先前从Node1上发过来的数据库的打包文件解压并替换掉原有文件,并确保属主及权限正确
cd /var/lib/mysql
tar -xvf /tmp/mysql-thisdb-snapshot.tar
chown -R mysql.mysql thisdb
chmod 700 thisdb
chmod 660 thisdb/*
5.启动Mysql
service mysqld start
至此Node2上的Mysql设置完毕
在Mysql中可通过以下命令来查看主从状态
show master status 查看master状态
show slave status 查看slave状态
show processlist \G 查看当前进程
stop slave 暂时停止slave进程
start slave 开始slave进程
其它相关命令及详细配置参数请自行查阅Mysql在线文档
四、安装配置Linux HA软件heartbeat
在每个节点上分别安装heartbeat
1.安装支持包(linux-ha.org站点提供下载)
Linux的版本不同,RPM文件名可能会不同,请选择相应版本的RPM
rpm -iUvh libnet-1.1.0-1.rh.el.1.i386.rpm
rpm -iUvh ipvsadm-1.21-1.rh.el.1.i386.rpm
rpm -iUvh perl-Parse-RecDescent-1.80-1.rh.el.um.1.noarch.rpm
rpm -iUvh perl-Mail-IMAPClient-2.2.7-1.rh.el.um.1.noarch.rpm
rpm -iUvh perl-Net-SSLeay-1.23-1.rh.el.um.1.i386.rpm
rpm -iUvh perl-Digest-SHA1-2.01-10.i386.rpm
rpm -iUvh perl-Digest-HMAC-1.01-11.noarch.rpm
rpm -iUvh perl-Authen-SASL-2.03-1.rh.el.um.1.noarch.rpm
rpm -iUvh perl-Convert-ASN1-0.16-2.rh.el.um.1.noarch.rpm
rpm -iUvh perl-IO-Socket-SSL-0.92-1.rh.el.um.1.noarch.rpm
rpm -iUvh perl-XML-NamespaceSupport-1.08-1.rh.el.um.1.noarch.rpm
rpm -iUvh perl-XML-SAX-0.12-1.rh.el.um.1.noarch.rpm
rpm -iUvh perl-ldap-0.2701-1.rh.el.um.1.noarch.rpm
2.按装heartbeat
以RPM方式按装(推荐),Linux的版本不同,RPM文件名可能会不同,请选择相应版本的RPM
rpm -iUvh heartbeat-pils-1.3.0-1.rh.el.3.0.i386.rpm
rpm -iUvh heartbeat-stonith-1.3.0-1.rh.el.3.0.i386.rpm
rpm -iUvh heartbeat-ldirectord-1.3.0-1.rh.el.3.0.i386.rpm
rpm -iUvh heartbeat-1.3.0-1.rh.el.3.0.i386.rpm
3.Copy配置文件到/etc/ha.d目录 (只在一个节点上做即可,所有配置完成后copy到其它节点)
cp /usr/share/doc/heartbeat-1.3.0/ha.cf /etc/ha.d/
cp /usr/share/doc/heartbeat-1.3.0/haresources /etc/ha.d/
cp /usr/share/doc/heartbeat-1.3.0/authkeys /etc/ha.d/
4.配置/etc/ha.d/ha.cf (只在一个节点上配即可,配好后copy到其它节点)
vi /etc/ha.d/ha.cf
按如下内容进行修改(文件中#开头的行为注释行,更多的选项及选项的详细说明请参考文件中的注释及相关文档)
debugfile /var/log/ha-debug #写debug信息到这个文件中
logfile /var/log/ha-log #写运行日志到这个文件中
keepalive 2 #设置心跳时间为2秒
deadtime 30 #设置离最近一次心跳多长时间没有心跳时表明节点失败
warntime 10 #设置离最近的一次心跳多长时间没有心跳时发出警告
initdead 120 #机器重启动或是刚开机时,网络能正确开始工作的时间,最小设置为deadtime的两倍
udpport 694 #bcast/ucast方式心跳通讯所用的UDP端口
#baud 19200 #串口的波特率,使用串口作心跳时需设置
#serial /dev/ttyS0 #串口设备名,使用串口作心跳时需设置
bcast eth1 #使用哪一个设备(网卡)做心跳
#bcast eth1 eth2 #使用多个设备(网卡)做心跳时的设置
auto_failback on #当主节点从失败状态恢复时是否恢复其主节点的身份,即应用是否返回到其自身运行
#on 返回
#off 不返回,其它节点继续作为主节点运行
#legacy 当所有节点都不支持自动返回时,将自身设为自动返回
node RHEL1 #节点的主机名或域名,需在/etc/hosts文件或
DNS服务器中设置
node RHEL2 #所有节点都以node开始的行列出
ping 192.168.168.254 #ping节点,不属于cluster内的节点,通常选一台路由器或交换机作为Ping节点,
#ipfail模块通过此节点来验证网络的连通性,可指定多个Ping节点,如:
#ping 192.168.168.253 192.168.0.254 ns1.rhel.com ping.linux-ha.org
respawn hacluster /usr/lib/heartbeat/ipfail #由heartbeat调用并监视ipfail模块
5.配置/etc/ha.d/haresources (只在一个节点上配即可,配好后copy到其它节点)
vi /etc/ha.d/haresources
按如下内容进行修改(文件中#开头的行为注释行,更多的选项及选项的详细说明请参考文件中的注释及相关文档)
RHEL1 192.168.168.103 mysqld #设置heartbeat管理的资源或服务
#格式为:主节点主机名或域名 浮动IP 服务名
#主节点主机名或域名为ha.cf中node行中指定的任一节点
#浮动IP 为对外提供访问的IP,主节点失败后会自动漂移到其它节点,继续对外提供服务.
#服务名 为 heartbeat管理的服务
#注意,此文件内容所有节点必须保持一致。
6.配置/etc/ha.d/authkeys (只在一个节点上配即可,配好后copy到其它节点)
vi /etc/ha.d/authkeys
按如下内容进行修改(文件中#开头的行为注释行,更多的选项及选项的详细说明请参考文件中的注释及相关文档)
auth 1 #设置认证方式
1 crc #格式为:auth <number>
#auth 2 # <number> <authmethod>
[<authkey>]
#2 md5 Hello! #如果是用心跳是用交叉线直接对连两个节点,用crc方式即可,CPU占用最少
#auth 3 #如果心跳位于不安全的网络,如通过共用交换机连接节点,则选用sha1或md5
#3 sha1 HI! #sha1占用CPU资源更多,但是更安全,md5安全性及CPU占用率居中
#sha1和md5都需要提供认证KEY,即用来加密的KEY
#注意,此文件权限必须设置为600
7.copy配置文件到其它节点
scp /etc/ha.d/ha.cf /etc/ha.d/haresources /etc/ha.d/authkeysroot@RHEL2:/etc/ha.d/
8.分别设置各节点/etc/ha.d/authkeys文件权限
chmod 600 /etc/ha.d/authkeys (文件权限必须设置为600,否则heartbeat不能正常启动)
9.在每个节点上启动heartbeat
service heartbeat start
五、测试
请自行模拟各种宕机情况,进行测试,这里不一一例举。
总结
此方案在Redhat Linux Enterprise Server 3.0 上测试通过,
其它系统请参照本文自行测试。(完)
2,启动中,通过ntpd进行时刻校正的同时,将各个客户端电脑的时刻也进行同期校正。
3,如果不能找到ntp服务器,那么就使用local time,同时同步客户。
全世界约有100多个ntp服务器,从下面地址找一个离你最近的
http://www.eecis.udel.edu/~mills/ntp/clock1a.html
我选择了两个
clock.nc.fukuoka-u.ac.jp 133.100.9.2 clock.tl.fukuoka-u.ac.jp 133.100.11.8
步骤:
FreeBSD中有两个标准的ntp程序,其一为ntpdate。
ntpdate通过从ntp服务器获取时刻,调整本地时刻。
# ntpdate clock.nc.fukuoka-u.ac.jp
9 Oct 18:12:23 ntpdate: step time server 133.100.9.2 offset -19.112674
大约有19秒钟的误差
自动设定
# grep ntpdate /etc/defaults/rc.conf >>/etc/rc.conf # vi /etc/rc.conf ntpdate_enable="YES" # Run ntpdate to sync time on boot (or NO). ntpdate_program="ntpdate" # path to ntpdate, if you want a different one. ntpdate_flags="clock.nc.fukuoka-u.ac.jp" # Flags to ntpdate (if enabled).
重新启动以后就运行了,当然设定没有完,不必急着启动
FreeBSD的另一个标准ntp程序,ntp
ntp程序使的获取ntp时刻的同时,向其他pc提供时刻。
添加文件ntp.conf:
用来作为标准时刻的ntp服务器我选择了两个
clock.nc.fukuoka-u.ac.jp 133.100.9.2 clock.tl.fukuoka-u.ac.jp 133.100.11.8
同时指定复数个服务器也没有问题,系统会自动选择一个可以信赖的。
这里,为避免多余的DNS数据包传递,我们直接指定IP地址。
server行 server 127.127.1.0 为参考本地时刻时用的地址。然后用fudge指定阶层编号为5,降低其优先度。
接着用restrict对每一个IP地址指定相应的规则。
最后,指定波长校正用的drift文档保存地址。关于这个命令行,具体的含义不太清楚。不过如果没有的话,时间校正起来就会比较慢
# vi /etc/ntp.conf server 133.100.9.2 #clock.nc.fukuoka-u.ac.jp server 133.100.11.8 #clock.tl.fukuoka-u.ac.jp server 127.127.1.0 fudge 127.127.0.1 stratum 5 restrict default ignore restrict 127.0.0.0 mask 255.0.0.0 restrict 192.168.1.0 mask 255.255.255.0 noquery nopeer notrust restrict 133.100.9.2 noquery restrict 133.100.11.8 noquery driftfile /etc/ntpd.drift
启动测试
# ntpd -p /var/run/ntpd.pid # tail /var/log/messages Oct 9 16:46:56 chiwawa ntpd[89409]: ntpd 4.1.0-a Thu Apr 3 08:26:24 GMT 2003 (1) Oct 9 16:46:56 chiwawa ntpd[89409]: kernel time discipline status 2040 ...... Oct 9 16:50:10 chiwawa ntpd[89409]: time set -0.189546 s
看到类似的结果就可以了。
运行测试
ntpd的运行用ntpq命令
# ntpq -p remote refid st t when poll reach delay offset jitter ============================================================================== *clock.nc.fukuok .GPS. 1 u 43 64 37 19.067 -6.884 10.339 +clock.tl.fukuok .GPS. 1 u 36 64 35 19.670 -3.259 2.341 LOCAL(0) LOCAL(0) 5 l 45 64 37 0.000 0.000 0.001
启动后到时刻校正完成需要一点时间。*是第一候补,+是第二。 本地时刻校正完成以后就可以为其他PC提供时刻校正服务了。
自动启动的设定
完成以上设定,确认运行无误以后:
# grep ntpd /etc/defaults/rc.conf >>/etc/rc.conf # vi /etc/rc.conf xntpd_enable="YES" # Run ntpd Network Time Protocol (or NO). xntpd_program="ntpd" # path to ntpd, if you want a different one. xntpd_flags="-p /var/run/ntpd.pid" # Flags to ntpd (if enabled).
往rc.conf追加上面3行内容,并修改。
客户端PC设定:
UNIX OS # vi /etc/ntp.conf server [local ntp server IP] prefer driftfile /etc/ntpd.drift
或者追加下面内容到crontab,这样,每过一个小时0分的时候就自动更新。
# vi /etc/crontab 0 * * * * root ntpdate [ntp server IP] >/dev/null 2>&1
当然,你的主机其实也是一个客户机,这些内容也可以用上。
Windows
精工的网站上有下载软件,不过是日语的
http://www.seiko-p.co.jp/systems/down/time.html
windows2000自带了sntp机能,请自己研究吧。
BBSURL:
0 - 5岁的时候女→妈妈。 男→妈妈。
6 - 10岁的时候 女→不是讨厌的男孩子就可以了! 男→可以陪我欺负女孩子的男孩。
11 - 15岁的时候 女→十五六七八岁的大哥哥,千万不要同年纪那班野蛮人! 男→足球,篮球,网球,乒乓球......
16 - 20岁的时候 女→我要十七八岁差不多年纪大家都称赞的「大帅哥」! 男→女人,女人就可以了!
21 - 25岁的时候 女→25-29岁的成熟男人,要有事业基础,有品味,才华...... 男→20-24岁漂亮又有身材的女人。 26 - 30岁的时候 女→仍是坚持要比自己年纪大的男人。 男→20-24岁漂亮又有身材的女人。
30 - 40岁的时候 女→心灵契合的好男人。 男→20-24岁漂亮又有身材的女人 4
0 - 50岁的时候 女→男人。 男→20-24岁漂亮又有身材的女人。
50 - 60岁的时候 女→可与他终老的男人。 男→20-24岁漂亮又有身材的女人。
70 - 80岁的时候 女→五六十岁时找到的那个男人,最好不需要自己照顾的。 男→20-24岁漂亮又有身材的女人。
80 - 90岁的时候 女→比自己迟死的男人。 男→虽然我已经老花眼,看不清楚......但是我还是希望是20-24岁......
