一、NDB Cluster (分布式存储引擎)存储引擎简单简介
NDB 存储引擎也叫NDB Cluster 存储引擎,主要用于MySQL Cluster 分布式集群环境,
Cluster 是MySQL 从5.0 版本才开始提供的新功能。这部分我们可能并不仅仅只是介绍NDB
存储引擎,因为离开了MySQL CLuster 整个环境,NDB 存储引擎也将失去太多意义。所以
接下来会和MySQL Cluster的搭建一块介绍。
Mysql Cluster 是一种技术,其主要功能是在无共享的相关系统中部署内存中数据库的Cluster,其主要是通过NDB Cluster(简称NDB)存储引擎来实现的。
在通过无共享体系结构,系统能够使用廉价的硬件,而且对软硬件无特殊要求。
一般来说,一个Mysql Cluster 的环境结构主要如下:
主要由以下三部分组成:
1). 负责管理各个节点的Manage 节点主机:
管理节点负责整个Cluster 集群中各个节点的管理工作,包括集群的配置,启动关闭
各节点,以及实施数据的备份恢复等。管理节点会获取整个Cluster 环境中各节点的状态和
错误信息,并且将各Cluster 集群中各个节点的信息反馈给整个集群中其他的所有节点。由
于管理节点上保存在整个Cluster 环境的配置,同时担任了集群中各节点的基本沟通工作,
所以他必须是最先被启动的节点。
2). SQL 层的SQL 服务器节点(后面简称为SQL 节点),也就是我们常说的Mysql Server:
主要负责实现一个数据库在存储层之上的所有事情,比如连接管理,query 优化和响
应,cache 管理等等,只有存储层的工作交给了NDB 数据节点去处理了。也就是说,在纯粹
的Mysql Cluster 环境中的SQL 节点,可以被认为是一个不需要提供任何存储引擎的Mysql
服务器,因为他的存储引擎有Cluster 环境中的NDB 节点来担任。所以,SQL 层各Mysql 服
务器的启动与普通的Mysql 启动有一定的区别,必须要添加ndbcluster 项,可以添加在
my.cnf 配置文件中,也可以通过启动命令行来指定。
3). Storage 层的NDB 数据节点,也就是上面说的NDB Cluster:
NDB 是一个内存式存储引擎也就是说,他会将所有的数据和索引数据都load 到内存中,
但也会将数据持久化到存储设备上。不过,最新版本,已经支持用户自己选择数据可以不全
部Load 到内存中了,这对于有些数据量太大或者基于成本考虑而没有足够内存空间来存放
所有数据的用户来说的确是一个大好消息。
NDB 节点主要是实现底层数据存储的功能,保存Cluster 的数据。每一个NDB 节点保存
完整数据的一部分(或者一份完整的数据,视节点数目和配置而定),在MySQL CLuster 里
面叫做一个fragment。而每一个fragment,正常情况来讲都会在其他的主机上面有一份(或
者多分)完全相同的镜像存在。这些都是通过配置来完成的,所以只要配置得当,Mysql
Cluster 在存储层不会出现单点的问题。
一般来说,NDB 节点被组织成一个一个的NDB Group,一个NDB Group 实际上就是一组存有完全相同的物理数据的NDB 节点群。
上面提到了NDB 各个节点对数据的组织,可能每个节点都存有全部的数据也可能只保存
一部分数据,主要是受节点数目和参数来控制的。首先在Mysql Cluster 主配置文件(在管
理节点上面,一般为config.ini)中,有一个非常重要的参数叫NoOfReplicas,这个参数
指定了每一份数据被冗余存储在不同节点上面的份数,该参数一般至少应该被设置成2,也
只需要设置成2 就可以了。因为正常来说,两个互为冗余的节点同时出现故障的概率还是非
常小的,当然如果机器和内存足够多的话,也可以继续增大。一个节点上面是保存所有的数
据还是一部分数据,还受到存储节点数目的限制。NDB 存储引擎首先保证NoOfReplicas 参
数配置的要求对数据冗余,来使用存储节点,然后再根据节点数目将数据分段来继续使用多
余的NDB 节点,分段的数目为节点总数除以NoOfReplicas 所得。
二、MySQL Cluster集群架构的实现
管理节点上:
rpm -ivh MySQL-Cluster-gpl-management-7.1.18-1.el6.x86_64.rpm
rpm -ivh MySQL-Cluster-gpl-tools-7.1.18-1.el6.x86_64.rpm
mkdir /usr/mysql-cluster
vi /usr/mysql-cluster/config.ini [ndbd default] noofreplicas=1 //运行NDB存储引擎 datamemory=30M indexmemory=10M [ndb_mgmd] nodeid=1 hostname=192.168.1.21 //管理节点ip datadir=/usr/mysql-cluster [ndbd] nodeid=2 hostname=192.168.1.22 //存储节点ip datadir=/usr/mysql-cluster [mysqld] //客户端 nodeid=3 hostname=192.168.1.23
ndb_mgmd -f /usr/mysql-cluster/config.ini --initial //指定配置文件,初始化
ndb_mgm //就可以查看各个节点的信息了
存储节点上:
rpm -ivh MySQL-Cluster-gpl-storage-7.1.18-1.el6.x86_64.rpm
vi /etc/my.cnf [mysqld] ndbcluster //运行ndb集群引擎 ndb-connectstring=192.168.1.21 //指定管理节点 [mysql_cluster] ndb-connectstring=192.168.1.21
ndbd --initial //初始化后,在manager节点上ndb_mgm查看存储节点已经连接上了
SQL节点 上:
MySQL-Cluster-gpl-client-7.1.18-1.el6.x86_64.rpm
MySQL-Cluster-gpl-server-7.1.18-1.el6.x86_64.rpm
SQL节点上若安装了mysql、mysql-server、mysql-libs,需要将其卸载才能安装MySQL-Cluster,否则会报错
error: Failed dependencies:
mysql conflicts with MySQL-Cluster-gpl-server-7.1.18-1.el6.x86_64
mysql-server conflicts with MySQL-Cluster-gpl-server-7.1.18-1.el6.x86_64
rpm -e mysql-libs --nodeps //强制卸载
rpm -ivh MySQL-Cluster-gpl-*
vi /etc/my.cnf [mysqld] .... ndbcluster (以下数据添加在[mysqld]区域的最下方) ndb-connectstring=192.168.1.21 [mysql_cluster] ndb-connectstring=192.168.1.21
/etc/init.d/mysql start //启动mysql,然后在管理节点上ndb_mgm查看
sql节点上如初始化时会在目录 /var/lib/mysql/mysql 中生成数据库的好多文件,如启动时初始化失败,可以手动执行命令 mysql_install_db --user=mysql 生成。
--------------------
添加新的存储节点和sql节点:
添加新的存储节点和sql节点前,必须先将已有的管理节点、存储节点、sql节点关闭
在管理节点上执行ndb_mgm -e shutdown只能关闭存储节点和管理节点自己的服务,sql节点仍需手工stop,之后再添加。
先在管理节点的配置文件中加入要添加的节点:
vi /usr/mysql-cluster/config.ini [ndbd default] noofreplicas=2 //定义两个节点为一个节点组, datamemory=30M indexmemory=10M [ndb_mgmd] nodeid=1 hostname=192.168.1.21 datadir=/usr/mysql-cluster [ndbd] nodeid=2 hostname=192.168.1.22 datadir=/usr/mysql-cluster [ndbd] //加入的存储节点 nodeid=4 hostname=192.168.1.10 datadir=/usr/mysql-cluster [mysqld] nodeid=3 hostname=192.168.1.23 [mysqld] //加入的sql节点 nodeid=5 hostname=192.168.1.24 [mysqld] //加个空闲连接,数据恢复要用到,需要时再加也可以
然后再配置新加的节点(和原来的配置一致)
ndb_mgmd -f /usr/mysql-cluster/config.ini --initial //重新初始化管理端
ndbd --initial //启动各个数据节点
/etc/init.d/mysql start //启动SQL节点
在管理节点上ndb_mgm show,就可以看见各个节点已经正常工作
# ndb_mgm -- NDB Cluster -- Management Client -- ndb_mgm> show Connected to Management Server at: localhost:1186 Cluster Configuration --------------------- [ndbd(NDB)] 2 node(s) id=2 @192.168.1.22 (mysql-5.1.56 ndb-7.1.18, Nodegroup: 0, Master) id=4 @192.168.1.10 (mysql-5.1.56 ndb-7.1.18, Nodegroup: 0) [ndb_mgmd(MGM)] 1 node(s) id=1 @192.168.1.21 (mysql-5.1.56 ndb-7.1.18) [mysqld(API)] 2 node(s) id=3 @192.168.1.23 (mysql-5.1.56 ndb-7.1.18) id=5 @192.168.1.24 (mysql-5.1.56 ndb-7.1.18)
从以上信息显示,节点2和4作为一个数据组,两个节点的数据是一样的,互为冗余;两个sql节点存储的表结构也互为冗余。
--------------
建立集群数据
在任一sql节点插入数据,都可以在另一节点看到,
mysql> create database ty; mysql> create table tjf( -> name varchar(20) not null, -> age int(8), -> sex varchar(8) not null -> )engine ndbcluster; //指定MySQL为该表使用NDB存储引擎,数据存储于各数据节点,不然mysql使用 //默认的MyISAM存储引擎,所有数据将会存储于本机,和单机一样 Query OK, 0 rows affected (0.81 sec)
//导入数据 mysql> insert into tjf values('tjf',21,'f'); mysql> insert into tjf values('ty',22,'m'); mysql> insert into tjf values('jn',20,'f'); mysql> insert into tjf values('fx',21,'f'); mysql> insert into tjf values('cs',22,'m');
在另一节点查看表,已经同步过来
mysql> select * from tjf; +------+------+-----+ | name | age | sex | +------+------+-----+ | jn | 20 | f | | cs | 22 | m | | ty | 22 | m | | tjf | 21 | f | | fx | 21 | f | +------+------+-----+ 5 rows in set (0.01 sec)
MySQL Cluster备份恢复
在管理节点上执行备份数据命令,数据将分别备份到各个存储节点上,恢复时需要在各个存储节点上都执行恢复命令;
ndb_mgm> start backup Waiting for completed, this may take several minutes Node 2: Backup 1 started from node 1 Node 2: Backup 1 started from node 1 completed StartGCP: 1443 StopGCP: 1446 #Records: 2062 #LogRecords: 0 Data: 51136 bytes Log: 0 bytes
在数据节点/usr/mysql-cluster/BACKUP目录中就可以看到备份的数据;
当在sql节点上删除数据,就可以利用此备份恢复(只能恢复数据,如将表或库直接删掉了,需要手动加上,才可以恢复);
恢复数据需要命令 ndb_restore (由包MySQL-Cluster-gpl-tools-7.1.18-1.el6.x86_64.rpm提供),若存储节点上没有此命令,可以将其直接由管理节点上复制过去,也可以安装tools包。
注意:恢复数据时,管理节点上一定要有空闲连接,否则无法恢复。
由于数据备份在两个数据节点,因此在各个数据节点都得执行恢复操作
在数据节点2恢复:
[root@node1 ~]# ls /usr/mysql-cluster/BACKUP/BACKUP-1/ BACKUP-1-0.2.Data BACKUP-1.2.ctl BACKUP-1.2.log [root@node1 ~]# ndb_restore -n 2 -b 1 -r /usr/mysql-cluster/BACKUP/BACKUP-1/ Nodeid = 2 Backup Id = 1 backup path = /usr/mysql-cluster/BACKUP/BACKUP-1/ Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1.2.ctl' File size 9408 bytes Backup version in files: ndb-6.3.11 ndb version: mysql-5.1.56 ndb-7.1.18 Stop GCP of Backup: 1445 Connected to ndb!! Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1-0.2.Data' File size 26388 bytes _____________________________________________________ Processing data in table: ty/def/tjf(7) fragment 0 _____________________________________________________ Processing data in table: sys/def/NDB$EVENTS_0(3) fragment 0 _____________________________________________________ Processing data in table: mysql/def/ndb_apply_status(6) fragment 0 _____________________________________________________ Processing data in table: mysql/def/NDB$BLOB_4_3(5) fragment 0 _____________________________________________________ Processing data in table: sys/def/SYSTAB_0(2) fragment 0 _____________________________________________________ Processing data in table: mysql/def/ndb_schema(4) fragment 0 Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1.2.log' File size 52 bytes Restored 3 tuples and 0 log entries NDBT_ProgramExit: 0 - OK
SQL节点上查看恢复情况,数据恢复了一部分
mysql> select * from tjf; +------+------+-----+ | name | age | sex | +------+------+-----+ | jn | 20 | f | | cs | 22 | m | | ty | 22 | m | +------+------+-----+ 3 rows in set (0.01 sec)
在数据节点4恢复:
[root@rhcs1 ~]# ls /usr/mysql-cluster/BACKUP/BACKUP-1/ BACKUP-1-0.4.Data BACKUP-1.4.ctl BACKUP-1.4.log [root@rhcs1 ~]# ndb_restore -n 4 -b 1 -r /usr/mysql-cluster/BACKUP/BACKUP-1/ Nodeid = 4 Backup Id = 1 backup path = /usr/mysql-cluster/BACKUP/BACKUP-1/ Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1.4.ctl' File size 9408 bytes Backup version in files: ndb-6.3.11 ndb version: mysql-5.1.56 ndb-7.1.18 Stop GCP of Backup: 1445 Connected to ndb!! Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1-0.4.Data' File size 25180 bytes _____________________________________________________ Processing data in table: ty/def/tjf(7) fragment 1 _____________________________________________________ Processing data in table: sys/def/NDB$EVENTS_0(3) fragment 1 _____________________________________________________ Processing data in table: mysql/def/ndb_apply_status(6) fragment 1 _____________________________________________________ Processing data in table: mysql/def/NDB$BLOB_4_3(5) fragment 1 _____________________________________________________ Processing data in table: sys/def/SYSTAB_0(2) fragment 1 _____________________________________________________ Processing data in table: mysql/def/ndb_schema(4) fragment 1 Opening file '/usr/mysql-cluster/BACKUP/BACKUP-1/BACKUP-1.4.log' File size 52 bytes Restored 2 tuples and 0 log entries NDBT_ProgramExit: 0 - OK
再次在SQL节点查看数据,已经恢复成功
mysql> select * from tjf; +------+------+-----+ | name | age | sex | +------+------+-----+ | jn | 20 | f | | cs | 22 | m | | ty | 22 | m | | tjf | 21 | f | | fx | 21 | f | +------+------+-----+ 5 rows in set (0.00 sec)
-n指节点id -b指备份id -r指备份目录