MySQL分片高可用集群之MySQL Cluster部署使用

MySQL Cluster 是MySQL官方出品的分布式数据库解决方案,使用的数据库引擎为NDB,跟单机下的MyISAM和Innodb引擎有所不同,操作界面之一就是MySQL,此外提供原生API,可以节省资源并加快执行速度。该方案比业界其他MySQL集群方案在数据量大时有更大优势,开发者使用上跟单库操作几乎无差异,原先使用MySQL的话几乎可以无缝迁移,就可以享受集群带来的力量。当然也有个明显的缺点:内存开销非常大,如果要选择该方案,需要足够的硬件内存资源。下面我们详细地讲述MySQL Cluster 的部署使用。

第一步:下载安装

我们可以从MySQL的官网上下载到http://dev.mysql.com/downloads/cluster/ 
此处我们下载的是源码版mysql-cluster-gpl-7.4.8.tar.gz,您可根据自己的情况选择其他二进制版本,免去依赖的安装。编译依赖比mysql多几个,主要注意下这里需要jdk7。只有jre是不够的,jdk8目前不支持。其他的依赖都没有特别的。

$ BUILD/autorun.sh
$ ./configure --prefix=/home/lyw/db/mysql-cluster
$ make -j4
$ sudo make install

安装好后我们可以看看bin目录下的内容,里面不仅有mysql开头的mysql相关文件,而且多了很多ndb开头的文件,这些ndb开头的文件就是MySQL Cluster的核心所在了。

第二步:用工具自动部署

从7.3版本开始,MySQL Cluster提供了一个自动部署工具,这真的是大大降低的入门的难度。

1.    启动自动部署工具
如果我们用的是桌面版,我们运行下面的命令,会自动用浏览器打开一个部署页面,

$ bin/ndb_setup.py

如果是服务器版,需要增加两个参数,免得在自己机器上打不开网页,如果有防火墙请允许对应端口访问。

$ bin/ndb_setup.py  -N 192.168.1.8  -p 8081

然后根据提示打开对应的网页,这里是http://192.168.1.8:8081/welcome.html
我们点击页面上的文字链接“Create New MySQL Cluster”,进入下面的页面

Application area中:
        第一项simple testing意思是只分配很少的内存,因此只能存一点点数据
        第二项Web application则会尽量多分配内存。(具体多少根据下面几页配置决定)
        第三项realtime是在Web application的基础上,缩短心跳的间隔,能更快的发现机器故障。
Write load中:
        三项的对应的写吞吐率,第一项小于100/s,第二项100~1000/s,第三项1000/s以上。
一般测试我们选择Web application和Medium就好了,一般都能应付。
下面的SSH property部分需要在多台机器部署时有用,如果跟hadoop一样已经有免密码登陆,则不用改,如果需要密码登陆,则写上机器的用户名密码。我们这里是本机部署因此无所谓。

2.    进入下一页服务器配置:

默认情况下Memory会配置为本机的所有内存,这样会导致内存不足而启动失败,请少配置一点。不过也不能太少,单机时最少1.8G,当配置小于1.8G时,基本上存不了什么数据,那时操作会报一些看起来奇怪的错误,因为跟其他的引擎错误不同。
如果您有很多机器,可以点击左下角的AddHost按钮多增加几台,每台的内存需要在450M以上,总内存还是需要在1.8G以上。

3.    进入下一页进程配置:

默认情况下会配置1个管理节点,2个数据节点,2个MySQL节点,另外还有3个API结点(直接用Ndb API连接及ndb工具运行时使用)。
自动配置时一般每个Data节点和MySQL节点都需要450M以上内存(普通MySQL只需要100M,这里会特别费内存),最好稍微计算下内存是否够用。如果内存足够,可以点击左下角的Add process按钮增加几个数据节点,其他节点测试时一般不用增加。如下图。

4.    再下一页是配置修改

我们可以点击绿色圈的“+”修改一下端口,路径等。管理节点的默认端口号是1186,如果修改了端口号,那后面的操作都需要增加参数。SQL节点使用了3306, 3307这样的默认端口,如果本机跑了其他MySQL占用了这两个端口,请修改下。

5.    最后进入下一页部署启动

只要点击下面中间那个”Deply and start cluster”按钮,然后等待一分钟左右,让进度条走完,除API外状态都变绿圈圈,MySQL Cluster就部署成功了。

我们现在就可以用mysql客户端去登陆了,您也可以用您喜欢的图形界面来查看。

$ bin/mysql -uroot -h127.0.0.1 -P3306
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| ndbinfo            |
| performance_schema |
| test               |
| tmp                |
+--------------------+
6 rows in set (0.00 sec)

mysql> create database lyw;
Query OK, 1 row affected (0.05 sec)

mysql> use lyw;
Database changed

