1.概述
MySQL主从复制是指MySQL从服务器(slave)从主MySQL主服务器(master)同步数据,确切的说是slave从master的二进制日志(bin_log)中读取事件,保存在slave的中继日志(relay_log)中,然后slave再从中继日志中读取出来并在本地执行一遍。
如果对数据库的读和写都在同一个数据库服务器中操作,业务系统性能会降低。为了提升业务系统性能,优化用户体验,可以通过过主从复制(Master-Slave)的方式来同步数据,再通过读写分离(Amoeba或MyCat)来提升数据库的并发负载能力来进行部署与实施。
通过主从复制(Master-Slave)的方式来同步数据;基于Amoeba、MyCat两种不同中间件实现读写分离。
1.2部署环境
操作系统:centos6.5
jdk:1.8.0_144-b01
mysql版本:5.1.73
M1:192.168.4.95 M2:192.168.4.178
S1:192.168.4.154 S2:192.168.4.103
MyCat IP:192.168.4.103 版本:Mycat-server-1.4-beta
Navicat Premium 版本:11.2.7(64-bit)-Permium
2.主从复制
2.1主从复制原理
复制分为3个步骤:
(1)master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);
(2)slave将master的binary log events拷贝到中继日志(relay log);
(3)slave重做中继日志中的事件,将改变反映为数据。
2.2主从复制配置
这里有两组主从,M1(192.168.4.95)与S1(192.168.4.154),M2(192.168.4.178)与S2(192.168.4.103)。我们以M1与S1为例,M2与S2配置与之相似。
2.2.1主服务器配置
MySQL数据库配置文件,默认是 /etc/my.cnf
binlog-do-db=gldn-2017-ftb #需要备份的数据库名
binlog-ignore-db=mysql #忽略的数据库
server-id=95 #每一个同步中的slave在master上都对应一个master线程,该线程就是通过slave的server-id来标识
2.2.2从服务器配置
master-connect-retry = 5 #每个5秒钟同步一次
master-host=192.168.4.95 #主服务器ip
2.2.3重启两台服务器的mysql
Service mysqld restart
2.2.4创建复制账号
在master数据库中建立一个复制账户,每个 slave 使用该账户连接 master 进行复制,需要 replication slave 和replication client 权限。
GRANT REPLICATION slave ON *.* TO 'ameoba'@'192.168.%.%' IDENTIFIED BY '123456';
2.2.5查看主数据库状态
show master status;
2.2.6从服务器连接主服务器
slave stop;
CHANGE MASTER TO MASTER_HOST='192.168.4.95',MASTER_USER='amoeba',MASTER_PASSWORD='123456,MASTER_LOG_FILE='mysql-bin.000029',MASTER_LOG_POS=514910;
slave start;
2.2.7查看从数据库状态
show slave status;
上图表示主从配置成功。
2.2.8常见问题
- mysql配置同步复制报错“The server is not configured as slave”
解决办法:master和slave的server-id可能重复,手动配置server-id
SET GLOBAL server_id=xx
- mysql 数据同步 出现Slave_IO_Running:No
常规操作:先stop slave,然后执行了一下提示的语句,再SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; start slave;
另外,出现Slave_IO_Running:NO还有一个原因是slave上没有权限读master上的数据。
2.3测试
在主库执行执行增删改操作,验证主从是否同步
以添加数据为例,在主库创建表,并插入数据,执行查询操作
查询主库
查询从库
结果表明,主从以同步;依次验证删除和修改操作。
3.Amoeba读写分离
3.1Amoeba简介
Amoeba(变形虫)专注分布式数据库 proxy 开发。座落与Client、DB Server(s)之间。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。
3.2Ameoba安装配置
3.2.1下载Amoeba
Wget http://nchc.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz
3.2.2安装Amoeba
#mkdir /usr/local/amoeba
#mv amoeba-mysql-binary-2.1.0-RC5.tar.gz/usr/local/amoeba
#tar xvf amoeba-mysql-binary-2.1.0-RC5.tar.gz
3.2.3配置Amoeba
Amoeba的配置文件在本环境下位于/usr/local/amoeba/conf目录下。配置文件比较多,但是仅仅使用读写分离功能,只需配置两个文件即可,分别是dbServers.xml和amoeba.xml,如果需要配置ip访问控制,还需要修改access_list.conf文件。
- 配置dbServers.xml
dbServers.xml定义连接后端Mysql服务器信息
将M1、M2节点加入WritePool
192.168.4.95
将S1、S2节点加入ReadPool
192.168.4.154
定义算法和数据库池
1 M1,S1
配置amoeba.xml
amoeba.xml定义数据库读写分离及节点管理信息
定义端口和IP
8066 192.168.4.103
设置连接主从数据库服务器的IP地址和服务器别名,用户名及密码
amoeba 123456
读写数据库设置
1500 定义默认池,一些sql语句默认会在此定义的服务器上执行M1 定义只写数据库M1 S1
efaultPool :配置了默认的数据库节点,一些除了SELECtUPDATEINSERTDELETE的语句都会在defaultPool执行。
writePool :配置了数据库写库,通常配为master。
readPool :配置了数据库读库,通常配为slave或者slave组成的数据库池。
配置
修改启动文件
将Xss修改为256k
3.2.4启动amoeba
启动文件在bin目录下,启动指令如下
3.2.5测试
- 链接测试
在任意客户端登录amoeba
如上表明amoeba配置正确。
- 读写测试
编写EJB工程,执行读写操作,在两台mysql服务器上使用tcpdump抓包。
首先执行添加操作,M1上实现的操作
18:47:41.353615 IP 192.168.4.103.40421 > 192.168.4.95.3306: Flags [P.], seq 20:162, ack 164, win 245, options [nop,nop,TS val 1620953 ecr 578704481], length 142
E.....@.@.....g..._.....c.q..............
...."~Ta.....insert into ftb_roles (in_time, remark, role_name, up_time) values ('2017-11-13 10:47:41', '82067506', 'UxQxCDsr', '2017-11-13 10:47:41')
18:47:41.356859 IP 192.168.4.103.40421 > 192.168.4.95.3306: Flags [P.], seq 162:173, ack 177, win 245, options [nop,nop,TS val 1620956 ecr 578704483], length 11
E..?..@.@......g..._.....c.....i.....H.....
S1上实现的操作
然后执行查询操作
M1上实现的操作
S1上实现的操作
8:53:09.908540 IP 192.168.4.103.47310 > 192.168.4.154.3306: Flags [P.], seq 20:215, ack 164, win 245, options [nop,nop,TS val 1949508 ecr 579030714], length 195 E.....@.@......g........#>5A.........;..... ...D".N......select roles0_.id as id1_0_, roles0_.in_time as in2_1_0_, roles0_.remark as remark1_0_, roles0_.role_name as role4_1_0_, roles0_.up_time as up5_1_0_ from ftb_roles roles0_ where roles0_.id=1 18:53:10.000243 IP 192.168.4.103.47310 > 192.168.4.154.3306: Flags [.], ack 593, win 262, options [nop,nop,TS val 1949600 ecr 579030766], length 0 E..4..@.@......g........#>6.........]...... ....".N.
tcpdump抓包结果表明:M1数据库执行写操作,S1数据库执行读操作。
3.2.6通过Amoeba对数据进行简单的分片
对M1,M2两主库进行分片操作
配置rule.xml
#cd/usr/local/amoeba/conf
#vi/role.xml
tableRule的name属性定义了表名、schema为数据库名、defaultPools定义了该表的默认库。
parameters元素定义了切分的参数,比如按照ID来进行切分。通常parameters的配置为该表的某列列名或几列列名。
expression元素定义了类似VB script的切分表达式。Amoeba对ID取余,如果ID为单数则存储在M2中,双数则存储在M1中。
使用Navicat Premium连接Amoeba,在ftb_roles表中执行添加数据操作
查看M1中ftb_roles表中数据
查看M2中ftb_roles表中数据
正如配置的那样,ID为偶数的数据被分片到了M1上,ID为奇数的数据被分片到了M2上。
4.MyCat读写分离
4.1MyCat简介
Mycat是一个开源的分布式数据库系统,但是因为数据库一般都有自己的数据库引擎,而Mycat并没有属于自己的独有数据库引擎,所有严格意义上说并不能算是一个完整的数据库系统,只能说是一个在应用和数据库之间起桥梁作用的中间件。
MyCat可以让程序员只需要关心业务代码的编写,而不用担心后端数据库集群的负载均衡,读写分离,分库分表的数据分片逻辑的编写,只要直接连接mycat并修改配置文件即可。
4.2MyCat安装配置
4.2.1下载MyCat
Wget https://github.com/MyCATApache/Mycat-download/blob/master/1.4-RELEASE/Mycat-server-1.4-beta-20150604171601-linux.tar.gz
4.2.2安装MyCat
创建MyCat用户并设置密码
# useradd mycat
# passwd mycat
解压MyCat文件
# tar xvf Mycat-server-1.4-beta-20150604171601-linux.tar.gz
# mv mycat/ /usr/local/mycat
4.2.3修改配置文件
- server.xml配置
server.xml几乎保存了所有mycat需要的系统配置信息。其在代码内直接的映射类为SystemConfig类。
这里配置了两个用来连接的用户
用户1 mycat 密码123456 给予此用户gldn-2017-ftb数据库的读写权限
用户2 mycat1 密码123456 给予此用户gldn-2017-ftb数据库的只读权限
配置说明:
schemas中可以配置一个或多个;
readOnly是应用连接中间件逻辑库所具有的权限,true为只读;
注意这里的schemas中gldn-2017-ftb不一定是数据库中真实库名。可以任意指定,只要和schema.xml配置文件中的库名统一即可。
- Schema.xml配置
Schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、表、分片规则、DataNode以及DataSource
配置说明:
checkSQLschema
当该值设置为 true 时,如果我们执行语句**select * from TESTDB.travelrecord;**则MyCat会把语句修改为**select * from travelrecord;**。
sqlMaxLimit
当该值设置为某个数值时。每条执行的SQL语句,如果没有加上limit语句,MyCat也会自动的加上所对应的值。例如设置值为100,执行**select * from TESTDB.travelrecord;**的效果为和执行**select * from TESTDB.travelrecord limit 100;**相同。
dataNode
该属性用于绑定逻辑库到某个具体的database上,可以配置默认分片,只需要配置需要分片的表即可。
maxCon属性
指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost、readHost标签都会使用这个属性的值来实例化出连接池的最大连接数。
minCon属性
指定每个读写实例连接池的最小连接,初始化连接池的大小。
balance属性
1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上;
2. balance="1",全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡;
3. balance="2",所有读操作都随机的在writeHost、readhost上分发;
4. balance="3",所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力。
writeType属性
负载均衡类型,目前的取值有3种:
writeType="0", 所有写操作发送到配置的第一个writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties
writeType="1",所有写操作都随机的发送到配置的writeHost
switchType属性
- -1 表示不自动切换
- 1 默认值,不自动切换
- 2 基于MySQL主从同步的状态决定是否切换
dbType属性
指定后端连接的数据库类型,目前支持二进制的mysql协议,还有其他使用JDBC连接的数据库。例如:mongodb、oracle、spark等。
dbDriver属性
指定连接后端数据库使用的Driver,目前可选的值有native和JDBC。
switchType属性
-1 表示不自动切换
1 默认值,自动切换
2 基于MySQL主从同步的状态决定是否切换
心跳语句为 show slave status
3 基于MySQL galary cluster的切换机制(适合集群)
心跳语句为 show status like ‘wsrep%’
heartbeat标签
这个标签内指明用于和后端数据库进行心跳检查的语句。例如,MYSQL可以使用
主从切换的语句必须是:show slave status
writeHost标签、readHost标签
这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。唯一不同的是,writeHost指定写实例、readHost指定读实例,组着这些读写实例来满足系统的要求。
在一个dataHost内可以定义多个writeHost和readHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去。
4.2.4启动mycat
#cd /usr/local/mycat/mycat/bin
#./mycat console
如果你看到这一段说明服务已经成功启动;
这里可以使用Navicat Premium连接,或者在任意客户端登录MyCat查看连接是否成功。
如果没有连接成功过,有错误的话会在/logs/mycat.log中去查看
# cd /usr/local/mycat/mycat/logs/
#tailf mycat.log
访问端口号
连接状态
4.3测试
使用tcpdump抓包,验证读写分离,方法与amoeba验证方式相同。



