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以内),只要将DataMemory和IndexMemory改大一点就好了。
我们可能需要将数据配置到其他路径下,就修改下对应的路径。
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的基本功能了,更多的细节功能需要在使用中去逐步发现和体会。