构建MySQL集群
一、目标
1.安装MySQL-Cluster相关软件包。
2.依次配置管理/数据/SQL节点。
3.启动并测试MySQL-Cluster集群架构。
二、方案
使用6台RHEL 6.5虚拟机,如图所示。其中sql1和sql2作为SQL节点,ndb1和ndb2作为数据节点,mgmsvr作为管理节点,这5个节点构成MySQL Cluster体系;而另一台虚拟机192.168.4.1作为测试客户机。
构成MySQL集群体系的5个节点应安装Cluster版的MySQL相关软件包;测试用的Linux客户机只需安装普通版的MySQL-client即可。
三、实现
1、准备工作
1)确认各节点服务器的IP地址,使各节点能互通,防火墙和selinux处于关闭状态。
关闭防火墙:
# iptables -F //清空防火墙条目
# service iptables stop //关闭防火墙
# chkconfig iptables off //开机不自启
关闭selinux:
vim打开 /etc/selinux/config修改SELINUX=disabled
# getenforce 0
2)卸载所有节点上的冲突包
官方提供的MySQL-Cluster相关软件包(可在这里获得 http://pan.baidu.com/s/1sjsILAX)已集成数据库服务端/客户端程序,因此可直接用来替换普通的MySQL服务端/客户端程序。如果已安装有普通版的mysql-server、mysql、MySQL-server、MySQL-client包,先将其卸载(若没有则忽略):
# rpm -qa | grep -i mysql //检查有没有安装普通版的mysql软件
对于RHEL自带的mysql-libs暂时保留(如果直接卸载会因为依赖关系删除许多重要的包,比如crontab、postfix等),但在安装MySQl-Cluster相关包的时候采用“-U”升级的方式执行替换。
# rpm -e --nodeps MySQL-client
如果有残留的/etc/my.cnf文件,确保已转移备用或直接删除。
# mv /etc/my.cnf /etc/my.cnf.bak
3)在所有节点上,解压下载的MySQL-Cluster集合包
# tar xvf MySQL-Cluster-gpl-7.3.3-1.el6.x86_64.rpm-bundle.tar
MySQL-Cluster-shared-gpl-7.3.3-1.el6.x86_64.rpm
MySQL-Cluster-shared-compat-gpl-7.3.3-1.el6.x86_64.rpm //安装共享库和兼容包
MySQL-Cluster-server-gpl-7.3.3-1.el6.x86_64.rpm //安装服务端程序
MySQL-Cluster-client-gpl-7.3.3-1.el6.x86_64.rpm //安装客户端程序
MySQL-Cluster-test-gpl-7.3.3-1.el6.x86_64.rpm
MySQL-Cluster-devel-gpl-7.3.3-1.el6.x86_64.rpm
MySQL-Cluster-embedded-gpl-7.3.3-1.el6.x86_64.rpm
在SQL节点(sql1、sql2)服务器上,修改MySQL数据库的root密码:
[root@sql1 ~]# service mysql start //启动MySQL服务程序
Starting MySQL... [确定]
[root@sql2 ~]# cat /root/.mysql_secret
# The random password set for the root user at Wed Sep 3 21:04:20 2014 (local time): msA7Bq2B
[root@sql1 ~]# mysql �Cu root �CpmsA7Bq2B //以上述默认密码登录
mysql> set password=password("123456");
Query OK, 0 rows affected (0.17 sec)
在数据节点(ndb1、ndb2)和管理节点(mgmsvr)上,实际上并不需要启动MySQL服务程序,因此建议将mysql服务的自启状态设为关闭
[root@ndb1 ~]# chkconfig mysql off
4)在sql节点添加授权数据库用户
在SQL节点(sql1、sql2)服务器上,添加相应的授权数据库用户,以方便客户端使用数据库服务。以用户user为例,允许其从192.168.4.0/24网段访问:
mysql> grant all on *.* to user@'192.168.4.%' identified by "123456";
Query OK, 0 rows affected (0.03 sec)
2、配置管理节点mgmsvr(192.168.4.3)
1)创建工作文件夹
为管理节点提供一个工作目录,方便记录mysql集群相关的日志消息:
[root@mgmsvr ~]# mkdir /var/log/mysql-cluster
2)创建配置文件
在管理节点的配置文件中,应涵盖所有节点的设置,主要包括各节点的ID号、主机名或IP地址、工作目录等信息。
针对本实验,管理节点的配置参考如下:
[root@mgmsvr ~]# cat /etc/config.ini //文件名可以随意
[ndbd default] //为所有的节点指定默认配置
NoOfReplicas=2//保留2份数据拷贝
DataMemory=80M//数据缓存大小
IndexMemory=18M//索引缓存大小
[ndb_mgmd]//指定一个管理节点的配置,可以有多个管理节点
nodeid=3//节点的id号,作为节点的唯一识别码,不可以与其他节点相同
hostname=192.168.4.3 //节点的ip地址
datadir=/var/log/mysql-cluster //该管理节点的工作目录
[ndbd]//指定数据节点的配置,每个数据节点对应一个ndbd配置
nodeid=4
hostname=192.168.4.4
datadir=/var/log/mysql-cluster/data
[ndbd]
nodeid=5
hostname=192.168.4.5
datadir=/var/log/mysql-cluster/data
[mysqld]//指定SQL节点的配置,每个SQL节点对应一个配mysqld置
nodeid=6
hostname=192.168.4.6
[mysqld]
nodeid=7
hostname=192.168.4.7
3、配置数据节点,分别在ndb1 (192.168.4.4)、ndb2(192.168.4.5)上做下面的操作
1)创建工作文件夹
为各数据节点提供一个工作目录,用来存放实际的数据库表记录等相关数据:
[root@ndb1~]# mkdir -p /var/lib/mysql-cluster/data
2)创建配置文件
指定一个数据存储目录,管理服务器的IP地址、采用ndbcluster存储引擎,以便支持集群特性;并添加[mysql_cluster]配置段,同样指定管理地址。
针对本实验,2个数据节点的配置参考如下:
[root@ndb1 ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/log/mysql-cluster/data //指定数据存储目录
ndb-connectstring=192.168.4.3 //要连接的管理服务器的ip地址
Ndbcluster//指定运行的存储引擎
[mysql_cluster]//集群连接配置
ndb-connectstring=192.168.4.3 //管理服务器的地址
4、配置SQL节点,分别在sql1(192.168.4.6)、sql2(192.168.4.7)上做下面的操作
调整my.cnf配置,指定运行的存储引擎、默认存储引擎,并通过[mysql_cluster]配置段指定管理地址。在MySQL-Cluster集群环境中,若某个数据库未采用ndbcluster引擎(而是InnoDB、MyISAM等其他引擎),则当更新数据库表时,可能无法同步到其他节点。
[root@sql1 ~]# cat /etc/my.cnf
[mysqld]
ndbcluster //指定运行的存储引擎
default-storage-engine=ndbcluster //指定默认的存储引擎
[mysql_cluster]
ndb-connectstring=192.168.4.3 //管理服务器的地址
5、启动MySQL集群
正确的启动顺序:管理节点 --> 数据节点 --> SQL节点。
关闭顺序:SQL节点 --> 数据节点 --> 管理节点。
1)启动管理节点
MySQL Cluster管理节点的对应服务程序为ndb_mgmd,通过选项-f指定建立的集群配置文件。
[root@mgmsvr ~]# ndb_mgmd -f /etc/config.ini
关于管理节点的启动,有以下几个需要注意的地方:
ndb_mgmd默认以后台模式运行(--daemon),调试过程中可添加选项--nodaemon来禁用后台模式。
ndb_mgmd初次启动成功以后,会自动保存集群配置,以后再启动时会忽略-f指定的配置文件,除非添加--initial选项(比如向集群中添加新的节点时,就应该重新初始化)。
若希望每次开机后自动运行ndb_mgmd,可将上述启动操作写入到/etc/rc.local配置文件内,例如:
[root@mgmsvr ~]# cat /etc/rc.local
.. ..
ndb_mgmd -f /etc/my-cluster.ini
启动完成后查看监听状态:
[root@svr3 ~]# netstat -anpt | grep ndb
tcp 0 0 0.0.0.0:1186 0.0.0.0:* LISTEN 3809/ndb_mgmd
tcp 0 0 127.0.0.1:1186 127.0.0.1:54902 ESTABLISHED 3809/ndb_mgmd
tcp 0 0 127.0.0.1:54902 127.0.0.1:1186 ESTABLISHED 3809/ndb_mgmd
2)启动数据节点ndb1、ndb2
MySQL Cluster数据节点的对应服务程序为ndbd(单线程的)、ndbmtd(多线程的),首次启动或重新初始化时加 --initial选项,以后不用加。
启动ndb1:
[root@ndb1 ~]# ndbd --initial
2014-09-05 20:15:17 [ndbd] INFO -- Angel connected to '192.168.4.3:1186'
2014-09-05 20:15:17 [ndbd] INFO -- Angel allocated nodeid: 4
启动ndb2;
[root@ndb2 ~]# ndbd --initial
2014-09-05 20:15:44 [ndbd] INFO -- Angel connected to '192.168.4.3:1186'
2014-09-05 20:15:44 [ndbd] INFO -- Angel allocated nodeid: 5
在ndb1和ndb2服务器上,修改/etc/rc.local配置文件,以便每次开机后能自动启动数据节点服务:
[root@ndb1 ~]# cat /etc/rc.local
.. ..
ndbd
3)启动SQL节点sql1、sql2
对于MySQL Cluster的SQL节点来说,对应的服务程序就是mysqld,正常通过mysql脚本重新启动服务就可以了。启动sql1:
[root@sql1~]# service mysql restart
Shutting down MySQL..... SUCCESS!
Starting MySQL................................ SUCCESS!
[root@sql1~]# chkconfig mysql on //开机自启
启动sql2:
[root@sql2 ~]# service mysql restar
Shutting down MySQL..... SUCCESS!
Starting MySQL.........SUCCESS
[root@sql2 ~]# chkconfig mysql on
成功启动后,可在本机登入mysql>环境,检查默认的存储引擎,确保已支持ndbcluster且作为默认存储引擎:
[root@sql1 ~]# mysql -uuser -p123456
... ...
mysql> show engines\G;
*************************** 1. row ***************************
Engine: ndbcluster
Support: DEFAULT
Comment: Clustered, fault-tolerant tables
Transactions: YES
XA: NO
Savepoints: NO
*************************** 2. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
... ...
4)在管理节点上查看集群状态
[root@mgmsvr 桌面]# ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show //查看当前各节点的状态
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]2 node(s) //两个数据节点
id=4@192.168.4.4 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0, *)
id=5@192.168.4.5 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0)
[ndb_mgmd(MGM)]1 node(s) //一个管理节点
id=3@192.168.4.3 (mysql-5.6.14 ndb-7.3.3)
[mysqld(API)]2 node(s)//两个SQL节点
id=6@192.168.4.6 (mysql-5.6.14 ndb-7.3.3)
id=7 @192.168.4.7 (mysql-5.6.14 ndb-7.3.3)
6.MySQL集群的高可用性测试
1)数据同步测试
从客户机访问sql1,执行写数据库、表相关操作:
[root@client~]# mysql -u user -h 192.168.4.6 -p
Enter password: //验证口令
.. ..
mysql> CREATE DATABASE testdb; //新建testdb库
Query OK, 1 row affected (0.04 sec)
mysql> USE testdb; //切换到testdb库
Database changed
mysql> CREATE TABLE tab1(id int(4)); //新建tab1表
Query OK, 0 rows affected (0.14 sec)
mysql> INSERT INTO testdb.tab1 VALUES(1234),(5678); //插入测试记录
Query OK, 2 rows affected (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM tab1; //确认添加的表记录
+------+
| id |
+------+
| 1234 |
| 5678 |
+------+
2 rows in set (0.02 sec)
然后从客户机访问sql2,确认结果(能看到从sql1上所建的库、表、表记录):
[root@client~]# mysql -u user -h 192.168.4.7 -p
Enter password: //验证口令
.. ..
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| ndbinfo |
| performance_schema |
| test |
| testdb | //确认可看到testdb库
+--------------------+
6 rows in set (0.13 sec)
mysql> USE testdb; //切换到testdb库
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> SELECT * FROM tab1; //查看表记录也一致
+------+
| id |
+------+
| 1234 |
| 5678 |
+------+
2 rows in set (0.09 sec)
反过来从sql2上所作的数据库表操作,从sql1上也能获得相同的结果。
2)高可用性测试(关闭一台数据节点)
关闭数据节点ndb1上的ndbd进程:
[root@ndb1 ~]# netstat -anpt | grep ndbd //正常运行时
tcp 0 0 192.168.4.4:37869 0.0.0.0:* LISTEN 2092/ndbd
tcp 0 0 192.168.4.4:45945 0.0.0.0:* LISTEN 2092/ndbd
tcp 0 0 192.168.4.4:38305 0.0.0.0:* LISTEN 2092/ndbd
tcp 0 0 192.168.4.4:45945 192.168.4.5:51824 ESTABLISHED 2092/ndbd
tcp 0 0 192.168.4.4:38305 192.168.4.6:44646 ESTABLISHED 2092/ndbd
tcp 0 0 192.168.4.4:37869 192.168.4.7:53096 ESTABLISHED 2092/ndbd
tcp 0 0 192.168.4.4:33238 192.168.4.3:1186 ESTABLISHED 2091/ndbd
tcp 0 0 192.168.4.4:33239 192.168.4.3:1186 ESTABLISHED 2092/ndbd
[root@ndb1 ~]# killall -9 ndbd //强制结束ndbd进程
[root@ndb1 ~]# netstat -anpt | grep ndbd //确认已结束
此时从管理节点上查看集群状态,会发现ndb1已断开连接:
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]2 node(s) //两个数据节点
id=4@192.168.4.4 (not connected, accepting connect from 192.168.4.4)
id=5@192.168.4.5 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0, *)
[ndb_mgmd(MGM)]1 node(s) //一个管理节点
id=3@192.168.4.3 (mysql-5.6.14 ndb-7.3.3)
[mysqld(API)]2 node(s)//两个SQL节点
id=6@192.168.4.6 (mysql-5.6.14 ndb-7.3.3)
id=7 @192.168.4.7 (mysql-5.6.14 ndb-7.3.3)
然后从客户机访问sql1或sql2,仍然可读、写数据库。比如可向mydb.mytb表中再添加一条记录:
mysql> INSERT INTO testdb.tab1 VALUES(1236); //添加一条表记录
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM testdb.tab1; //确认结果
+------+
| id |
+------+
| 1234 |
| 1236 |
| 5678 |
+------+
3 rows in set (0.00 sec)
以上测试成立说明:只要还有一台数据节点可用,MYSQL数据库整体就仍然可用。
接下来可进一步验证故障恢复过程。重新启动ndb1上的ndbd服务进程,稍待片刻后强制关闭ndb2上的ndbd服务进程。然后再次访问sql1或sql2节点,查询tab1表的记录,发现与前面添加的结果一致:
[root@ndb1 ~]# ndbd
2014-09-05 21:15:17 [ndbd] INFO -- Angel connected to '192.168.4.3:1186'
2014-09-05 21:15:17 [ndbd] INFO -- Angel allocated nodeid: 4
[root@ndb2 ~]# killall -9 ndbd
[root@ndb2 ~]# netstat -anptu | grep ndb
[root@client ~]# mysql -uuser -h 192.168.4.7 -p123456
mysql> SELECT * FROM testdb.tab1; //确认结果
+------+
| id |
+------+
| 1234 |
| 1236 |
| 5678 |
+------+
3 rows in set (0.00 sec)
以上测试成立说明:因故障中断的数据节点(ndb1)恢复后,会立即从正常的数据节点(sql2)同步数据,确保数据一致性。
3)高可用性测试(关闭一台SQL节点)
当MySQL集群内有多个SQL节点时,只要有一台SQL节点可用,就可以通过它来访问MySQL数据库中保存的表数据。
比如说,关闭sql1、sql2中的任何一台以后,还可以通过另外一台来访问mydb库。
[root@sql1 ~]# netstat -anptu | grep mysql
tcp 0 0 192.168.4.6:44646 192.168.4.4:38305 ESTABLISHED 1545/mysqld
tcp 0 0 192.168.4.6:38400 192.168.4.3:1186 ESTABLISHED 1545/mysqld
tcp 0 0 192.168.4.6:35859 192.168.4.5:43959 ESTABLISHED 1545/mysqld
tcp 0 0 :::3306 :::* LISTEN
[root@sql1 ~]# service mysql stop
Shutting down MySQL.... SUCCESS!
[root@sql1 ~]# netstat -anptu | grep mysql
[root@client ~]# mysql -uuser -h192.168.4.6 -p
Enter password:
ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.4.6' (111) //sql1出故障,不能登录
[root@client ~]# mysql -uuser -h192.168.4.7 -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.6.14-ndb-7.3.3-cluster-gpl MySQL Cluster Community Server (GPL)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases; //sql2可以正常访问
+-------------------------+
| Database |
+-------------------------+
| information_schema |
| mysql |
| ndbinfo |
| performance_schema |
| test |
| testdb |
+------------------------+
6 rows in set (0.00 sec)
四、问题和经验总结
测试的过程中会出现各种问题,要耐心调试才行。所有问题的出现都是有原因的,出现问题后看报错,找日志可以快速定位造成问题的地方,然后根据提示信息,找到原因。不看日志,盲目地重启服务,重启电脑,即使偶尔解决了,也不会从中得到什么。
下面是我测试过程中,收集的一些问题:
问题1:
[root@sql2 ~]# /etc/init.d/mysql restart
MySQL server PID file could not be found! [失败]
Starting MySQL..........................................................................................................................................................................................................................^C //实在等不下去了,只能ctrl+c中断
这个问题经常出现,而且造成这种情况的原因比较多,在强制杀掉mysqld进程的时候会出现,在没有关闭mysql服务的情况下修改hostname的时候也会出现,等等情况。我做法是先查看是否有mysqld的残留进程,然后统统杀掉,再重启服务,一般的情况下会奏效,不奏效只能去看错误日志了。
问题2
如果管理节点上显示下面的数据节点后面两个都没有“*”,有可能是数据节点的selinux没有关掉。
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]2 node(s)
id=4@192.168.4.4 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0)
id=5@192.168.4.5 (mysql-5.6.14 ndb-7.3.3, Nodegroup: 0)
问题3
出现数据节点连接不上管理节点,如下
[root@ndb1 mysql]# ndbd --initial
2014-09-05 22:59:29 [ndbd] INFO -- Angel connected to '192.168.4.3:1186'
2014-09-05 23:00:00 [ndbd] ERROR -- Failed to allocate nodeid, error: 'Error: Could not alloc node id at 192.168.4.3 port 1186: No free node id found for ndbd(NDB).'
这是可能是因为你的ndbd进程已经在运行,在管理节点上已经没有可以供分配的节点id了。
在数据节点上查看进程正常就可以了,这个错误可以忽略。