mysql> create table t1 (id int primary key, a int, v varchar(32)) engine ndbcluster;
Query OK, 0 rows affected (0.77 sec)

mysql> insert into t1 values (1, 1, ‘a‘), (2, 2, ‘b‘);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from t1;
+----+------+------+
| id | a    | v    |
+----+------+------+
|  1 |    1 | a    |
|  2 |    2 | b    |
+----+------+------+
2 rows in set (0.00 sec)

我们发现默认的数据库比平常多两个,特别是 ndbinfo,当然是存储 ndb相关的一些数据了。当我们创建表格时,我们要在后面指定存储引擎 engine ndbcluster,否则创建出来的表格还是默认的innodb,只在单机上有数据。我们下面用多种工具校验下数据确实存储到了ndb引擎。
方法一:查看创建语句 show create table t1;  如果返回的内容里面有ENGINE=ndbcluster,说明用的是ndb引擎。

方法二:链接上我们的另外一个MySQL节点。看是否有对应的数据

$ bin/mysql -uroot -h127.0.0.1 -P3307
mysql> select * from lyw.t1;
+----+------+------+
| id | a    | v    |
+----+------+------+
|  1 |    1 | a    |
|  2 |    2 | b    |
+----+------+------+
2 rows in set (0.00 sec)

数据能从另外的节点查到,说明数据已经在ndb上,如果您自己创建一个其他引擎的表,数据在其他库是查不到的。

方法三:用ndb_desc命令,后面两个参数是数据库名和表名。管理者端口改了,或不是本机,需要增加参数 -c 192.168.1.8:1186

$ bin/ndb_desc -p -d lyw t1
或
$ bin/ndb_desc -p -d lyw t1 -c 192.168.1.8:1186

如果有一大屏幕的内容,说明这个表已经在ndb引擎里了,并且显示了关于该表的各种信息。

第三步:创建磁盘表

ndb默认创建的表格是内存表,意思是所有数据都加载在内存中,当内存不能够放下所有数据时,将不能插入数据。数据再磁盘中也会存,但那些只是在宕机重启后用于加载的,平常不会去读。如果数据全部在内存,而我们的内存并非很大,需要存储的数据却很多,那怎么办呢,7.3版本开始ndb引擎支持磁盘表,创建时需要多两个步骤,我们下面来创建一下。
首先我们要创建一个日志文件组lg1:

mysql> create logfile group lg1 add undofile ‘undo.lg1‘ initial_size 16M engine ndbcluster;

然后创建一个表空间ts1:

mysql> create tablespace ts1 add datafile ‘data.ts1‘ use logfile group lg1 initial_size 64M engine ndbcluster;

这时我们就可以创建表格了:

mysql> create table t2 (id int primary key, a int, v varchar(32)) tablespace ts1 storage disk engine ndbcluster;

这里比上面有多个几个关键字 tablespace ts1 storage disk。
这里的数据和日志文件就相当于innodb引擎里的数据文件和日志文件,一般日志文件不用太大,而数据文件需要足够放表里的数据。如果运行到一定时间发现不够了,我们也可以添加的。

mysql> alter tablespace ts1 add datafile ‘data2.ts1‘ initial_size 128M engine ndbcluster;

这样ts1这个表空间里面就有两个数据文件了,总大小是64+128=192M了。
日志组也同样可以增加文件,这个一般在写入吞吐率增加时才需要增加。

mysql> alter logfile group lg1 add undofile ‘undo2.lg1‘ initial_size 16M engine ndbcluster;

表空间创建好后我们可以用ndb_show_tables命令查看是否真的建立成功了

$ bin/ndb_show_tables  |grep -E "lg1|ts1"
37    Tablespace           Online   -                             ts1
36    Undofile             Online   -                             undo.lg1
39    Datafile             Online   -                             data2.ts1
38    Datafile             Online   -                             data.ts1
40    Undofile             Online   -                             undo2.lg1
35    LogfileGroup         Online   -                             lg1

另外我们也可以到文件系统上去看,是否有了对应的文件。

第四步:自己手动部署集群

前面我们部署的集群是用了自动化工具的,有些配置不能轻易修改,只适合快速和初学使用,实际应用的时候我们还是应该要手动地去部署。同时也为我们后面的集群扩容做准备。我们参考自动部署产生的配置文件,在上面修改一下。
数字49目录下的config.ini就是我们最关键的配置了。刚才我们生成的配置文件如下

[NDB_MGMD DEFAULT]
Portnumber=1186

[NDB_MGMD]
NodeId=49
HostName=127.0.0.1
DataDir=/home/lyw/db/mysql-cluster/run/data/49/
Portnumber=1186

[TCP DEFAULT]
SendBufferMemory=4M
ReceiveBufferMemory=4M

