本文的大致框架来自罗志威、黄川的报告, 在它的基础上进行简化和修改一些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目录下建立mysqld.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;
数据节点 和 管理节点通过进入 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主从复制)是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来实现,上面提及的是一般方法