MYSQL CLUSTER 方案介绍
本文的大致框架来自 罗志威、黄川的报告, 在它的基础上进行简化和修改一些bug并且添加了主从复制的章节,最后做出该文档
MySQL Cluster 是 MySQL 适合于分布式计算环境的高实用、高冗余版本。它采用了 NDB Cluster 存储引擎,允许在 1 个 Cluster 中运行多个 MySQL 服务器。现在 mysql cluster 被独立出来 , 作为一个专门的产品进行运营 , mysql-server-5.6+ 就不在存在对 mysql cluster 的支持,需要独立下载 cluster 包进行安装 .
推荐在 Linux 下完成安装 , 如果一定要在 Windows 上的话 , 则需要考虑使用解压版本的进行安装 , 且路径中不能带有空格字符 .
测试环境信息
服务器信息
项 |
项 值 |
操作系统 |
Ubuntu 14.04 32 位 |
Mysql Cluster 版本 |
mysql-cluster-gpl-7.3.5-debian6.0-i686 |
内存 |
2G |
CPU |
2.20 双核 |
网络环境 |
100M 局域网 |
部署 |
1 个数据节点, 1 SQL 节点, 1 管理节点 |
管理节点信息
机器 IP |
数据节点编号 |
192.168.1.37 |
1 |
机器 IP |
数据节点编号 |
192.168.1.37 |
2 |
数据节点信息
SQL 节点信息
机器 IP |
数据节点编号 |
192.168.1.37 |
3 |
机器安装环境
机器 IP |
用户名、密码 |
安装路径 |
路径说明 |
192.168.1.37 |
root/root |
/root/mysql/mysqlc |
mysql cluster 目录 |
/root/mysql/data/mysqld_data |
sql 节点数据路径 |
||
/root/mysql/data/ndb_data |
数据节点数据路径 |
||
/root/mysqldata/mgmd_data |
管理节点数据 |
||
/root/mysql/conf |
配置文件路径 |
节点说明
SQL 节点:
这是用来访问簇数据的节点。对于 MySQL 簇,客户端节点是使用 NDB 簇存储引擎的传统 MySQL 服务器。典型情况下, SQL 节点是使用命令 mysqld – -ndbcluster 启动的,或将 ndbcluster 添加到 my.cnf 后使用 mysqld 启动。簇中所有的表结构都保存在 mysql 节点中,为了保证每个数据节点中数据分布均匀,在进行数据插入的时候 sql 节点采用了 表分片的策略将数据均匀分配到不同的数据节点上。
数据节点:
这类节点用于保存簇的数据。数据节点的数目与副本的数目相关,是片段的倍数。例如,对于两个副本,每个副本有两个片段,那么就有 1 个数据节点(在测试环境中就采用了两个副本两个片段的策略,故有 1 个数据节点, ( ndb_mgmd 配置文件中 NoOfReplicas 属性配置 ) 此时管理节点会将数据节点进行分组, 数据节点是用命令 ndbd启动的。
各个数据节点中都用两个检查点:本地检查点、全局检查点。本地检查点的目的是为了将内存中的数据和磁盘上的数据进行同步。全局检查点是在各节点中进行通讯,以保证事物的一致性。
管理节点:
管理节点是管理数据节点和 sql 节点的工具,在系统正常运行期间停止管理节点对整个系统的运行不会有任何影响。在管理节点提供了数据节点和 sql 节点的全局配置信息,包括数据、索引所占用内存大小、数据存放的目录信息、各个节点 ip 信息等。通过管理节点可以启动和停止节点、启动和停止消息跟踪(仅对调试版本)、显示节点版本和状态、启动和停止备份等的命令。
安装配置说明
软件下载说明:
1、 软件下载地址: http://www.mysql.com/downloads/cluster/
2、 安装版本: mysql-cluster-gpl-7.3.5-debian6.0-i686
安装步骤说明:
一、 管理节点安装
1、 登陆系统建立目录结构
mkdir –p /root/mysql/data/mgmd_data
mkdir /root/mysql/data/ndb_data
mkdir /root/mysql/data/mysqld_data
mkdir /root/mysql/conf
mkdir /root/mysql/mysqlc
2、 安装 mysqlc
dpkg –i mysql-cluster-gpl-7.3.5-debian6.0-i686
mv /opt/mysql/server-5.6/* /root/mysql/mysqlc
3、 设置环境变量
在 .bashrc 文件的 PATH 后面加入如下信息 /root/mysql/mysqlc/bin
vim ~/.bashrc
加入后,文件如下所示
加入后执行如下命令使配置生效:
. ~/.bashrc
4、 在 /root/mysql/conf 目录下建立 mgmd.conf文件,然后在文件中配置各节点信息 , 如下所示:
[ndbd default]
NoOfReplicas=1 #设置冗余的分数(一个sql节点对应几个data节点)
DataMemory=100M #指定存放数据的内存段大小
IndexMemory=50M#制定索引的内存段大小
LockPagesInMainMemory=1 #将进程锁定在内存中
TimeBetweenLocalCheckpoints=20#本地检查点时间间隔。
TimeBetweenGlobalCheckpoints=1000#全局检查点时间间隔。
TimeBetweenEpochs=100#复制同步的间隔时间
TimeBetweenWatchdogCheckInitial=60000
MaxNoOfTables=1024 #该参数为作为整体的簇设置了最大表对象数目
MaxNoOfOrderedIndexes=2048 #设置哈希索引在系统中同一时间被使用总数
MaxNoOfUniqueHashIndexes=512 #设置最大的唯一索引的总数
MaxNoOfAttributes=20480 #定义了可在簇中定义的属性数目
MaxNoOfTriggers=10240#设置簇中触发程序对象的最大数目
DiskCheckpointSpeedInRestart=100M #重启的时候本地检查点期间发送到磁的速度
NoOfFragmentLogFiles=16 #该参数用于设置节点的REDO日志文件的个数
RedoBuffer=65M #设置redo日志缓存
MaxNoOfConcurrentOperations=500000 #设置事务中同时更新的最大记录数
MaxNoOfExecutionThreads=8#线程的数量
BatchSizePerLocalScan=512 #该参数用于计算锁定记录的数目
SharedGlobalMemory=20M #这个参数设置用于日志缓冲、磁盘操作和表空间...
DiskPageBufferMemory=80M #设置硬盘上的缓存页的空间总量的大小
#[tcp default]
#portnumber=2202#通讯端口(现在无效)
[ndb_mgmd]
hostname=192.168.1.39#管理节点IP
datadir=/root/mysql/data/mgmd_data#管理节点数据目录
Nodeid=1#管理节点编号
[ndbd]
hostname=192.168.1.39#数据节点IP
datadir=/root/mysql/data/ndb_data#数据节点数据目录
NodeId=2#数据节点编号
[mysqld]
hostname=192.168.1.39#sql节点IP
NodeId=3#sql节点编号
5、 管理节点启动命令
第一次启动:
ndb_mgmd -f /root/mysql/conf/mgmd.conf --configdir=/root/mysql/conf/ --initial
非第一次启动:
ndb_mgmd -f /root/mysql/conf/mgmd.conf --configdir=/root/mysql/conf/
注意: 路径不能使用相对地址, 需要使用绝对地址.
启动后可以输入 ndb_mgm 命令进入管理控制台,然后输入 show 命令查看节点状态,如下图所示:
二、 数据节点安装
1、 管理节点启动命令
第一次启动命令:
ndbd -c 192.168.1.39:1186 --initial
非第一次启动命令:
ndbd -c 192.168.1.39:1186
注意:如果在启动的时候加入 initial 参数,那么会将用于备份和还原的日志信息都会清空,也就是说会将数据库中的数据删除掉。在启动的时候一定要注意。
三、 SQL 节点安装
1、 在 /root/mysql/conf 目录下建立 mys qld.conf 文件,然后在文件中配置各节点信息 , 如下所示:
[mysqld]
ndbcluster
ndb-wait-setup=1 #等待data节点创建数据表时间限制
datadir=/root/mysql/data/mysqld_data
basedir=/root/mysql/mysqlc
socket=/tmp/mysql.sock #Windows注释掉
skip-name-resolve #跳过域名解析
port=3306
#ndb-connectstring=192.168.1.39
[mysql_cluster]
ndb-connectstring=192.168.1.39 #指向管理节点
2、 第一次安装 sql 节点后要执行如下脚本,该脚本只执行一次。
cd /root/mysql/mysqlc
./scripts/mysql_install_db --no-defaults --datadir=/root/mysql/data/mysqld_data/ --basedir=.
3、 sql节点启动命令
mysqld --defaults-file=/root/mysql/conf/mysqld.conf --user=root
4、 权限配置
本地权限配置 :
mysqladmin –uroot –proot
非本机访问权限配置 :
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;
关闭mysql cluster
数据节点 和 管理节点通过进入 ndb_mgm , 输入shutdown 来关闭
sql节点通过 mysqladmin -uroot -p shutdown 来关闭
方案测试
一、 测试工具
压力测试工具使用的是 mysql 自带的 mysqlslap 压力测试工具。
mysqlslap:
mysql 自带的一个压力测试工具,自 5.1.4 版本之后的 MySQL client 包含了此工具,下载 mysql client rpm 包安装后可直接使用。在 使用 mysqlslap 的时候,可以指定 sql 语句或者是包含 sql 语句的文件,如果是文件,那么文件中的每一行至少有一个语句(不能一个 sql 语句分成 两行或多行),因为默认的分隔符( delimiter )是换行符,当然,你也可以手动重置新的分隔符。另外,你也不能在文件中添加注 释, mysqlslap 不支持。
Mysqlslap参数说明 :
--concurrency 代表并发数量,多个可以用逗号隔开,当然你也可以用自己的分隔符隔 开,这个时候要用到 --delimiter 开关。
--engines 代表要测试的引擎,可以有多个,用分隔符隔开。
--iterations 代表要运行这些测试多少次。
--auto-generate-sql 代表用系统自己生成的 SQL 脚本来测试。
--auto-generate-sql-load-type 代表要测试的是读还是写还是两者混合的
--number-of-queries 代表总共要运行多少次查询。每个客户运行的查询数量可以 用查询总数 / 并发数来计算。比如倒数第二个结果 2=200/100 。
--debug-info 代表要额外输出 CPU 以及内存的相关信息。
--number-int-cols 代表示例表中的 INTEGER 类型的属性有几个。
--number-char-cols 意思同上。
--create-schema 代表自己定义的模式(在 MySQL 中也就是库)。
--query 代表自己的 SQL 脚本。
--only-print 如果只想打印看看 SQL 语句是什么,可以用这个选项。
-h sql 节点 ip
-u 用户
-p( 小写 ) 密码
-P( 大写 ) 端口
二、 压力测试建表及存储过程
1. 建库、建表脚本:
CREATE DATABASE cluster1;
USE cluster1;
CREATE TABLE ndbtest (
id int(11) NOT NULL AUTO_INCREMENT,
regtime DATETIME DEFAULT NULL,
name VARCHAR(200) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=ndb AUTO_INCREMENT=1000001 DEFAULT CHARSET=latin1 PACK_KEYS=0;
2. 存储过程脚本
DELIMITER $$
DROP PROCEDURE IF EXISTS `p_test_t1_disk` $$
CREATE PROCEDURE `p_test_t1_disk`()
BEGIN
declare i int default 0;
test: loop
insert into cluster1.ndbtest(regtime,name) values(sysdate(),md5(rand()));
set i=i+1;
if i>=10000 then
leave test;
end if;
end loop;
END $$
DELIMITER ;
3. 工具运行命令
mysqlslap -uroot -proot --concurrency=1 --iterations=1 --query='call cluster1.p_test_t1_disk;' --number-of-queries=1 -h 192.168.1.37 --create-schema=cluster1
MYSQL REPLICATION 方案介绍
Mysql Replication ( MySQL 主从复制)是 MySQL 数据库使用率非常高的一种技术,它使用某个数据库服务器为 主,然后在其他数据库服务器上进行复制,后面复制的数据库也称从数据库。 MySQL 支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个 其它服务器充当从服务器。
在设置链式复制服务器时,从服务器本身也可以充当主服务器,如:
a->b->c
,
b
对于
a
来说是从服务器,但是它又 是
c
的主服务器。
Mysql Replication
(
MySQL
主从复制)主要用于:
1. 使用一个从服务器执行备份,而不会干扰主服务器。在备份过程中主服务器可以继续处理更新;
2.
解决数据库读需求很高
(
读写分离
),
通常使用
amoeba
或者
mysqlproxy
作为中间代理层
.
Mysql Replication
(
MySQL
主从复制)的原理:
Mysql 的复制( replication )是一个异步的复制,从一个 Mysql instace (称之为 Master )复制到另一个 Mysql instance (称之 Slave )。实现整个复制操作主要由三个进程完成的,其中两个进程在 Slave ( Sql 进程和 IO 进程),另外一个进程在 Master ( IO 进程)上。
要实施复制,首先必须打开
Master
端的
binary log
(
bin-log
)功能,否则无法实现。因为整个复制过程实际上就是
Slave
从
Master
端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。
复制的基本过程如下:
1)
、
Slave
上面的
IO
进程连接上
Master
,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
2)
、
Master
接收到来自
Slave
的
IO
进程的请求后,通过负责复制的
IO
进程根据请求信息读取制定日志指定位置之后的日志信息,返回给
Slave
的
IO
进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到
Master
端的
bin-log
文件的名称以及
bin-log
的位置;
3)
、
Slave
的
IO
进程接收到信息后,将接收到的日志内容依次添加到
Slave
端的
relay-log
文件的最末端,并将读取到的
Master
端的
bin-log
的文件名和位置记录到
master-info
文件中,以便在下一次读取的时候能够清楚的高速
Master“
我需要从某个
bin-log
的哪个位置开始往后的日志内容,请发给我
”
;
4)
、
Slave 的 Sql 进程检测到 relay-log 中新增加了内容后,会马上解析 relay-log 的内容成为在 Master 端真实执行时候的那些可执行的内容,并在自身执行。
如果要实现 Slave 和 Master 为同一个 mysqld, 需要添加 log-slave-updates = 1
参数到 my.cnf- à[mysqld]
服务器结构:
A 、 B 、 C 三台服务器; 其中 A 为新闻数据源, A 为 B 的 Master , B 为 A 的 Slave , 同时也是 C 的 Master ;
B 服务器从 A 复制部分数据, C 备份 A 的所有数据;
注意 :
如果数据库在做主从的时候已经有数据了 , 则需要进行锁表操作 .
mysql> flush tables with read lock;
记住数据导完后要解锁:
mysql> unloclk tables;
Master A 的配置
sudo vi /etc/mysql/my.cnf
删除以下参数前的注释并修改
server-id = 1 // 分配 server-id
log-bin = master-bin // 默认 mysql-bin, 可以不修改
log-bin-index = master-bin.index // 非必须
bind-adress = 0.0.0.0 // 默认 127.0.0.1 不修改可能导致无法访问
修改系统防火墙使 B 服务器可以访问 3306 端口,(详查 ufw 命令)
重启 mysql :
sudo /init.d/mysql restart
通过语句:
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO user@'ip B' IDENTIFIED BY 'password';
给 B 服务器建立一个可以连接到 A 的帐号
进入 mysql ,通过:
show master status;
查看 A 的状态,记录下 file 的位置和 postion 的参数
Slave B 的配置
sudo vi /etc/mysql/my.cnf
server-id = 2
log-bin = slave-bin
bind-address = 0.0.0.0
relay-log-index = slave-relay-bin.index // 非必须
relay-log = slave-relay-bin // 非必须
添加参数:
log-slave-updates = 1
// 通常情况,从服务器从主服务器接收到的更新不记入它的二进制日志。
// 该选项告诉从服务器将其 SQL 线程执行的更新记入到从服务器自己的二进制日志。
replicate_wild_do_table = copy_db.copy_table // 表示需要复制的库中的表,可以善用 %
replicate_wild_ignore_table = ignore_db.ignore_table // 不复制的表
至于为什么不使用 replicate_do_db 和 replicate_ignore_db 参数,
是为了方式跨库更新时出错,如果能确保不会跨库更新可考虑
重启 mysql ,进入本机 mysql
执行以下语句:
CHANGE MASTER TO MASTER_HOST='server A ip',
MASTER_PORT=3306,
MASTER_USER='user',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=0;
//MASTER_LOG_FILE 和 MASTER_LOG_POS 对应 A 中的 file 位置和 postion 参数,表示开始复制的 bin 文件和位置
start slave; // 启动 Slave
show slave status ; // 查看 Slave_IO_State 参数,如果是 Waiting for master to send event, 则正常
// 正常状态下 Slave_IO_Running 与 Slave_SQL_Running 均为 yes
// 如不能正常链接,根据 Slave_IO_State , Slave_IO_Running , Slave_SQL_Running , Last_IO_Error
// 等参数查找失败原因
通过:
show master status;
命令记录 file 位置和 postion 参数;
给 C 服务器分配一个帐号用于同步;
方法参照 A ,防火墙设置参照 A ;
Slave C 的配置
sudo vi /etc/mysql/my.cnf
server-id = 3
relay-log-index = slave-relay-bin.index // 非必须
relay-log = slave-relay-bin // 非必须
通过 CHANGE MASTER TO 语句来修改 master 的参数,参照 B 的配置;
通过
show slave status;
检查 C 的状态,参照 B
读写分离配置 :
推荐使用 amoeba, amoeba 相比较 mysqlproxy, 优点在于中文文档齐全 ( 国人编写 ) ,稳定性高,免除了 mysqlproxy 的 lua 配置的复杂性 .
Amoeba 读写分离:
http://docs.hexnova.com/amoeba/rw-splitting.html
高可用性
可以制作两个 master, 它们两个为双热备主机,然后通过 keepalive 整合 master 变为一个 VIP , 最后 amoeba 和 slave 都是通过这个 VIP 来进行操作, amoeba 把 insert 等操作发送到这个 VIP , slave 通过 VIP 获得具体的 bin 日志,然后进行更新
Keepalive 在使用的时候,通常只有一台 master 会进行工作,另外一台进行主从复制,当 query 发送到 VIP 的时候,就会进入工作的 master 运行。当工作 master 宕机后, keepaliave 会自动切换 VIP 指向空闲 master 进行工作, 这样子就实现了高可用性。
所以在双击热备的环境中 ,总共会占用 3+ 个 IP 地址。
负载均衡
负载均衡在 IP 层上,通常使用 LVS 软件,在 HTTP 层面上可以使用 Nginx , lighttpd , apache web server 等软件。
现在为了实现 MySql 的 master 的负载均衡,可以使用 LVS , 在 IP 层面上进行负载均衡,
也可以使用 MySql-Cluster(NDB) 产品, 它已经实现了高可用性以及负载均衡 .
高可用性和负载均衡都可以直接通过 NDB 来实现 , 上面提及的是一般方法