[NDBD DEFAULT]
BackupMaxWriteSize=1M
BackupDataBufferSize=16M
BackupLogBufferSize=4M
BackupMemory=20M
BackupReportFrequency=10
MemReportFrequency=30
LogLevelStartup=15
LogLevelShutdown=15
LogLevelCheckpoint=8
LogLevelNodeRestart=15
DataMemory=135M
IndexMemory=22M
MaxNoOfTables=4096
MaxNoOfTriggers=3500
NoOfReplicas=2
StringMemory=25
DiskPageBufferMemory=64M
SharedGlobalMemory=20M
LongMessageBuffer=32M
MaxNoOfConcurrentTransactions=16384
BatchSizePerLocalScan=512
FragmentLogFileSize=256M
NoOfFragmentLogFiles=3
RedoBuffer=32M
MaxNoOfExecutionThreads=2
StopOnError=false
LockPagesInMainMemory=1
TimeBetweenEpochsTimeout=32000
TimeBetweenWatchdogCheckInitial=60000
TransactionInactiveTimeout=60000
HeartbeatIntervalDbDb=15000
HeartbeatIntervalDbApi=15000

[NDBD]
NodeId=1
HostName=127.0.0.1
DataDir=/home/lyw/db/mysql-cluster/run/data/1/

[NDBD]
NodeId=2
HostName=127.0.0.1
DataDir=/home/lyw/db/mysql-cluster/run/data/2/

[MYSQLD DEFAULT]

[MYSQLD]
NodeId=53
HostName=127.0.0.1

[MYSQLD]
NodeId=54
HostName=127.0.0.1

[API]
NodeId=50
HostName=127.0.0.1

[API]
NodeId=51
HostName=127.0.0.1

[API]
NodeId=52
HostName=127.0.0.1

[NDB_MGMD] 组没有多少内容,可以根据自己的情况改改端口路径等。
[NDBD DEFAULT] 组配置了各数据节点相同的参数,我们可以看到这个文件中配置的内存都是挺大的,我们可以自行调整,如果机器内存较小,可以把所有内存都配小一点,如果内存较大,(每个节点16G以内),只要将DataMemoryIndexMemory改大一点就好了。
我们可能需要将数据配置到其他路径下,就修改下对应的路径。
FragmentLogFileSize*NoOfFragmentLogFiles因大于DataMemory的值,否则会出现内存用不完而硬盘不够放的情况。
增加几个 [NDBD] 组的内容即可增加几个数据节点,注意NDBD 的id范围在1~48之间。
增加几个 [MYSQLD] 组的内容即可增加几个MySQL节点。这种id范围在1~255之间。
由于数据节点范围是1~48,资源很宝贵,因此尽量将这个区间保留给数据节点,其他节点使用49~255的范围。
[API] 组一般不用动,如果编程时大量使用原生API编程,需要增加一些。bin目录下的ndb_开头的工具都是使用API组的连接,不过他们属于短连接,使用完就释放了。

我们再看一下53或54目录下的my.cnf,这是mysql的配置文件

[mysqld]
log-error=mysqld.53.err
datadir="/home/lyw/db/mysql-cluster/run/data/53/"
tmpdir="/home/lyw/db/mysql-cluster/run/data/53/tmp"
basedir="/home/lyw/db/mysql-cluster/"
port=3306
ndbcluster=on
ndb-nodeid=53
ndb-connectstring=127.0.0.1:1186,
socket="/home/lyw/db/mysql-cluster/run/data/53/mysql.socket"

可以看到里面多了3行ndb相关的参数,您可以自行在配置文件里增加参数,比如innodb相关的,因为innodb引擎已经不再使用,默认128M的内存,48M的日志文件显得过大,我们完全可以将他们调小。设置下server-id,方便后面说的主从复制。

innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
innodb_log_file_size = 5M
innodb_log_buffer_size = 5M
server-id = 53

如果是单机下,我们准备一个初始化和启动脚本initial.sh:

basedir=/home/lyw/db/mysql-cluster/run/data
bindir=/home/lyw/db/mysql-cluster
$bindir/bin/ndb_mgmd --ndb-nodeid=49 --config-dir=$basedir/49 --config-file=$basedir/49/config.ini  --initial
sleep 3
# 更多的数据节点,就增加几个数字
for id in 1  2
do
    mkdir $id
    $bindir/bin/ndbmtd --ndb-nodeid=$id --ndb-connectstring=127.0.0.1:1186  --initial
    sleep 10
done
sleep 10
cd $bindir
for id2 in 53  54
do
    mkdir -p $basedir/$id2/tmp
    $bindir/scripts/mysql_install_db --defaults-file=$basedir/$id2/my.cnf 
    $bindir/bin/mysqld_safe --defaults-file=$basedir/$id2/my.cnf &
done
sleep 3
ps aux|grep mysql

然后我们将前面配置的3种4个配置文件下面目录组织起来。

.
├── 49
│   └── config.ini
├── 53
│   └── my.cnf
├── 54
│   └── my.cnf
└── initial.sh

