关于 MySQL 集群的 3 个主要组成部分,我们再来介绍一下。
(1)负载均衡节点(mysql)
负载均衡节点(也叫 SQL 节点)是用来 访问集群数据的。相关的软件,就是我们平时所使用的 MySQL 数据库软件;也就是由/etc/init.d/mysql 脚本来管理的那个服务。
(2)存储节点(ndbd)
数据存储节点是用来 保存集群数据的,其服务的启停是由脚本/etc/init.d/mysql-ndb来管理的
(3)管理节点(ndbd-mgm)
管理节点是用来 管理集群内其他节点的,比如提供配置信息、启动或停止节点、执行备份等。其服务的启停是由/etc/init.d/mysql-ndb-mgm 脚本来管理的。由于这类节点是管理者,所以管理节点必须首先启动,然后其他两类节点再启动。
实验环境
mysql-mgm.mytest.com:192.168.1.10,管理节点
mysql-lb1.mytest.com:192.168.1.11,负载均衡节点 1
mysql-lb2.mytest.com:192.168.1.12,负载均衡节点 2
mysql-data1.mytest.com:192.168.1.13,数据节点 1
mysql-data2.mytest.com:192.168.1.14,数据节点 2
此外,我们需要有一个虚拟 IP 地址,作为整个集群对外的一个 IP 地址;各种应用程序都通过该 IP 地址来访问 MySQL,并设置好以上服务器的 hostname 和 IP 地址
一、集群环境搭建
1.管理节点
sudo apt-get update install mysql-server
配置 ndb_mgmd.cnf,文件路径为/etc/mysql/ndb_mgmd.cnf
[NDBD DEFAULT]
NoOfReplicas=2
[MYSQLD DEFAULT][NDB_MGMD DEFAULT]
[TCP DEFAULT][NDB_MGMD] # 管理节点
HostName=192.168.1.10 # 本机(管理节点)的 IP 地址
[NDBD] # 存储节点 1
HostName=192.168.1.13
DataDir=/var/lib/mysql-cluster
BackupDataDir=/var/lib/mysql-cluster/backup
[NDBD] # 存储节点 2
HostName=192.168.1.14
DataDir=/var/lib/mysql-cluster
BackupDataDir=/var/lib/mysql-cluster/backup
# 有几个存储节点,就写几行[MYSQLD]
[MYSQLD]
[MYSQLD]
启动 MySQL 的 mgm 服务了
sudo /etc/init.d/mysql-ndb-mgm start
2. 数据节点
sudo apt-get update install mysql-server
sudo /etc/init.d/mysql stop //先停止mysql
配置/etc/mysql/my.cnf
[client]
socket = /var/run/mysqld/mysqld.sock
port = 3306
[mysqld]
ndbcluster
ndb-connectstring=192.168.1.10 # 管理节点的 IP 地址
default-storage-engine=NDBCLUSTER
[mysql_cluster]
ndb-connectstring=192.168.1.10 # 管理节点的 IP 地址
启动 ndb 服务
sudo /etc/init.d/mysql-ndb start-initial
ps aux|grep ndb|grep -v grep //查看 ndb 服务是否已经启动
sudo /etc/init.d/mysql start //启动 mysql 服务
管理节点上验证配置
$ ndb_mgm //进入 MGM 的客户端界面,quit退出客户端
ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=2 @192.168.1.13 (Version: 5.0.51, Nodegroup: 0)
id=3 @192.168.1.14 (Version: 5.0.51, Nodegroup: 0, Master)
[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.1.10 (Version: 5.0.51)
[mysqld(API)] 2 node(s)
id=4 @192.168.1.13 (Version: 5.0.51)
id=5 @192.168.1.14 (Version: 5.0.51)
在mysql-data1.mytest.com 节点上创建表
$ mysql -u root -p
mysql> CREATE DATABASE clustertest;
mysql> USE clustertest;
mysql> CREATE TABLE testtable (Count INT) ENGINE=NDBCLUSTER; //采用 NDBCLUSTER 作为数据库引擎
mysql> INSERT INTO testtable () VALUES (1);
在mysql-data2.mytest.com 节点上
$ mysql -u root -p
mysql> CREATE DATABASE clustertest;
mysql> USE clustertest;
mysql> SELECT * FROM testtable; //查询的为mysql-data1.mytest.com上插入的数据,2节点的数据也会同步到1节点
3. ndb 服务模拟故障
在 mysql-data1.mytest.com 上停止ndb 服务模拟故障:
$ sudo /etc/init.d/mysql-ndb stop // 停止ndb 服务,并插入一条数据
到管理节点 mysql-mgm.mytest.com 上确认
$ ndb_mgm
ndb_mgm> show
ndb_mgm> quit
此时在 mysql-data2.mytest.com 上还能查询testtable表的数据
在mysql-data1.mytest.com 上重新启动ndb 服务
sudo /etc/init.d/mysql-ndb start
登入数据库发现可以查询到刚刚插入的数据
二、负载均衡
1.ldirectord+heartbeat 介绍
到目前为止,“集群”本身已经安装好了。不过,这个集群还没有一个统一的对外 IP地址;所以,现在要使用该集群的话,你只能配置一部分程序使用 mysql-data1.mytest.com作为数据库服务器,另外一部分程序则使用 mysql-data2.mytest.com。这样做的坏处是,两台数据库服务器的工作量很难做到“平衡”。而且,最大的问题是:万一某台数据库服务器发生故障,会导致所有使用它的程序停止工作。解决该问题的方法,就是在数据库服务器的前面,放置“负载均衡”服务器。负载均衡服务器使用一个虚拟 IP 地址连接两台数据库服务器,所有应用程序都使用该虚拟 IP 地址作为数据库服务器地址。这样一来,即便某台数据库服务器宕机,也不会影响应用程序,只要有一台数据库服务器能正常工作,整个系统就不会停止运转。
不过,新的问题又来了。万一负载均衡服务器本身发生故障怎么办?那样岂不是整个系统就瘫痪了。是的,为了防止发生这种问题,我们需要配置两个负载均衡节点(它们分别是 mysql-lb1.mytest.com 和 mysql-lb2.mytest.com);它们以“主/从”模式配合工作,平时只有“主服务器”在工作,“从服务器”在待命;一旦“主服务器”宕机,“从服务器”马上进入工作状态。要实现负载均衡,所使用的主要软件有 heartbeat 和 ldirectord,下面我们来分别介绍。
ldirectord 的作用在 Apache 服务器的前端,我们要放置一台服务器专门来做负载调度的任务(为了称呼简单和便于理解,我们将这样的负载调度服务器简称为“导演”),用来把访问需求分发给两台 Apache 服务器。这个“导演”的任务,正是由 ldirectord 来完成的。
heartbeat 的核心功能有两个部分:心跳监测和资源接管。通过心跳监测,节点之间相互“打招呼”(发送报文)来告诉对方自己当前的状态;如果在指定的时间内没“听”到对方“打招呼”(没收到报文),那么就认为对方罢工了,这时 heartbeat 会自动启动资源接管模块,运行相关的 shell 脚本来接管运行在对方主机上的资源或者服务。
2、安装 heartbeat、ldirectord 等软件
下面我们来安装 heartbeat、ldirectord,以及要用到的其他软件。在 mysql-lb1.mytest.com
和 mysql-lb2.mytest.com 上,执行下面的命令:
$ sudo apt-get install heartbeat ldirectord
$ sudo apt-get install libdbi-perl libdbd-mysql-perl libmysqlclient15-dev
3.配置 heartbeat
调整两个负载均衡节点上的/etc/hosts 文件,将主机名写进去
127.0.0.1 localhost
192.168.1.11 mysql-lb1.mytest.com mysql-lb1
192.168.1.12 mysql-lb2.mytest.com mysql-lb2
创建/etc/ha.d/ha.cf
logfacility local0
bcast eth0
mcast eth0 225.0.0.1 694 1 0
auto_failback off
node mysql-lb1
node mysql-lb2
respawn hacluster /usr/lib/heartbeat/ipfail
apiauth ipfail gid=haclient uid=hacluster
创建/etc/ha.d/haresources
mysql-lb1
ldirectord::ldirectord.cf \
LVSSyncDaemonSwap::master \
IPaddr2::192.168.1.15/24/eth0/192.168.1.255
创建/etc/ha.d/authkeys
auth 3
3 md5 A46fsdgCH
4.配置 ldirectord
以下操作,在 mysql-lb1.mytest.com 和 mysql-lb2.mytest.com 上完全相同
创建/etc/ha.d/ldirectord.cf
# Global Directives
checktimeout=10
checkinterval=2
autoreload=no
logfile="local0"
quiescent=yes
virtual = 192.168.1.15:3306
service = mysql
real = 192.168.1.13:3306 gate
real = 192.168.1.14:3306 gate
checktype = negotiate
login = "ldirector"
passwd = "ldirectorpassword"
database = "ldirectordb"
request = "SELECT * FROM connectioncheck"
scheduler = wrr
在上面配置中,我们定义了虚拟 IP 地址为 192.168.1.15,端口为 3306(MySQL 的默认端口);两台真实服务器的 IP 地址分别为 192.168.1.13 和 192.168.1.14,端口都是 3306。还定义了一个用户 ldirector,密码为 ldirectorpassword,一个数据库 ldirectordb,一个 SQL
语句。ldirectord 将用这些信息来检测两台数据库服务器是否正常
禁止 ldirectord 服务自动启动(我们用 heartbeat 来控制 ldirectord 服务),然后修改 heartbeat 服务的启动顺序,让其推后启动,以等待其他服务先行启动
sudo update-rc.d -f ldirectord remove
sudo update-rc.d -f heartbeat remove
sudo update-rc.d heartbeat start 90 2 3 4 5 . stop 05 0 1 6 .
5.NDB 节点配置
1)为ldirector创建数据库
在 mysql-data1.mytest.com 上,创建该数据库
mysql> GRANT ALL ON ldirectordb.* TO 'ldirector'@'%' IDENTIFIED BY 'ldirectorpassw
ord';
mysql> FLUSH PRIVILEGES;
mysql> CREATE DATABASE ldirectordb;
mysql> USE ldirectordb;
mysql> CREATE TABLE connectioncheck (Status INT) ENGINE=NDBCLUSTER;
mysql> INSERT INTO connectioncheck () VALUES (1);
mysql> quit
然后,在 mysql-data2.mytest.com 上创建该数据库,数据会自动从 mysql-data1 上复制过来
mysql> GRANT ALL ON ldirectordb.* TO 'ldirector'@'%' IDENTIFIED BY 'ldirectorpassw
ord';
mysql> FLUSH PRIVILEGES;
mysql> CREATE DATABASE ldirectordb;
mysql> quit
3)设置 IP 路由
我们需要让两台数据库服务器 mysql-data1.mytest.com 和 mysql-data2.mytest.com 能够通过虚拟 IP 地址 192.168.1.15 连接起来
sudo apt-get install iproute //安装 iproute 软件包
/etc/sysctl.conf中加入以下内容,并使其生效sudo sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.eth0.arp_announce = 2
4)设置虚拟 IP 地址
在 mysql-data1 和 mysql-data2 上分别修改/etc/network/interfaces,添加虚拟 IP 地址,并启用sudo ifup lo:0
auto lo:0
iface lo:0 inet static
address 192.168.1.15
netmask 255.255.255.255
pre-up sysctl -p > /dev/null
6.测试
启动负载均衡服务,在 mysql-lb1.mytest.com 和 mysql-lb2.mytest.com 上,执行下列命令。执行完毕进行reboot重启
sudo /etc/init.d/ldirectord stop
sudo /etc/init.d/heartbeat start
1)ldirectord 状态检查
在 mysql-lb1 和 mysql-lb2 上,执行下面的命令,并检查虚拟IP
$ ldirectord ldirectord.cf status
在 mysql-lb1 上,其输出应为:
ldirectord for /etc/ha.d/ldirectord.cf is running with pid: 4584
在 mysql-lb2 上,其输出应为:
ldirectord is stopped for /etc/ha.d/ldirectord.cf
2)IPVS 状态检查
sudo ipvsadm -L -n
在 mysql-lb1 上,其输出应为:
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.15:3306 wrr
-> 192.168.1.13:3306 Route 1 0 0
-> 192.168.1.14:3306 Route 1 0 0
在 mysql-lb2 上,其输出应为:
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
sudo /etc/ha.d/resource.d/LVSSyncDaemonSwap master status
在 mysql-lb1 上,其输出应为:
master running
(ipvs_syncmaster pid: 4704)
在 mysql-lb2 上,其输出应为:
master stopped
(ipvs_syncbackup pid: 1440)
3)结果测试
mysql测试
在 192.168.1.0 网络内的某台机器上,通过虚拟 IP 地址 192.168.1.15 连接我们的负载均衡服务器试试看:
$ mysql -h 192.168.1.15 -u ldirector -p
负载均衡测试
将 mysql-lb1 服务器上的 heartbeat服务停掉,这时从 ping 命令的输出看,应该 ping 不到 192.168.1.15,几秒钟后,又能够重新 ping 到 192.168.1.15(说明 mysql-lb2 成功地接替 mysql-lb1,进入工作状态了)