哎,我的毕业报告本来写的是高可用加负载均衡的WEB集群,但是呢,因为写这个了太多了。老师说比较雷同,所以就苦了除第一个让老师看其报告的其他人了,不幸的是我恰恰在其他人之列。所以呢,我又重新写了份报告,而这份报告就是本博客了题目了。呵呵
本着分享的原则,拿出报告中的分析、设计与实现部分来与大家共同分享。由于经验和知识的不足,很多地方可能有错误和不足的地方,还请大家指出来。为了使这篇博客看起来比较完整,有些内容在以前的博客中也有涉及,不过,这里全部写出来了。
第1章 数据库分析与设计
随着信息技术的发展,人类社会经济呈现明显的数据和信息密集型的特征,大量的信息数据被存储于数据库并广泛应用于各种信息系统,而且对于这些数据,企业十分需要连续访问这些关键的信息数据。而且对于这些数据的安全性,要求也高,为了保证数据的安全性,要及时的备份,而由于我们要求提供服务的服务器要时时刻刻在线,所以对于备份来说有一定的难度,所以我们采用数据库的主从复制架构来实现主从服务器的数据同步复制,并通过从服务器来进行备份。
1.1 数据库
在当下,比较流行的关系型数据库就数Oracle和MySQL等数据库了。而前者是商业软件,需要一笔相当不菲的费用,而后者虽然被Oracle收购了,但是其还是开源产品,而且,网络上对MySQL进行支持的社区还是很多的。据说MySQL的性能在某些方面比Oracle数据的性能还要好。所以在选择数据库方面,我们采用MySQL数据库来实现数据库系统架构的完成。
1.1.1 MySQL数据库介绍
MySQL是一个小型关系型数据库管理系统,开发者为瑞典MySQL AB公司。在2008年1月16号被Sun公司收购。而2009年,SUN又被Oracle收购。MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内。这样就增加了速度并提高了灵活性。MySQL的SQL“结构化查询语言”。SQL是用于访问数据库的最常用标准化语言。MySQL软件采用了GPL(GNU通用公共许可证)。由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。
MySQL最初的开发者的意图是用mSQL和他们自己的快速低级例程(ISAM)去连接表格。经过一些测试后,开发者得出结论:mSQL并没有他们需要的那么快和灵活。这导致了一个使用几乎和mSQL一样的API接口的用于他们的数据库的新的SQL接口的产生,这样,这个API被设计成允许为用于mSQL而写的第三方代码更容易移植到MySQL。
系统特性:
Ø 使用C和C++编写,并使用了多种编译器进行测试,保证源代码的可移植性
Ø 支持AIX、FreeBSD、HP-UX、Linux、Mac OS、NovellNetware、OpenBSD、OS/2 Wrap、Solaris、Windows等多种操作系统
Ø 为多种编程语言提供了API。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等
Ø 支持多线程,充分利用CPU资源
Ø 优化的SQL查询算法,有效地提高查询速度
Ø 既能够作为一个单独的应用程序应用在客户端服务器网络环境中,也能够作为一个库而嵌入到其他的软件中提供多语言支持,常见的编码如中文的GB 2312、BIG5,日文的Shift_JIS等都可以用作数据表名和数据列名
Ø 提供TCP/IP、ODBC和JDBC等多种数据库连接途径
Ø 提供用于管理、检查、优化数据库操作的管理工具
Ø 可以处理拥有上千万条记录的大型数据库
Ø 支持多种存储引擎
1.2 数据库架构设计
MySQL高可用集群大致分为两层:第一层:主MySQL服务器,并利用corosync+pacemaker+drbd对其做高可用;第二层:从MySQL服务器层,在这一层架设多个MySQL从服务器。当主服务器中有一个故障的时候,服务会自动转移到备用节点上,从服务器的复制源也改向备用节点上。
1.2.1规划图
图1-1 逻辑示意图
数据库集群通过交换机互联起来,上面两台服务器作为主MySQL服务器,并对其做高可用,即只有一台工作,当其中一台出现故障的时候,自动切换到另外一台,继续提供服务。并且使用VIP来提供服务。下面两个是两个从服务器,从服务器从正在提供服务的服务器复制数据,当正在提供服务的数据库服务器出现故障的时候,从服务器会自动转到另外一台提供服务的服务器上,继续复制数据。
1.2.2 IP地址规划
IP地址规划如表1-1所示:
表1-1 IP地址规划
服务器 |
IP |
主机名 |
node1 |
IP:192.168.1.111 |
node1.mysql.com |
VIP:192.168.1.110 |
||
node2 |
IP:192.168.1.112 |
node2.mysql.com |
VIP:192.168.1.110 |
||
rp1 |
IP:192.168.1.113 |
rp1.mysql.com |
rp2 |
IP:192.168.1.114 |
rp2.mysql.com |
第2章 实现与测试
本部分将按上面分的层次分别实现,并对其进行必要的测试。网站的构建采用的是Linux操作系统,为什么采用Linux系统作为服务器的理由就不多说了,你懂的。我们采用的是RedHat发行版的Linux----RHEL5.4_x86系统上构建。
2.1 建立双机互信
2.1.1 node1的配置
1、生成一对密钥:(私钥).ssh/id_rsa,.ssh/id_rsa.pub
- [root@node1 ~]# ssh-keygen -t rsa
2、把公钥.ssh/id_rsa.pub复制到Slave Director的root用户的家目录下的.ssh目录中的authorized_keys文件中去
- [root@node1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
2.1.2 node2的配置
1、生成一对密钥:(私钥).ssh/id_rsa,.ssh/id_rsa.pub
- [root@node2 ~]# ssh-keygen -t rsa
2、把公钥.ssh/id_rsa.pub复制到Master Director的root用户的家目录下的.ssh目录中的authorized_keys文件中去
- [root@node2 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
3、所有服务器的/etc/hosts文件添加如下内容:
- 192.168.1.111 node1.mysql.com node1
- 192.168.1.112 node2.mysql.com node2
- 192.168.1.113 rp1.mysql.com rp1
- 192.168.1.114 rp2.mysql.com rp2
2.2 DRBD的实现
2.2.1 安装DRBD软件包
1、软件包从http://mirrors.sohu.com/centos/5.6/extras/i386/RPMS/获取,这里我使用的是drbd83-8.3.8-1.el5.centos.i386.rpm、kmod-drbd83-8.3.8-1.el5.centos.i686.rpm两个软件包。
配置好yum源,然后在连个节点上执行下列命令:
- [root@node1 ~]# yum –y –nogpgcheck localinstall kmod-drbd83-8.3.8-1.el5.centos.i686.rpm drbd83-8.3.8-1.el5.centos.i386.rpm
2.2.2 创建磁盘分区
- [root@node1 ~]#fdisk /dev/sda #创建过程如图2-1所示
图2-1 磁盘分区创建
2.2.3 配置DRBD
下面操作在node1.mysql.com上完成。
1、复制样例配置文件为即将使用的配置文件:
- [root@node1 ~]#cp /usr/share/doc/drbd83-8.3.8/drbd.conf /etc
2、配置/etc/drbd.d/global-common.conf文件
- [root@node1 ~]#vim /etc/drbd.d/global-common.conf
- global {
- usage-count no;
- # minor-count dialog-refresh disable-ip-verification
- }
- common {
- protocol C;
- handlers {
- 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";
- }
- startup {
- wfc-timeout 120;
- degr-wfc-timeout 240;
- }
- disk {
- on-io-error detach;
- }
- net {
- cram-hmac-alg "sha1";
- shared-secret "askjfldeoir";
- }
- syncer {
- rate 1000M;
- }
- }
3、定义一个资源/etc/drbd.d/mysql.res
- [root@node1 ~]#vim /etc/drbd.d/mysql.res
- resource mysql {
- on node1.mysql.com {
- device /dev/drbd0;
- disk /dev/sda3;
- meta-disk internal;
- address 192.168.1.111:7789;
- }
- on node2.mysql.com {
- device /dev/drbd0;
- disk /dev/sda3;
- meta-disk internal;
- address 192.168.1.112:7789;
- }
- }
将所有的修改配置同步到node2上:
- [root@node1 ~]#scp –r /etc/drbd.* node2:/etc
4、在两个节点上初始化已定义的资源并启动服务:
初始化资源,在node1和node2上分别执行:
- [root@node1 ~]#drbdadm create-md mysql
分别在node1和node2上启动drbd服务:
- [root@node1 ~]#service drbd start
查看启动状态,如图2-2所示:
图2-2 drbd启动状态
从上面的信息中可以看出此时两个节点均处于Secondary状态。于是,我们接下来需要将node1设置为Primary。在要设置为Primary的节点上执行如下命令:
- [root@node1 ~]#drbdadm -- --overwrite-data-of-peer primary mysql
而后再次查看其状态,可以发现数据同步过程已经开始,如图2-3所示:
图2-3 数据同步过程
5、创建文件系统
当同步完成后,节点之间有了主次之分,而且文件系统的挂载只能在Primary节点进行,因此,也只有在设置了主节点后才能对drbd设备进行格式化:
- [root@node1 ~]#mke2fs –j /dev/drbd0
2.3 MySQL
安装mysql有三种方式:rpm包安装、源代码包安装、类似绿色软件的安装。这里我们使用第三种方式安装mysql,直接解压并初始化就可以运行了。另外安装的mysql版本需要与系统平台对应,我所使用的是32位平台,因此选择的软件包是:mysql-5.5.22-linux2.6-i686.tar.gz。
注:MySQL从服务器的MySQL数据库版本必须与主服务器的版本相同或更新,因为软件一般都是向下兼容的,如果主服务器的版本比从服务器的高,可能某些特性无法使从服务器识别,从而导致数据的不一致现象,这种事情是不应该也不允许发生的。
除了node2的MySQL数据库不用初始化之外,其它所有的安装,配置过程都相同。node2之所以不需要初始化,是因为在node1上已经初始化之后,数据会自动同步到node2的drbd分区上。
2.3.1 为数据库创建文件系统
在3.1中我们已经在node1上创建好了文件系统,这里我们直接使用(注:从服务器上的磁盘分区需要事先创建好)
- [root@node1 ~]#mkdir /mysql #创建挂载点
- [root@node1 ~]#mount /dev/drbd0 /mysql
- [root@node1 ~]#mkdir /mysql/data #创建mysql数据的存放目录
2.3.2 为mysql数据库新建用户
- [root@node1 ~]#groupadd –r mysql
- [root@node1 ~]#groupadd –g mysql –r –s /sbin/nologin –M mysql
- [root@node1 ~]#chown –R mysql:mysql /mysql/data
2.3.3 安装mysql-5.5.22
- [root@node1 ~]#tar xf mysql-5.5.22-linux2.6-i686.tar.gz –C /usr/local
- [root@node1 local]#cd /usr/local/
- [root@node1 local]#ln –sv mysql-5.5.22-linux2.6-i686 mysql
- [root@node1 mysql]#cd mysql
- [root@node1 mysql]#chown –R mysql:mysql . #初始化mysql数据库的时候需要将所有文件改为mysql组mysql用户
- [root@node1 mysql]#scripts/mysql_install_db --user=mysql --datadir=/mysql/data #初始化mysql数据库(注:node2不需要执行此步骤
- [root@node1 mysql]#chown –R root . #将文件的属主再改为root
2.3.4 配置Mysql
1、为mysql提供主配置文件:
- [root@master mysql]#cp support-files/my-large.cnf /etc/my.cnf
修改/etc/my.cnf配置文件,将thread_concurrency的值改为我们主机CPU个数的2倍,这样既可以有效的利用CPU,又不至于是CPU的负荷过大,编辑配置文件,如下:
- [root@node1 ~]#vim /etc/my.cnf
- thread_concurrency = 2
- datadir = /mysql/data #指定mysql数据文件的存放位置
2、添加SysV服务脚本,执行下列命令:
- [root@node1 mysql]#cd /usr/local/mysql
- [root@node1 mysql]#cp support-files/mysql.server /etc/rc.d/init.d/mysqld
- [root@node1 ~]#chkconfig –add mysqld
- [root@node1 ~]#chkconfig mysqld on
- [root@node1 ~]#service mysqld on
3、为了使mysql的安装符合系统的使用规范,我们还需要进行如下步骤:
- [root@node1 ~]#vim /etc/man.config #导出帮助文档
- MANPATH /usr/local/mysql/man
- [root@node1 ~]#ln –sv /usr/local/mysql/include /usr/include/mysql #导出头文件
- [root@node1 ~]#echo '/usr/local/mysql/lib' > /etc/ld.so.conf.d/mysql.conf #导出库文件
- [root@node1 ~]#ldconfig
- [root@node1 ~]#vim /etc/profile #导出命令
- PATH=$PATH:/usr/local/mysql/bin
- [root@master ~]#. /etc/profile #使修改的配置文件生效
4、为数据库中的root设置密码:
- [root@node1 ~]#mysqladmin -uroot -hlocalhost -p password '1234567'
2.4 MySQL数据库的高可用配置
2.4.1 安装corosync及相关软件包
- cluster-glue-1.0.6-1.6.el5.i386.rpm
- cluster-glue-libs-1.0.6-1.6.el5.i386.rpm
- corosync-1.2.7-1.1.el5.i386.rpm
- corosynclib-1.2.7-1.1.el5.i386.rpm
- heartbeat-3.0.3-2.3.el5.i386.rpm
- heartbeat-libs-3.0.3-2.3.el5.i386.rpm
- libesmtp-1.0.4-5.el5.i386.rpm
- pacemaker-1.1.5-1.1.el5.i386.rpm
- pacemaker-cts-1.1.5-1.1.el5.i386.rpm
- pacemaker-libs-1.1.5-1.1.el5.i386.rpm
- perl-TimeDate-1.16-5.el5.noarch.rpm
- resource-agents-1.0.4-1.1.el5.i386.rpm
获取这些软件包后执行下面命令(注:这些软件包都放在root用户的家目录下了,软件包见附件):
- [root@node1 ~]# yum -y --nogpgcheck localinstall *.rpm
2.4.2 配置corosync
编辑corosync的主配置文件corosync.conf
- [root@node1 ~]# cd /etc/corosync/
- [root@node1 corosync]# cp corosync.conf.example corosync.conf
- [root@node1 corosync]# vim corosync.conf :添加如下内容
- service {
- ver: 0
- name: pacemaker
- }
- aisexec {
- user: root
- group: root
- }
另外,设定此配置文件中 bindnetaddr后面的IP地址为你的网卡所在网络的网络地址,我们这里的两个节点在192.168.0.0网络,因此这里将其设定为192.168.0.0;如下
- bindnetaddr: 192.168.0.0
生成节点间通信时用到的认证密钥文件:
- [root@node1 corosync]# corosync-keygen
将corosync.conf和authkey复制至node2
- [root@node1 corosync]# scp corosync.conf authkey node2:/etc/corosync/
分别为两个节点创建corosync生成的日志所在的目录
- [root@node1 ~]# mkdir /var/log/cluster
- [root@node1 ~]# ssh node2 'mkdir /var/log/cluster'
启动corosync(以下命令在node1上执行)
- [root@node1 ~]# service corosync start
验证corosync引擎是否正常启动,如图2-4所示:
图2-4 corosync状态
验证初始化成员节点通知是否正常发出,如图2-5所示:
图2-5 节点信息
验证pacemaker是否正常启动,如图2-6所示:
图 2-6 pacemaker启动
从以上验证中,可以看出没有问题,然后执行下列命令,启动node2上的corosync
- [root@node1 ~]# ssh node2 -- /etc/init.d/corosync start
2.4.3 定义集群资源
1、在定义集群资源之前,先将所有要定义为资源的服务设置为开机不自动启动,node1和node2命令相同:
- [root@node1 ~]#chkconfig drbd off
- [root@node1 ~]#chkconfig mysqld off
- [root@node1 ~]#service drbd stop
- [root@node1 ~]#service mysqld stop
2、定义高可用集群资源
- [root@node1 ~]#crm configure
- crm(live)configure#property stonith-enabled=false
- crm(live)configure#property no-quorum-policy=ignore
- crm(live)configure#primitive drbd ocf:linbit:drbd params drbd_resource="mysql" \
- op monitor interval="29s" role="Master" \
- op monitor interval="31s" role="Slave" \
- op start interval="0" timeout="240s" \
- op stop interval="0" timeout="100s"
- crm(live)configure#ms ms_drbd drbd meta master-max="1" master-node-mas="1" clone-mas="2" clone-node-max="1" notify="true"
- crm(live)configure# primitive fs ocf:heartbeat:Filesystem \
- params device="/dev/drbd0" directory="/mysql" fstype="ext3" \
- op start interval="0" timeout="60s" \
- op stop interval="0" timeout="60s"
- crm(live)configure#primitive myip ocf:heartbeat:IPaddr \
- params ip="192.168.1.110"
- crm(live)configure#primitive mysql lsb:mysqld
- crm(live)configure#group mysqlservice fs myip mysql
- crm(live)configure#colocation fs_with_drbd inf: mysqlservice ms_drbd:Master
- crm(live)configure#colocation mysql_with_ms_drbd inf: mysql ms_drbd:Master
- crm(live)configure#order fs_after_drbd inf: ms_drbd:promote mysqlservice:start
- crm(live)configure#order mysql_after_fs inf: fs:start mysql:start
- crm(live)configure#verify
- crm(live)configure#commit
2.4.4 验证
1、首先验证在crm中定义的集群资源是否成功,如图2-7所示:
图2-7 集群资源
如图所示,可以看出资源定义已经成功。
2、验证服务是否启动成功,如图2-8所示:
图2-8 服务启动
从图中可以看出服务已经在node1上启动。
3、查看当node1现故障的时候,服务是否自动转移到node2上,如图2-9,2-10所示:
如图2-9是两个节点正常的时候,服务在node1上运行。
图2-9 node1为主节点服务启动对比
如图2-10,模拟node1出现故障,node1上的服务马上停止,并转移到node2上:
图2-10 node2为主节点服务启动对比
由此可见,对主MySQL服务器的高可用配置已经成功。
2.5 MySQL主从配置
由于所有的MySQL从服务器的配置都相同,所以,下面所提到的MySQL从服务器的配置是在rp1上进行的。
2.5.1 主MySQL服务器配置
1、登陆MySQL数据库,为从服务器创建用户账户(在node1上进行配置):
- mysql> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO replay@'192.168.1.113' IDENTIFIED BY '1234567';
- mysql> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO replay@'192.168.1.114' IDENTIFIED BY '1234567';
- mysql>FLUSH PRIVILEGES;
复制需要REPLICATION CLIENT权限;监视和管理复制需要REPLICATION SLAVE权限。
2、查看下二进制日志的信息,如图2-11所示:
图 2-11 二进制日志信息
2.5.2 从MySQL服务器配置
1、编辑/etc/my.cnf配置文件
rp1服务器上的配置:
- #log_bin = mysql-bin #关闭二进制日志
- server-id = 10
- relayrelay_log = relay-bin #开启中继日志
rp2服务器上的配置:
- #log_bin = mysql-bin #关闭二进制日志
- server-id = 20
- relayrelay_log = relay-bin #开启中继日志
注:从服务器的server-id的值必须不能与主服务器的相同。
2、下面操作是在rp1服务器上完成的,登陆MySQL数据库,执行下列命令
- mysql> CHANGE MASTER TO
- -> MASTER_HOST='192.168.1.110',
- -> MASTER_USER='replay',
- -> MASTER_PASSWORD='1234567',
- mysql>START SLAVE;
2.5.3 MySQL的测试与验证
1、在rp1从服务器上使用下面命令查看状态信息,如图2-12所示
- mysql>SHOW SLAVE STATUS\G
图2-12 从服务器状态图
如图,如果Slave_IO_Running与Slave_SQL_Running状态为Yes,说明MySQL主从服务器配置正常
2、测试数据是否可以同步
首先,在node1主服务器上创建一个数据库,如图2-13所示:
图2-13 主服务器创建数据库
从服务器上查看数据库信息,如图2-14所示
图2-14 从服务器数据库信息
从图2-12、图2-13以及图2-14可以看出MySQL主从服务器配置成功,且能实现数据同步,至此,MySQL主从服务器配置宣告结束。
到此为止,一个高可用的MySQL数据库集群就构建完毕了。