执行我们写好的脚本initial.sh,大约需要一分钟,显示一大堆的内容后,我们的集群就部署并启动好了。我们回过头去看下启动脚本,说明下启动的步骤:

1. 启动管理节点ndb_mgmd,注意,参数需要指定全路径,有个--initial,这个参数自在第一次启动时使用。

$bindir/bin/ndb_mgmd --ndb-nodeid=49 --config-dir=$basedir/49 --config-file=$basedir/49/config.ini  --initial

2. 启动每个数据节点ndbmtd,这里也一样第一次启动需要--initial参数进行初始化,目录需要事先创建好。

mkdir $id
$bindir/bin/ndbmtd --ndb-nodeid=$id --ndb-connectstring=127.0.0.1:1186  --initial

3. 初始化每个数据库 mysql_install_db

mkdir -p $basedir/$id2/tmp
$bindir/scripts/mysql_install_db --defaults-file=$basedir/$id2/my.cnf

4. 启动每个数据库mysqld

$bindir/bin/mysqld_safe --defaults-file=$basedir/$id2/my.cnf &

这样所有节点就全部启动好了。我们可以跟前面一样测试下系统是否工作正常。

第五步:集群在线扩容

我们前面部署的集群只有两个数据节点,能够存储的数据量有限,当我们数据越来越多时,就需要扩充集群容量,MySQL Cluster最强大的功能之一就是在线扩容,扩容期间服务看不出停顿。我们就来看看在线扩容是如何操作的吧。
我们用前面准备的集群,并且在集群中写入若干数据(写入过程略)。我这里写了lyw.sbtest1表100000条数据,我们用ndb_desc命令查看数据的分布情况

$ bin/ndb_desc -d lyw sbtest1 -pn
。。。。。。
FragmentCount: 2
。。。。。。
-- Per partition info -- 
Partition    Row count    Commit count    Frag fixed memory    Frag varsized memory    Extent_space    Free extent_space    Nodes    
0            49950        49950           10715136             0                        0                0                     1,2    
1            50050        50050           10747904             0                        0                0                     2,1

可以看到数据基本平均分布在两个分片里。默认情况下,分片数是跟节点数相同的,这个可以配置,在分片章节再讲。

我们用另外一个命令看一下集群的健康状况

$ bin/ndb_mgm
-- NDB Cluster -- Management Client --

ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]    2 node(s)
id=1    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 0, *)
id=2    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 0)
[ndb_mgmd(MGM)]    1 node(s)
id=49    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8)
[mysqld(API)]    5 node(s)
id=50 (not connected, accepting connect from 127.0.0.1)
id=51 (not connected, accepting connect from 127.0.0.1)
id=52 (not connected, accepting connect from 127.0.0.1)
id=53    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8)
id=54    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8)

ndb_mgm> all report memory
Node 1: Data usage is 18%(781 32K pages of total 4320)
Node 1: Index usage is 6%(196 8K pages of total 2848)
Node 2: Data usage is 18%(781 32K pages of total 4320)
Node 2: Index usage is 6%(196 8K pages of total 2848)

show命令查看各节点的存活状态如何。
all report memory 命令查看各数据节点的内存使用情况。

接下来我们打算将集群从2个数据节点扩充到4个数据节点。首先我们在49/config.ini配置文件里增加2个数据节点的配置:

[NDBD]
NodeId=3
HostName=127.0.0.1
DataDir=/home/lyw/db/mysql-cluster/run/data/3/

[NDBD]
NodeId=4
HostName=127.0.0.1
DataDir=/home/lyw/db/mysql-cluster/run/data/4/

我们用ndb_mgm客户端工具停止ndb_mgmd节点

ndb_mgm> 49 stop

ndb_mgmd节点停止了并不会影响集群的数据操作,因此您不用着急,慢慢来就好了。
再用命令行启动,这里的参数跟前面的不同,原先--initial 变成--reload,另外注意参数最好用全路径

$ /home/lyw/db/mysql-cluster/bin/ndb_mgmd --ndb-nodeid=49 --config-dir=/home/lyw/db/mysql-cluster/run/data/49 --config-file=/home/lyw/db/mysql-cluster/run/data/49/config.ini --reload

检查下是否启动正常

ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]    4 node(s)
id=1    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 0, *)
id=2    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 0)
id=3 (not connected, accepting connect from 127.0.0.1)
id=4 (not connected, accepting connect from 127.0.0.1)
[ndb_mgmd(MGM)]    1 node(s)
id=49    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8)
[mysqld(API)]    5 node(s)
id=50 (not connected, accepting connect from 127.0.0.1)
id=51 (not connected, accepting connect from 127.0.0.1)
id=52 (not connected, accepting connect from 127.0.0.1)
id=53    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8)
id=54    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8)

