zoukankan      html  css  js  c++  java
  • MySQL Cluster搭建与测试

     

    MySQL Cluster是一个基于NDB Cluster存储引擎的完整的分布式数据库系统。不仅仅具有高可用性,而且可以自动切分数据,冗余数据等高级功能。和Oracle Real Cluster Application不太一样的是,MySQL Cluster 是一个Share Nothing的架构,各个MySQL Server之间并不共享任何数据,高度可扩展以及高度可用方面的突出表现是其最大的特色。虽然目前还只是MySQL家族中的一个新兴产品,但是已经有不少企业正在积极的尝试使用了。但是好像还不是很多,我常常听见人家问这玩意,包括一些企业,虽然该产品还不是很成熟,还有很多缺陷,但是我还是打算学习学习^_^

    MySQL Cluster 介绍

    简单的说,MySQL Cluster 实际上是在无共享存储设备的情况下实现的一种完全分布式数据库系统,其主要通过 NDB Cluster(简称 NDB)存储引擎来实现。MySQL Cluster 刚刚诞生的时候可以说是一个可以对数据进行持久化的内存数据库,所有数据和索引都必须装载在内存中才能够正常运行,但是最新的 MySQL Cluster 版本已经可以做到仅仅将所有索引装载在内存中即可,实际的数据可以不用全部装载到内存中。

    一个 MySQL Cluster 的环境主要由以下三部分组成:
    (1)SQL 层的 SQL 服务器节点(后面简称为 SQL 节点);也就是我们常说的MySQL Server。主要负责实现一个数据库在存储层之上的所有事情,比如连接管理,Query 优化和响应 ,Cache 管理等等,只有存储层的工作交给了NDB 数据节点去处理了。也就是说,在纯粹的MySQL Cluster 环境中的SQL 节点,可以被认为是一个不需要提供任何存储引擎的MySQL服务器,因为他的存储引擎有Cluster 环境中的NDB 节点来担任。所以,SQL 层各MySQL服务器的启动与普通的MySQL Server 启动也有一定的区别,必须要添加ndbcluster参数选项才行。我们可以添加在my.cnf配置文件中,也可以通过启动命令行来指定。

    (2)Storage 层的 NDB 数据节点;也就是上面说的NDB Cluster。最初的NDB是一个内存式存储引擎,当然也会将数据持久化到存储设备上。但是最新的NDB Cluster存储引擎已经改进了这一点,可以选择数据是全部加载到内存中还是仅仅加载索引数据。NDB 节点主要是实现底层数据存储功能,来保存Cluster 的数据。每一个Cluster节点保存完整数据的一个fragment,也就是一个数据分片(或者一份完整的数据,视节点数目和配置而定),所以只要配置得当,MySQL Cluster在存储层不会出现单点的问题。一般来说,NDB 节点被组织成一个一个的NDB Group,一个 NDB Group实际上就是一组存有完全相同的物理数据的NDB节点群。

    上面提到了NDB 各个节点对数据的组织,可能每个节点都存有全部的数据也可能只保存一部分数据,主要是受节点数目和参数来控制的。首先在 MySQL Cluster主配置文件(在管理节点上面,一般为 config.ini)中,有一个非常重要的参数叫NoOfReplicas,这个参数指定了每一份数据被冗余存储在不同节点上面的份数,该参数一般至少应该被设置成2,也只需要设置成2就可以了。因为正常来说,两个互为冗余的节点同时出现故障的概率还是非常小的,当然如果机器和内存足够多的话,也可以继续增大来更进一步减小出现故障的概率。此外,一个节点上面是保存所有的数据还是一部分数据还受到存储节点数目的限制。NDB 存储引擎首先保证NoOfReplicas参数配置的要求来使用存储节点,对数据进行冗余,然后再根据节点数目将数据分段来继续使用多余的NDB节点。分段的数目为节点总数除以NoOfReplicas 所得。

    (3)负责管理各个节点的 Manage 节点主机;管理节点负责整个Cluster集群中各个节点的管理工作,包括集群的配置,启动关闭各节点,对各个节点进行常规维护,以及实施数据的备份恢复等。管理节点会获取整个Cluster环境中各节点的状态和错误信息,并且将各 Cluster 集群中各个节点的信息反馈给整个集群中其他的所有节点。由于管理节点上保存了整个Cluster 环境的配置,同时担任了集群中各节点的基本沟通工作,所以他必须是最先被启动的节点。
    下面是一幅 MySQL Cluster 的基本架构图(出自 MySQL 官方文档手册):

    通过图中我们可以更清晰的了解整个 MySQL Cluster 环境各个节点以及客户端应用之间的关系。

    MySQL Cluster 环境搭建

    搭建 MySQL Cluster首先需要至少一个管理节点主机来实现管理功能,一个SQL节点主机来实现MySQL server功能和两个ndb节点主机实现NDB Cluster的功能。我在这里测试使用双SQL节点来搭建测试环境,具体信息如下:

    1、服务器准备

    a) MySQL节点1             192.168.0.70
    b) MySQL节点2             192.168.0.60
    c) ndb节点1               192.168.0.50
    d) ndb节点2               192.168.0.40
    e) 管理节点                192.168.0.30

    2、软件安装

    测试环境(5台服务器均一样,不是必须的,所以服务器均已关闭iptables和selinux,生产环境请自行开放相关端口)

    [root@localhost ~]# uname -a
    Linux localhost.localdomain 2.6.32-220.el6.x86_64 #1 SMP Tue Dec 6 19:48:22 GMT 2011 x86_64 x86_64 x86_64 GNU/Linux

    安装 MySQL 节点:

    sql节点1: 192.168.0.70
    sql节点2: 192.168.0.60

    下载安装包:mysql-cluster-gpl-7.2.4-linux2.6-x86_64.tar.gz,我这里使用二进制编译好了的,同学们可以自己下载源码包编译。这里操作一台SQL节点服务器,另外一台SQL节点服务器也是相同的,都执行如下安装步骤。

    [root@192.168.0.70 ~]# wget https://downloads.skysql.com/archives/mysql-cluster-gpl-7.2/mysql-cluster-gpl-7.2.4-linux2.6-x86_64.tar.gz
    复制代码
    [root@192.168.0.70 ~]# groupadd mysql
    [root@192.168.0.70 ~]# useradd -r -g mysql mysql
    [root@192.168.0.70 ~]# tar xf mysql-cluster-gpl-7.2.4-linux2.6-x86_64.tar.gz -C /usr/local/
    [root@192.168.0.70 ~]# cd /usr/local/
    [root@192.168.0.70 local]# ln -s mysql-cluster-gpl-7.2.4-linux2.6-x86_64 mysql
    [root@192.168.0.70 local]# cd mysql
    [root@192.168.0.70 mysql]# chown -R mysql .
    [root@192.168.0.70 mysql]# chgrp -R mysql .
    [root@192.168.0.70 mysql]# mkdir /data/mysql
    [root@192.168.0.70 mysql]# chown -R mysql.mysql /data/mysql/
    [root@192.168.0.70 mysql]# cp support-files/my-large.cnf /etc/my.cnf 
    [root@192.168.0.70 mysql]# /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/data/mysql/ --basedir=/usr/local/mysql
    复制代码
    [root@192.168.0.70 mysql]# chown -R root .
    [root@192.168.0.70 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
    [root@192.168.0.70 mysql]# chmod 755 /etc/init.d/mysqld 
    [root@192.168.0.70 mysql]# echo "export PATH=$PATH:/usr/local/mysql/bin" >> /root/.bash_profile    #添加环境变量,执行命令方便一点
    [root@192.168.0.70 mysql]# source /root/.bash_profile 

    SQL节点配置

    修改/etc/my.cnf配置文件,追加如下配置

    复制代码
    [mysqld]
    datadir=/data/mysql
    basedir= /usr/local/mysql
    ndbcluster                         # 运行NDB存储引擎
    ndb-connectstring=192.168.0.30     # 管理节点
    [MYSQL_CLUSTER]
    ndb-connectstring=192.168.0.30     #管理节点
    复制代码

    NDB节点安装(数据节点)

    数据节点1: 192.168.0.50
    数据节点2: 192.168.0.40

    如果希望尽可能的各环境保持一致,建议在NDB节点也和SQL节点一样安装整个带有 NDB Cluster 存储引擎的MySQL Server。(NDB节点可以不用初始化数据,自己已经测试,但是我依然会初始化)安装细节和上面的SQL节点完全一样。两台NDB节点操作一样,如下:

    复制代码
    [root@192.168.0.40 ~]# groupadd mysql
    [root@192.168.0.40 ~]# useradd -r -g mysql mysql
    [root@192.168.0.40 ~]# tar xf mysql-cluster-gpl-7.2.4-linux2.6-x86_64.tar.gz -C /usr/local/
    [root@192.168.0.40 ~]# cd /usr/local/
    [root@192.168.0.40 local]# ln -s mysql-cluster-gpl-7.2.4-linux2.6-x86_64 mysql
    [root@192.168.0.40 local]# cd mysql
    [root@192.168.0.40 mysql]# chown -R mysql .
    [root@192.168.0.40 mysql]# chgrp -R mysql .
    [root@192.168.0.40 mysql]# mkdir /data/mysql
    [root@192.168.0.40 mysql]# chown -R mysql.mysql /data/mysql/
    [root@192.168.0.40 mysql]# /usr/local/mysql/scripts/mysql_install_db --user=mysql --datadir=/data/mysql/ --basedir=/usr/local/mysql
    复制代码
    复制代码
    [root@192.168.0.40 mysql]# chown -R root .
    [root@192.168.0.40 mysql]# cp support-files/my-large.cnf /etc/my.cnf 
    [root@192.168.0.40 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
    [root@192.168.0.40 mysql]# chmod 755 /etc/init.d/mysqld 
    [root@192.168.0.40 mysql]# echo "export PATH=$PATH:/usr/local/mysql/bin" >> /root/.bash_profile
    [root@192.168.0.40 mysql]# source /root/.bash_profile 
    [root@192.168.0.40 mysql]# 
    复制代码
    [root@192.168.0.40 mysql]# mkdir /data/mysql-cluster/data -p

    上面这个目录用来存放NDB节点的数据,在管理节点里面也要配置为该目录,配置其他的目录会报错,说无法创建各种日志文件。上面提到的/data/mysql是用来在没使用NDB时存放的数据,和平时我们使用的mysql没有区别。

    NDB节点配置(数据节点):

    和SQL节点是一样的,修改/etc/my.cnf,追加如下内容:

    复制代码
    [mysqld]
    datadir=/data/mysql
    basedir= /usr/local/mysql
    ndbcluster                         # 运行NDB存储引擎
    ndb-connectstring=192.168.0.30     # 管理节点
    [MYSQL_CLUSTER]
    ndb-connectstring=192.168.0.30     #管理节点
    复制代码

    安装管理节点

    管理节点所需要的安装更简单,实际上只需要 ndb_mgm 和ndb_mgmd两个程序即可,这两个可执行程序可以在上面的MySQL节点的MySQL安装目录中的bin目录下面找到。将这两个程序copy到管理节点上面合适的位置(自行考虑,我一般会放在/usr/local/mysql/bin下面)并且添加环境变量就可以了。

    复制代码
    [root@192.168.0.30 ~]# mkdir /usr/local/mysql/bin -p                                      
    [root@192.168.0.30 ~]# scp 192.168.0.70:/usr/local/mysql/bin/ndb_mgm /usr/local/mysql/bin/
    root@192.168.0.70's password: 
    ndb_mgm                                                                                                            100% 6213KB   6.1MB/s   00:00    
    [root@192.168.0.30 ~]# scp 192.168.0.70:/usr/local/mysql/bin/ndb_mgmd /usr/local/mysql/bin/
    root@192.168.0.70's password: 
    ndb_mgmd                                                                                                           100%   14MB   6.9MB/s   00:02    
    [root@192.168.0.30 ~]# echo "export PATH=$PATH:/usr/local/mysql/bin" >> /root/.bash_profile
    [root@192.168.0.30 ~]# source /root/.bash_profile 
    [root@192.168.0.30 ~]# 
    复制代码

    管理节点配置:

    1.在/data/创建目录mysql-cluster,该目录会存放相关日志文件,以及pid号。并在目录中创建配置文件config.ini

    [root@192.168.0.30 ~]# mkdir /data/mysql-cluster
    [root@192.168.0.30 ~]# cd /data/mysql-cluster/
    [root@192.168.0.30 mysql-cluster]# touch config.ini

    2.根据我们上面提供的环境,config.ini文件配置如下(在安装目录下面也有样例配置文件可以参考),详细的配置参数请阅读这里MySQL Cluster配置详解

    复制代码
    [root@192.168.0.30 ~]# cat /data/mysql-cluster/config.ini 
    [NDBD DEFAULT]
    NoOfReplicas=1                        #每个数据节点的镜像数量,通常最低设置为2,否则就没有意义了,这里是方便后面测试。
    DataMemory=64M                        #每个数据节点中给数据分配的内存
    IndexMemory=16M                       #每个数据节点中给索引分配的内存
    #管理节点
    [NDB_MGMD]
    nodeid=1
    hostname=192.168.0.30                 #管理节点ip
    datadir=/data/mysql-cluster           #管理节点数据目录,存放相关日志,以及pid文件
    #第一个 ndbd 节点:
    [NDBD]
    nodeid=2
    hostname=192.168.0.50                 #数据节点ip地址
    datadir=/data/mysql-cluster/data
    #第二个 ndbd 节点:
    [NDBD]
    nodeid=3
    hostname=192.168.0.40
    datadir=/data/mysql-cluster/data     #NDB点数据存放目录
    # SQL node options:
    [MySQLD]
    nodeid=4
    hostname=192.168.0.70                #SQL节点ip地址
    [MySQLD]
    nodeid=5
    hostname=192.168.0.60
    [MySQLD]                             这里保留了一个空节点。否则停止NDB会报错:No free node id found for ndbd(NDB).
    [root@192.168.0.30 ~]#
    复制代码

    在上面的配置文件中,包括很多的组,组名用"[]"括起来,这里我们最关心的是3类节点组的配置,分别定义如下:

    [NDB_MGMD] 表示管理节点的配置,只能有一个。

    [NDBD DEFAULT] 表示每个数据节点的默认配置,在每个节点的[NDBD]中不用再写这些选项,只能有一个。

    [NDBD] 表示每个数据节点的配置,可以有多个。

    [MYSQLD] 表示SQL节点的配置,可以有多个,分别写上不同的SQL节点的ip地址;也可以不用写,只保留一个空节点,表示任意一个ip地址都可以进行访问。此节点的个数表明了可以用来连接数据节点的SQL节点总数。

    每个节点都有一个独立的id号,可以填写,比如nodeid=2,(老版本使用id,新版本已经不使用id标识了)也可以不用填写,系统会按照配置文件的填写顺序自动分配。

    开始使用Cluster

    上面我们都已经配置完毕了,下面说明启动,关闭和使用方法

    启动顺序为:管理节点->数据节点->SQL节点(很重要)

    (1)启动管理节点:

    复制代码
    [root@192.168.0.30 ~]# ndb_mgmd -f /data/mysql-cluster/config.ini
    MySQL Cluster Management Server mysql-5.5.19 ndb-7.2.4
    [root@192.168.0.30 ~]# netstat -ntlp | grep 1186
    tcp        0      0 0.0.0.0:1186                0.0.0.0:*                   LISTEN      1329/ndb_mgmd       
    [root@192.168.0.30 ~]# ps -ef | grep ndb_mgmd | grep -v  grep
    root      1329     1  0 21:50 ?        00:00:00 ndb_mgmd -f /data/mysql-cluster/config.ini
    [root@192.168.0.30 ~]# 
    复制代码

    (2)启动NDB(数据节点)

    注意:只是在第一次启动或在备份/恢复或配置变化后重启ndbd时,才加–initial参数!原因在于,该参数会使节点删除由早期ndbd实例创建的,用于恢复的任何文件,包括用于恢复的日志文件。

    [root@192.168.0.40 ~]# ndbd --initial
    2014-04-15 21:51:51 [ndbd] INFO     -- Angel connected to '192.168.0.30:1186'
    2014-04-15 21:51:51 [ndbd] INFO     -- Angel allocated nodeid: 3
    [root@192.168.0.40 ~]# 
    [root@192.168.0.50 ~]# ndbd --initial 
    2014-04-15 21:52:29 [ndbd] INFO     -- Angel connected to '192.168.0.30:1186'
    2014-04-15 21:52:29 [ndbd] INFO     -- Angel allocated nodeid: 2
    [root@192.168.0.50 ~]# 

    查看是否有相关进程:

    [root@192.168.0.50 ~]# ps -ef | grep ndbd | grep -v grep
    root      1879     1  0 21:52 ?        00:00:00 ndbd --initial
    root      1880  1879  2 21:52 ?        00:00:03 ndbd --initial
    [root@192.168.0.50 ~]# 
    [root@192.168.0.40 ~]# ps -ef | grep ndbd | grep -v grep
    root      2266     1  0 21:51 ?        00:00:00 ndbd --initial
    root      2267  2266  1 21:51 ?        00:00:04 ndbd --initial
    [root@192.168.0.40 ~]# 

    ndbd进程是使用NDB存储引擎处理表中数据的进程。通过该进程,存储节点能够实现分布式事务管理,节点恢复,在线备份相关任务。

    (3)启动SQL节点(启动mysql服务)

    本文中是192.168.0.60,192.168.0.70两个节点

    [root@192.168.0.60 ~]# /etc/init.d/mysqld start
    Starting MySQL                                             [  OK  ]
    [root@192.168.0.60 ~]# 
    [root@192.168.0.70 ~]# /etc/init.d/mysqld start
    Starting MySQL.....                                        [  OK  ]
    [root@192.168.0.70 ~]# 

    (4)节点全部启动成功后,在管理节点使用ndb_mgm工具的show命令查看集群状态:

    复制代码
    [root@192.168.0.30 ~]# 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.0.50  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 0, Master)
    id=3    @192.168.0.40  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 1)
    
    [ndb_mgmd(MGM)] 1 node(s)
    id=1    @192.168.0.30  (mysql-5.5.19 ndb-7.2.4)
    
    [mysqld(API)]   3 node(s)
    id=4    @192.168.0.70  (mysql-5.5.19 ndb-7.2.4)
    id=5    @192.168.0.60  (mysql-5.5.19 ndb-7.2.4)
    id=6 (not connected, accepting connect from any host)
    
    ndb_mgm> 
    复制代码

    ndb_mgm工具是ndb_mgmd(MySQL Cluster Server)的客户端管理工具,通过该工具可以方便的检查Cluster的状态,启动备份,关闭等功能。更详细的方法可以通过ndb_mgm --help命令来进行查看。

    从上面显示的状态可以看出如下信息。

    (1)集群目前的管理服务器端口是1186

    Connected to Management Server at: localhost:1186

    (2)集群的数据节点(NDB)有2个,详细信息:

    [ndbd(NDB)]     2 node(s)
    id=2    @192.168.0.50  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 0, Master)
    id=3    @192.168.0.40  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 1)

    (3)集群的管理节点有一个,详细信息:

    [ndb_mgmd(MGM)] 1 node(s)
    id=1    @192.168.0.30  (mysql-5.5.19 ndb-7.2.4)

    (4)SQL节点有3个,目前处于连接状态的有2个,详细信息:

    [mysqld(API)]   3 node(s)
    id=4    @192.168.0.70  (mysql-5.5.19 ndb-7.2.4)
    id=5    @192.168.0.60  (mysql-5.5.19 ndb-7.2.4)
    id=6 (not connected, accepting connect from any host)

    到这里MySQL Cluster就已经搭建完成了。接下来就到测试时间咯。^_^

    MySQL Cluster 高可用测试

    成功启动后,下面来测试一下Cluster的功能。如果要使用cluster,则表的引擎必须为NDB,其他类型存储引擎的数据不会保存到数据节点中。对于cluster的一个重要功能就是防止单点故障。我们下面对这些问题分别来进行测试。

    1.NDB存储引擎测试

    (1)在任意一个SQL节点(我这里选择192.168.0.70)的test库中创建测试表t1,设置存储引擎为NDB,并插入两条测试数据:

    复制代码
    mysql> create table t1 (
        -> id int,
        -> name varchar(20)
        -> )
        -> engine=ndb
        -> ;
    Query OK, 0 rows affected (0.44 sec)
    
    mysql> insert into t1 select 1,'yayun';
    Query OK, 1 row affected (0.11 sec)
    Records: 1  Duplicates: 0  Warnings: 0
    
    mysql> insert into t1 select 1,'atlas';
    Query OK, 1 row affected (0.03 sec)
    Records: 1  Duplicates: 0  Warnings: 0
    
    mysql> 
    复制代码

    (2)在另外一个SQL节点(192.168.0.60)查询test库中t1表,结果如下:

    复制代码
    mysql> select * from test.t1;
    +------+-------+
    | id   | name  |
    +------+-------+
    |    1 | atlas |
    |    1 | yayun |
    +------+-------+
    2 rows in set (0.08 sec)
    
    mysql> 
    复制代码

    显然,两个SQL节点查询的数据时一致的。

    (3)在SQL节点192.168.0.70上把测试表t1引擎改为MyISAM,再次插入测试数据:

    复制代码
    mysql> alter table t1 engine=myisam;
    Query OK, 2 rows affected (0.50 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> insert into t1 select 2,'good boy';
    Query OK, 1 row affected (0.00 sec)
    Records: 1  Duplicates: 0  Warnings: 0
    
    mysql> 
    复制代码

    (4)在SQL节点192.168.0.60上再次查询表t1,结果如下:

    复制代码
    mysql> select * from t1;
    ERROR 1146 (42S02): Table 'test.t1' doesn't exist
    mysql> show tables;
    Empty set (0.04 sec)
    
    mysql> 
    复制代码

    直接报错,说表不存在了。(老版本是报ERROR 1412:Table definition ha  changed,please retry transaction)

    (5)我们再次改回NDB引擎。

    mysql> alter table t1 engine=ndb;
    Query OK, 3 rows affected (0.25 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> 

    (6)再次进行查询如下:

    复制代码
    mysql> select * from t1;
    +------+----------+
    | id   | name     |
    +------+----------+
    |    1 | atlas    |
    |    2 | good boy |
    |    1 | yayun    |
    +------+----------+
    3 rows in set (0.02 sec)
    
    mysql> 
    复制代码

    发现表t1的数据再次同步到了数据节点。所有SQL节点又都可以正常查询数据。

    2.单点故障测试

    对于任意一种节点,都存在单点故障的可能性。在cluster的设置过程中,应该尽量对每一类节点设置冗余,以防止单点故障发生时造成的应用终端。对于管理节点,一般不需要特殊的配置,只需要将管理工具和配置文件防止多台服务器上即可。下面我们测试一下SQL节点和NDB(数据节点)的单点故障。

    SQL节点发生单点故障

    对于上面的测试环境中,我们设置了两个SQL节点,应用从两个节点对数据访问都可以得到一致的结果。如果有一个节点故障,系统会正常运行吗?我们测试便知。

    (1)将SQL节点192.168.0.60上的MySQL服务停止:

    [root@192.168.0.60 ~]# /etc/init.d/mysqld stop
    Shutting down MySQL..                                      [  OK  ]
    [root@192.168.0.60 ~]# 

    (2)查看cluster状态:

    复制代码
    ndb_mgm> show
    Cluster Configuration
    ---------------------
    [ndbd(NDB)]     2 node(s)
    id=2    @192.168.0.50  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 0, Master)
    id=3    @192.168.0.40  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 1)
    
    [ndb_mgmd(MGM)] 1 node(s)
    id=1    @192.168.0.30  (mysql-5.5.19 ndb-7.2.4)
    
    [mysqld(API)]   3 node(s)
    id=4    @192.168.0.70  (mysql-5.5.19 ndb-7.2.4)
    id=5 (not connected, accepting connect from 192.168.0.60)
    id=6 (not connected, accepting connect from any host)
    
    ndb_mgm> 
    复制代码

    可以发现SQL节点192.168.0.60已经断开,但是另外一个SQL节点192.168.0.70仍然处于正常状态。

    (3)从SQL节点192.168.0.70上查看表t1,结果如下:

    复制代码
    mysql> select * from t1;
    +------+----------+
    | id   | name     |
    +------+----------+
    |    2 | good boy |
    |    1 | yayun    |
    |    1 | atlas    |
    +------+----------+
    3 rows in set (0.01 sec)
    
    mysql> 
    复制代码

    显然,SQL节点的单点故障并没有引起数据查询的故障。对于应用来说,需要改变的就是将以前对故障节点的访问改为对非故障节点的访问(SQL节点前面可以挂LVS,然后做各种检测)

    NDB(数据节点)的单点故障

    在这个测试环境中,数据节点也是两个,那么他们对数据的存储是互相镜像还是一份数据分成几块存储呢?(类似磁盘阵列RAID1还是RAID0)?这个答案关键在于配置文件中[NDBD DEFAULT]组中的NoOfReplicas参数,如果这个参数等于1,表示只有一份数据,但是分成N块分别存储在N个数据节点上,如果该值等于2,则表示数据被分成N/2,每块数据都有两个备份,这样即使有任意一个节点发生故障,只要它的备份节点正常,数据就可以正常查询。

    在下面的例子中,先将两个数据节点之一停止,访问表t1,看能否正常访问;然后将NoOfReplicas配置改为2,这时,数据节点实际上已经互为镜像,保存了两份。这时再停止任意一个数据节点,看是否能访问表t1。

    (1)将数据节点192.168.0.40上的NDB进程停止:

    复制代码
    [root@192.168.0.40 ~]# ps -ef | grep ndbd
    root      2266     1  0 21:51 ?        00:00:00 ndbd --initial
    root      2267  2266  1 21:51 ?        00:01:03 ndbd --initial
    root      2368  1300  0 23:06 pts/0    00:00:00 grep ndbd
    [root@192.168.0.40 ~]# pkill -9 ndbd
    [root@192.168.0.40 ~]# ps -ef | grep ndbd
    root      2371  1300  0 23:07 pts/0    00:00:00 grep ndbd
    [root@192.168.0.40 ~]# 
    复制代码

    (2)在任意节点,这里是192.168.0.70查看表t1的数据:

    mysql> select * from t1;
    ERROR 1296 (HY000): Got error 157 'Unknown error code' from NDBCLUSTER
    mysql> 

    显然无法访问表t1的数据了。

    (3)将配置文件中的NoOfReplicas改为2,按照前面的步骤重新启动集群:

    [root@192.168.0.30 ~]# grep 'NoOfReplicas' /data/mysql-cluster/config.ini 
    NoOfReplicas=2                        #每个数据节点的镜像数量
    [root@192.168.0.30 ~]# 

    最后发现无法启动数据节点,查看错误日志如下:

    复制代码
    Time: Tuesday 15 April 2014 - 23:22:51
    Status: Permanent error, external action needed
    Message: Invalid configuration received from Management Server (Configuration error)
    Error: 2350
    Error data: Illegal configuration change. Initial start needs to be performed  when changing no of replicas (1 != 2)
    Error object: DBDIH (Line: 4820) 0x00000002
    Program: ndbd
    复制代码

    看来NoOfReplicas参数无法临时更改,我们开始就需要设置好,不要到后面才想到更改,那时就悲剧了。

    如果重新ndbd --initial,将会丢失所有数据,好吧,记住这个坑,下次就不会踩进去了。

    [root@192.168.0.40 ~]# ndbd --initial
    2014-04-15 23:36:08 [ndbd] INFO     -- Angel connected to '192.168.0.30:1186'
    2014-04-15 23:36:08 [ndbd] INFO     -- Angel allocated nodeid: 3
    [root@192.168.0.40 ~]# 
    [root@192.168.0.50 ~]# ndbd --initial
    2014-04-15 23:38:50 [ndbd] INFO     -- Angel connected to '192.168.0.30:1186'
    2014-04-15 23:38:50 [ndbd] INFO     -- Angel allocated nodeid: 2
    [root@192.168.0.50 ~]# 

    重新建表插入数据再测试吧,囧..............

    复制代码
    mysql> create table t1 (name varchar(20))engine=ndb;
    Query OK, 0 rows affected (0.31 sec)
    
    mysql> insert into t1 select 'yayun';
    Query OK, 1 row affected (0.04 sec)
    Records: 1  Duplicates: 0  Warnings: 0
    
    mysql> insert into t1 select 'atlas';
    Query OK, 1 row affected (0.06 sec)
    Records: 1  Duplicates: 0  Warnings: 0
    
    mysql> select * from t1;
    +-------+
    | name  |
    +-------+
    | atlas |
    | yayun |
    +-------+
    2 rows in set (0.01 sec)
    
    mysql> 
    复制代码

    查看cluster状态:

    复制代码
    [root@192.168.0.30 ~]# 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.0.50  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 0, Master)
    id=3    @192.168.0.40  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 0)
    
    [ndb_mgmd(MGM)] 1 node(s)
    id=1    @192.168.0.30  (mysql-5.5.19 ndb-7.2.4)
    
    [mysqld(API)]   3 node(s)
    id=4    @192.168.0.70  (mysql-5.5.19 ndb-7.2.4)
    id=5    @192.168.0.60  (mysql-5.5.19 ndb-7.2.4)
    id=6 (not connected, accepting connect from any host)
    
    ndb_mgm> 
    复制代码

    一切正常。我们现在停止NDB节点192.168.0.50,看是否还能访问数据:

    复制代码
    [root@192.168.0.50 ~]# ps -ef | grep ndbd
    root      2119     1  0 23:38 ?        00:00:00 ndbd --initial
    root      2120  2119  2 23:38 ?        00:00:10 ndbd --initial
    root      2161  1275  0 23:45 pts/0    00:00:00 grep ndbd
    [root@192.168.0.50 ~]# pkill -9 ndbd
    [root@192.168.0.50 ~]# ps -ef | grep ndbd
    root      2164  1275  0 23:45 pts/0    00:00:00 grep ndbd
    [root@192.168.0.50 ~]# 
    复制代码
    复制代码
    ndb_mgm> show
    Cluster Configuration
    ---------------------
    [ndbd(NDB)]     2 node(s)
    id=2 (not connected, accepting connect from 192.168.0.50)
    id=3    @192.168.0.40  (mysql-5.5.19 ndb-7.2.4, Nodegroup: 0, Master)
    
    [ndb_mgmd(MGM)] 1 node(s)
    id=1    @192.168.0.30  (mysql-5.5.19 ndb-7.2.4)
    
    [mysqld(API)]   3 node(s)
    id=4    @192.168.0.70  (mysql-5.5.19 ndb-7.2.4)
    id=5    @192.168.0.60  (mysql-5.5.19 ndb-7.2.4)
    id=6 (not connected, accepting connect from any host)
    
    ndb_mgm> 
    复制代码

    看见只有一个NDB节点在运行。

    访问任意SQL节点查询数据,我这里用192.168.0.70,查询结果如下:

    复制代码
    mysql> select * from t1;
    +-------+
    | name  |
    +-------+
    | atlas |
    | yayun |
    +-------+
    2 rows in set (0.01 sec)
    
    mysql> 
    复制代码

    显然挂掉一个NDB节点不影响我们正常的数据查询,数据节点的冗余同样防止了单点故障。

    MySQL Cluster集群的关闭

    关闭顺序:SQL节点->数据节点->管理节点(在MySQL Cluster环境中,NDB节点和管理节点的关闭都可以在管理节点的管理程序中完成,也可以分节点关闭,但是SQL节点却没办法。所以,在关闭整个MySQL Cluster环境或者关闭某个SQL节点的时候,首先必须到SQL节点主机上来关闭SQL节点程序。关闭方法和MySQL Server的关闭一样。)

    (1)SQL节点关闭

    [root@192.168.0.70 ~]# /etc/init.d/mysqld stop
    Shutting down MySQL..                                      [  OK  ]
    [root@192.168.0.70 ~]# 

    (2)(NDB)数据节点关闭

    [root@192.168.0.50 ~]# ndbd stop
    2014-04-15 23:54:36 [ndbd] INFO     -- Angel connected to '192.168.0.30:1186'
    2014-04-15 23:54:36 [ndbd] INFO     -- Angel allocated nodeid: 2
    [root@192.168.0.50 ~]# 

    (3)管理节点关闭

    复制代码
    ndb_mgm> shutdown
    Node 2: Cluster shutdown initiated
    Node 3: Cluster shutdown initiated
    3 NDB Cluster node(s) have shutdown.
    Disconnecting to allow management server to shutdown.
    Node 3: Node shutdown completed.
    ndb_mgm> 
    复制代码

    总结:

    慢慢的学习过程中,踩了不少坑,比如参数NoOfReplicas无法临时更改,管理节点配置文件中如果不多预留一个[MySQLD],在停止NDB节点时会报错,以及配置文件中的[NDBD]段落中的datadir指定的目录在数据节点的服务器上面要存在。以及selinux,iptables等相关问题。总之收获满满。后续的文章中将会介绍mysql cluster的日常维护,包括数据备份,数据恢复,日志管理等。MySQL Cluster的核心在于NDB Cluster存储引擎,不仅对数据进行了水平切分,还对数据进行了跨节点冗余。既解决了数据库的扩展问题,同时也在很大程度上提高了数据库整体可用性。

  • 相关阅读:
    linux高可用集群(HA)原理详解
    【C#/WPF】修改图像的DPI、Resolution
    【C#】图像的变形/变换/扭曲。用Emgu或YLScsFreeTransform(FreeImageTransformation)或MagickImage
    【C#】遍历List列表的同时,移除访问到的元素
    【WPF】动态设置Binding的ConverterParameter转换器参数
    【SVN/Visual Studio】清除/更换AnkhSVN的用户登录信息
    【C#】允许泛型方法<T>返回空值Null
    【C#】时间日期格式转换:long和DateTime相互转换
    【C#/WPF】ListView的MVVM例子,及禁止拖动ListView的头部Header
    【C#/WPF】保存BitmapImage数据到文件中
  • 原文地址:https://www.cnblogs.com/drizzle-xu/p/10233191.html
Copyright © 2011-2022 走看看