我们发现 ndb_mgmd节点已启动, 新增的2个数据节点3, 4并没有连接。我们还不着急启动他们俩,我们先将现在活着的节点逐个重启一下,让他们都知道很快就会有新同事来了。节点的重启需要花费数十秒,请耐心等待“Node 1: Started  (version 7.4.8)”字样的出现。(这些字符不是命令的输入),然后再操作下一条语句。

ndb_mgm> 1 restart
Node 1: Node shutdown initiated
Node 1: Node shutdown completed, restarting, no start.
Node 1 is being restarted
ndb_mgm> Node 1: Start initiated (version 7.4.8)
Node 1: Started (version 7.4.8)

ndb_mgm> 2 restart
Node 2: Node shutdown initiated
Node 2: Node shutdown completed, restarting, no start.
Node 2 is being restarted
ndb_mgm> Node 2: Start initiated (version 7.4.8)
Node 2: Started (version 7.4.8)

2个mysql节点也要逐个重启下

$ bin/mysqladmin -uroot -h127.0.0.1 -P3306 shutdown
$ bin/mysqld_safe --defaults-file=/home/lyw/db/mysql-cluster/run/data/53/my.cnf &

$ bin/mysqladmin -uroot -h127.0.0.1 -P3307 shutdown
$ bin/mysqld_safe --defaults-file=/home/lyw/db/mysql-cluster/run/data/54/my.cnf &

我们用ndb_mgm> show命令检查一下,是否都启动成功(显示内容略)
至此原先环境的所有进程都已经重启好了,我们启动新加入的两个节点,注意最后的--initial参数

$ mkdir 3 4
$ /home/lyw/db/mysql-cluster/bin/ndbmtd --ndb-nodeid=3 --ndb-connectstring=127.0.0.1:1186  --initial    
$ /home/lyw/db/mysql-cluster/bin/ndbmtd --ndb-nodeid=4 --ndb-connectstring=127.0.0.1:1186  --initial

数十秒后,用show命令检查,显示如下:

ndb_mgm> show
[ndbd(NDB)]    4 node(s)
id=1    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 0, *)
id=2    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 0)
id=3    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, no nodegroup)
id=4    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, no nodegroup)
。。。。。。

节点都已启动成功,不过3,4两个节点后面显示为 “no nodegroup”,而1,2两个节点显示为“Nodegroup: 0”。根据MySQL Cluster的结构,一个集群可由多个nodegroup组成,一个nodegroup可由多个datanode组成,数据分片fragement在相同nodegroup的多个datanode间相互同步。至于还没有加入任何组的数据节点是不会提供服务的。我们需要为这两个节点建立一个组。

ndb_mgm> create nodegroup 3,4
Nodegroup 1 created
ndb_mgm> show
[ndbd(NDB)]    4 node(s)
id=1    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 0, *)
id=2    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 0)
id=3    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 1)
id=4    @127.0.0.1  (mysql-5.6.27 ndb-7.4.8, Nodegroup: 1)

这样我们就有两个nodegroup了。再来看下我们之前插入的100000条数据的分布情况,

$ bin/ndb_desc -d lyw sbtest1 -pn
。。。。。。
FragmentCount: 2
。。。。。。
-- Per partition info -- 
Partition    Row count    Commit count    Frag fixed memory    Frag varsized memory    Extent_space    Free extent_space    Nodes    
0            49950        49950           10715136             0                        0                0                     1,2    
1            50050        50050           10747904             0                        0                0                     2,1

我们发现还是跟以前一样是两个分片,且都在1,2两个数据节点上。就算是等上一天也不会改变,似乎我们的新节点还没有生效。我们加一个新表lyw2.sbtest1 试试,也写入100000条。

$ bin/ndb_desc -d lyw2 sbtest1 -pn
。。。。。。
FragmentCount: 4
。。。。。。
-- Per partition info -- 
Partition    Row count    Commit count    Frag fixed memory    Frag varsized memory    Extent_space    Free extent_space    Nodes    
0            24943        24943           5373952              0                        0                0                     1,2    
2            25007        25007           5373952              0                        0                0                     2,1    
3            24961        24961           5373952              0                        0                0                     4,3    
1            25089        25089           5373952              0                        0                0                     3,4

我们发现新表的数据是可以自动分布到新的节点上去了。
如果我们想让原先表 lyw.sbtest1的数据也均匀分布到新节点上,还需要在mysql客户端做下面的操作。

mysql> alter online table lyw.sbtest1 reorganize partition;

这时再用ndb_desc查看分布,数据已经分布到新节点上去了

$ bin/ndb_desc -d lyw sbtest1 -pn
。。。。。。
FragmentCount: 4
。。。。。。
-- Per partition info -- 
Partition    Row count    Commit count    Frag fixed memory    Frag varsized memory    Extent_space    Free extent_space    Nodes    
0            24943        99964           10715136             0                        0                0                     1,2    
1            25089        99972           10747904             0                        0                0                     2,1    
2            25007        25007           5373952              0                        0                0                     3,4    
3            24961        24961           5373952              0                        0                0                     4,3

不过还是会发现0,1 两个分片的内存使用量(Frag fixed memory列)并没有下降,目前版本这个内存只会在删除表的情况下才会释放,个人觉得这是个较大缺陷,估计后面的版本会改进吧。

第六步:表的分片设定

1.    分片数量控制

前面创建的表格的分片数都是系统根据节点数自动设置的,一般跟节点数相同,实际上这个分片数也是可以指定的,用partitions参数:

mysql> create table t3( id int primary key, a int, v varchar(32)) engine ndbcluster partition by key(id) partitions 1;
mysql> create table t8( id int primary key, a int, v varchar(32)) engine ndbcluster partition by key(id) partitions 8;

如果某些表估计数据量不大,就可以考虑将分片数设置为1,这种情况下就相当于是单库操作。如果某些表数据量巨大,就可以增大分片数,最大分片数是8*nodegroup数。

2.    多主键下的分片控制

当我们创建的表格需要两个主键的时候会是怎样的呢?我们也来创建一个:

mysql> create table d1(id1 int, id2 int, a int, v varchar(32), primary key (id1, id2)) engine ndbcluster;
mysql> insert into d1 values(1,1,1,‘a‘), (1,2,3,‘a‘), (1,3,4, ‘b‘), (1,4,5,‘d‘);

这里我们插入的数据id1都相同,id2是不同的,然后我们查看数据的分布:

$ bin/ndb_desc -d lyw d1 -pn
。。。。。。
-- Attributes --
id1 Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
id2 Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
。。。。。。
-- Per partition info -- 
Partition    Row count    Commit count    Frag fixed memory    Frag varsized memory    Extent_space    Free extent_space    Nodes    
0            1            1               32768                32768                   0                0                     1,2    
2            1            1               32768                32768                   0                0                     2,1    
1            1            1               32768                32768                   0                0                     3,4    
3            1            1               32768                32768                   0                0                     4,3

4个分片里面全有数据,实际上这里的分片规则是根据两个key一起决定的,我们再看表属性里面id1 和id2 都有 “DISTRIBUTION KEY” 字样,也是说明了这一点。
如果是这样分片很有可能不是我们想要的分片方式,我们经常会希望让id1相同的数据都在一起,在一个分片上就能查找到,这样能够减少数据库的查询开销。要想达到这个目的,我们建表时需要多写一点内容。

mysql> create table d2(id1 int, id2 int, a int, v varchar(32), primary key (id1, id2)) engine ndbcluster partition by key(id1);
mysql> insert into d2 values(1,1,1,‘a‘), (1,2,3,‘a‘), (1,3,4, ‘b‘), (1,4,5,‘d‘);

建表语句后面增加了partition by key(id1)。我们插入同样的4行,再来看表属性

$ bin/ndb_desc -d lyw d2 -pn
。。。。。。
-- Attributes --
id1 Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
id2 Int PRIMARY KEY AT=FIXED ST=MEMORY
。。。。。。
-- Per partition info -- 
Partition    Row count    Commit count    Frag fixed memory    Frag varsized memory    Extent_space    Free extent_space    Nodes    
3            4            4               32768                32768                   0                0                     4,3

所有数据都在3号分片上,这绝非是巧合,您可以自己多插入些数据试试。另外我们看到id2属性比id1 少了“ DISTRIBUTION KEY”这部分内容,也说明了该表只按照id1进行分片。

我们也可以指定只按照id2进行分片,但是不可以按照非主键的列进行分片:

mysql> create table d3(id1 int, id2 int, a int, v varchar(32), primary key (id1, id2)) engine ndbcluster partition by key(id2);
Query OK, 0 rows affected (1.04 sec)

mysql> create table d4(id1 int, id2 int, a int, v varchar(32), primary key (id1, id2)) engine ndbcluster partition by key(a);
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table‘s partitioning function

第七步:NDB引擎的事务

InnoDB引擎支持所有4个级别的事务,而NDB引擎却只支持READ COMMITTED级别事务,比InnoDB引擎的默认级别低了一级,也就是说,本来在InnoDB引擎下运行良好的程序,迁移到NDB引擎有可能会产生一些错误。迁移前需要做好足够的检查和测试。下面我们用一个例子说明下NDB引擎的事务情况。我们用

mysql-A>和mysql-B>>区分两个客户端
mysql-A> create table t1 (id int primary key, a int, v varchar(32)) engine ndbcluster;
mysql-A> insert into t1 values (1, 1, ‘a‘), (2, 2, ‘b‘);
mysql-A> begin;
Query OK, 0 rows affected (0.02 sec)

mysql-B>> begin;
Query OK, 0 rows affected (0.00 sec)

mysql-A> update t1 set a = 100 where id = 1;
Query OK, 1 row affected (0.07 sec)
Rows matched: 1  Changed: 1  Warnings: 0 

mysql-B>> select * from t1 where id = 1;
+----+------+------+
| id | a    | v    |
+----+------+------+
|  1 |    1 | a    |
+----+------+------+
1 row in set (0.00 sec)

mysql-A> commit;
Query OK, 0 rows affected (0.00 sec)

mysql-B>> select * from t1 where id = 1;
+----+------+------+
| id | a    | v    |
+----+------+------+
|  1 |  100 | a    |
+----+------+------+
1 row in set (0.00 sec)

可以看到在事务A里面commit前事务B并不能查到更改,但是commit后,B就能查到了更改。而在InnoDB引擎里面,B是永远都查不到外界的任何修改的。如果原先的代码中依赖可重复读,那么迁移时需要修改下。

第八步:分布式权限管理

NDB使用的权限系统就是MySQL这一套,只是到目前为止的权限还是配置在MySQL节点上,并且各个MySQL节点的权限数据可以不同,如果修改了其中一个节点的权限,其他节点的权限并没有修改。为了使所有的MySQL节点的权限是分布式一致的,我们需要做一定的调整。
NDB提供了一个sql脚本share/ndb_dist_priv.sql帮助我们做这件事情,这个脚本会创建几个函数供我们使用,我们在任意一个MySQL节点执行下面这个两行代码即可。

$ bin/mysql -uroot -h127.0.0.1 -P3306
mysql> source share/ndb_dist_priv.sql;
mysql> call mysql.mysql_cluster_move_privileges();

我们来测试下权限情况:
先来删掉两个无密码的用户。在任意一个MySQL节点执行删除语句。

mysql> delete from mysql.user where user=‘‘;

在每个MySQL节点执行下面这条语句刷新权限。

mysql> flush privileges;

在任意一个MySQL节点添加一个用户。

mysql> grant all on *.* to ‘lyw‘@‘%‘ identified by ‘123456‘;

执行后我们尝试用新用户登录

$ bin/mysql -ulyw -h127.0.0.1 -P3306 -p123456
mysql>
$ bin/mysql -ulyw -h127.0.0.1 -P3307 -p123456
mysql>

我们发现两个MySQL节点都已经有了lyw这个新用户,并且已经生效。以后如果使用grant方法进行权限的更改,都能够同步到每一个MySQL节点上。而直接操作user表修改权限,需要flush privileges时,需要在每个MySQL节点上执行flush privileges命令才能全部生效。

第九步:其他集群管理

1. 关闭集群
ndb相关节点关闭用ndb_mgm客户端

ndb_mgm> shutdown
或
bin/ndb_mgm -e shutdown

mysql 节点用mysql的关闭方法

bin/mysqladmin -uroot -h127.0.0.1 -P3306 shutdown
或
sudo service mysql stop

2. 启动集群
前面集群的第一次启动,命令行参数后面都有个--initial,从第二次启动开始,就不需要这个参数了。单机时可以稍微修改下前面的初始化脚本为启动脚本。

$ /home/lyw/db/mysql-cluster/bin/ndb_mgmd --ndb-nodeid=49 --config-dir=/home/lyw/db/mysql-cluster/run/data/49 --config-file=/home/lyw/db/mysql-cluster/run/data/49/config.ini
$ /home/lyw/db/mysql-cluster/bin/ndbmtd --ndb-nodeid=1 --ndb-connectstring=127.0.0.1:1186
。。。。。。

3. 主从复制(热备份)
跟普通的MySQL主从复制一样,只是这里可以在集群A任意选择一台MySQL节点作为主,在集群B任意选择一台MySQL节点作为从,让他们之间建立主从即可,传统方式和GTID方式均可。这样集群A的任何修改都会同步到集群B,当然是异步的。可以作为异地灾备方案。
同样的,可以利用主从配置方法配置出更多结构:一主多从,双主,三主等。

4. NDB冷备份
NDB提供类似mysqldump的在线冷备份功能

ndb_mgm> start backup

执行后,会在数据节点目录下多一个BACKUP目录,备份内容就在该目录下,并自动命名为BACKUP-1。以后执行数字依次递增。数字也可以手动指定,如

ndb_mgm> start backup 20151111
$ ls 1/BACKUP/
BACKUP-1   BACKUP-20151111

内容就备份到BACKUP-20151111目录下了。

以上就是MySQL Cluster的基本功能了,更多的细节功能需要在使用中去逐步发现和体会。

时间: 2024-11-25 10:15:25

MySQL分片高可用集群之MySQL Cluster部署使用的相关文章

MySQL分片高可用集群之Cobar部署使用

Cobar是taobao公司用java开发的分布式MySQL中间件,可以支持数据的分片,且接口与mysql相同,因此可以无缝切换.并且不仅支持Mysql,而且还支持MariaDB哦,对版本的要求也很低,只要5.1以上就可以了.如果公司有较多的java项目,推荐使用.我们就来试试Cobar的集群搭建吧. 第一步:下载Cobar 现在可以从两个官方地址下载,一个是github上:https://github.com/alibaba/cobar  可以下载源码,也可以直接下载编译好的包https://

Mysql Fabric高可用集群分片功能测试

一.MySQL Fabric高可用集群中一台数据库崩溃了,不影响数据的完整性 1.测试前准备 a)   查看group_id-1集群组的服务器状态 mysqlfabric group lookup_servers group_id-1 返回结果: Command : { success = True   return = [{'status': 'PRIMARY', 'server_uuid': '7a45f71d-7934-11e4-9e8c-782bcb74823a', 'mode': 'R

CoroSync + Drbd + MySQL 实现MySQL的高可用集群

Corosync + DRBD + MySQL 构建高可用MySQL集群 节点规划: node1.huhu.com172.16.100.103 node2.huhu.com172.16.100.104 资源名称规划 资源名称:可以是除了空白字符外的任意ACSII码字符 DRBD设备:在双节点上,此DRBD设备文件,一般为/dev/drbdN,主设备号147 磁盘:在双方节点上,各自提供存储设备 网络配置:双方数据同步所使用的网络属性 DRBD从Linux内核2.6.33起已经整合进内核 1.配置

基于keepalived搭建MySQL的高可用集群

http://www.cnblogs.com/ivictor/p/5522383.html 基于keepalived搭建MySQL的高可用集群 MySQL的高可用方案一般有如下几种: keepalived+双主,MHA,MMM,Heartbeat+DRBD,PXC,Galera Cluster 比较常用的是keepalived+双主,MHA和PXC. 对于小公司,一般推荐使用keepalived+双主,简单. 下面来部署一下 配置环境: 角色                          

使用drbd结合corosync实现mysql的高可用集群服务

DRBD:Distributed Replicated Block Dvice 分布式复制块设备,它可以将两个主机的硬盘或者分区做成镜像设备,类似于RAID1的原理,只不过它会将主节点的数据主动通过网络同步到从节点做成镜像,当主节点发生故障,让从节点成为主节点,因为是镜像设备,所以数据不会丢失.corosync在这里的作用就是将drbd通过pacemaker做成高可用服务的资源,以便于主从节点间的自动切换.drbd由于使用各节点之间自身的硬盘设备,因此对于需要共享存储的场景不失为一种节约成本的解

Mysql MHA高可用集群架构

记得之前发过一篇文章,名字叫<浅析MySQL高可用架构>,之后一直有很多小伙伴在公众号后台或其它渠道问我,何时有相关的深入配置管理文章出来,因此,民工哥,也将对前面的各类架构逐一进行整理,然后发布出来.那么今天将来发布的MHA的架构整体规划与配置操作. 简单介绍MHA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,作为MySQL高可用性环境下故障切换和主从提升的高可用软件.在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数

【mysql】高可用集群之MMM

一.复制的常用拓扑结构 复制的体系结构有以下一些基本原则: (1)    每个slave只能有一个master: (2)    每个slave只能有一个唯一的服务器ID: (3)    每个master可以有很多slave: (4)    如果你设置log_slave_updates,slave可以是其它slave的master,从而扩散master的更新. MySQL不支持多主服务器复制(Multimaster Replication)——即一个slave可以有多个master.但是,通过一些

# IT明星不是梦 #MySQL高可用集群之基于MyCat部署HaProxy实现高可用

基于MyCat部署HaProxy实现高可用 在实际项目中, Mycat 服务也需要考虑高可用性,如果 Mycat 所在服务器出现宕机,或 Mycat 服务故障,需要有备机提供服务,需要考虑 Mycat 集群. 一.高可用方案 可以使用 HAProxy+Keepalived配合两台MyCat搭起MyCat集群,实现高可用性. HAProxy实现了MyCat多节点的集群高可用和负载均衡,而 HAProxy自身的高可用则可以通过Keepalived来实现. 架构图: 于上一个博客的环境部署(MySQL

Corosync+Pacemaker+DRBD+MySQL实现MySQL的高可用集群

一.Corosync概述 1.什么是AIS和OpenAIS? AIS是应用接口规范,是用来定义应用程序接口(API)的开放性规范的集合,这些应用程序作为中间件为应用服务提供一种开放.高移植性的程序接口.是在实现高可用应用过程中是亟需的.服务可用性论坛(SA Forum)是一个开放性论坛,它开发并发布这些免费规范.使用AIS规范的应用程序接口(API),可以减少应用程序的复杂性和缩短应用程序的开发时间,这些规范的主要目的就是为了提高中间组件可移植性和应用程序的高可用性. OpenAIS是基于SA