Mysql主从复制与读写分离

目录:

1、mysql主从复制工作原理

2、mysql读写分离原理,使用Amoeba中间代理层实现读写分离

3、在vmware中实现mysql主从复制+读写分离

一、Mysql主从复制的工作原理:

1、mysql支持的复制类型:

1)、基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。

2)、 基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。

3)、混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

2、主从复制的原理

c3d5aed52c43e765c4d9b794fc81151d.png

根据上图说明mysql的主从复制原理:

(1)、在mysql_master上更新数据,写入二进制日志(Binary log),并通知存储引擎提交事务

(2)、mysql_slave启用I/O线程将master的binary log复制到slave的中继日志(Relay log),

(3)、mysql_slave启用SQL线程从Relay log中读取事件,并重放其中的事件从而更新slave数据,使其与master中的数据一致,只要该线程与I/O线程保持一致,中继日志通常会位于os缓存中,所以中继日志的开销很小。

3、mysql读写分离原理:

在主从复制的基础上,master更新数据同步到slave服务器中,master只负责写入数据,slave只提供读取数据,从而实现了数据库性能的优化,以及提升了服务器的安全性。

29bac437e7e8e2b1f71204c5163297e1.png

实现mysql读写分离的方法:

1)基于程序代码内部实现

在代码中根据select 、insert进行路由分类,这类方法也是目前生产环境下应用最广泛的。优点是性能较好,因为程序在代码中实现,不需要增加额外的硬件开支,缺点是需要开发人员来实现,运维人员无从下手。

2)、基于中间代理层实现

代理一般介于应用服务器和数据库服务器之间,代理数据库服务器接收到应用服务器的请求后根据判断后转发到,后端数据库,有以下代表性的程序。

(1)mysql_proxy。mysql_proxy是Mysql的一个开源项目,通过其自带的lua脚本进行sql判断。

(2)Atlas。是由 Qihoo 360, Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。

(3)Amoeba。由阿里巴巴集团在职员工陈思儒使用序java语言进行开发,阿里巴巴集团将其用户生产环境下,但是他并不支持事物以及存数过程。

不是所有的应用都能够在基于程序代码中实现读写分离,像一些大型的java应用,如果在程序代码中实现读写分离对代码的改动就较大,所以,像这种应用一般会考虑使用代理层来实现,那么今天就使用Amoeba为例,完成主从复制和读写分离。

二、实验案例

1、实验拓扑:

574d69d060deb0c5029dd800bb7d05a4.png

2、实验环境:

OS:centos7

mysql-5.7.13

ip规划如拓扑环境

624a14685a13da20025683fd169aee24.png

b4ff549396a5bcae4c35fc43c568cc08.png

3、实验步骤:

首先部署主从复制架构,再实现读写分离,使用client测试读写分离;

3-1:

1)、主从复制:

配置ntp,在master上搭建时间同步服务器,确保主从服务器时间同步

配置本地yum:

5899c702fa27f132f916a83a7b124b47.png

安装ntp:

yum -y install ntp

2)、配置NTP时间服务器:

vim  /etc/ntp.conf

添加如下配置:

17f220b965dcfd1d622ac22ecea449a4.png

3)、重启ntpd服务:

bfe290f87cbb358a57b3f396d0c4955c.png

4)、防火墙添加例外:

4255daee46b11387c89c61acc41fa6ae.png

5)分别slave1和slave2执行时间同步:

分别在slave1 slave2安装ntp  ntpdate

b19bc67cf794cd2e3dedeed392e58494.png

e50bc7756f94e9a4b218fe2636cc3fc8.png

在salve1和slave2执行命令同步时间:

045da0228822f5d7e6d10d31f2a3cbda.png

3-2:

1)、分别在master和slave1,slave2安装Mysql,安装步骤略:

mysql版本如下:

33c10a10cad02a2780d87f801ccac7db.png

2)、mysql_master配置:

修改/etc/my.cnf配置文件:

03f152f90b05230ee720fcbcd7fe8d17.png

注释:

server-id=1  ##注意主从server-id不可一样

log-slave-updates=true:一般用于联机复制中,

log-bin=master-bin:指定binlog日志名

重启mysqld服务

6c0de7913fd3c3c7cba63272b2e1ec9e.png

在master创建用于复制数据用户,并授权,查看master的binlog日志信息。

83e1fb1c9dc63cb0ab329ab4c9ec385f.png

4、配置从服务器(slave1和slave2配置一样)

1)、修改/etc/my.cnf主配置文件:

55310424c74ac33a6201ccfddcd958e9.png

注释:

server-id=2:  server-id修改为2

log-bin=mysql-bin:  slave的二进制日志

relay-log=relay-log-bin  :中继日志文件名

relay-log-index=slave-relay-bin.index : 中继日志的索引文件名

重启mysqld服务

systemctl restart mysqld

注意:

slave2也执行以上操作

3)、在salve1和salve2分别执行change master to操作,用于同步数据:

在master上开启防火墙的3306端口例外:

9dbd383e1eff98da41cca27b176bd607.png

注意要记住在master上执行show master status的binlog的二进制名,与位置信息,下面需要指定:

aab885867934cce387caeb40784acb75.png

slave2也执行相同操作:

4)、启动slave(slave1和slave2都执行此操作)

mysql>  start slave;

5)、查看slave状态,确保以下两个值为YES

320fafa2d59b716777738db857f96914.png

当前Slave_IO_Running:值为No,向下查看错误信息:

1b91c1364c72abbefc1a770a222b58be.png

根据上述信息,可以判断,我的环境为克隆状态,所以mysql的UUID值一样,使用以下方法解决:

556f5c1a42b5aa897cda9344e77e224e.png

修改auto.cnf中的UUID值,随意更改一个值即可。(slave2也一样)

重启mysqld服务:

systemctl restart mysqld

再次登录mysql,查看主从复制的状态:

根据Slave_SQL_Running  和Slave_IO_Running值是否为Yes状态

salve1:

ec996f4180fed2f5e20ac343491dcc53.png

slave2:

f19806cd0943be2c7178135a0b2d04d6.png

5、验证从是否同步数据:

1)、在主服务器上新建数据库”IT“

fb560519a4e9e824aeca58496c5b8e61.png

创建test表,并插入数据:

5513cdf46a0a1106f9b2c7e79ae78466.png

在slave1和slave2上查看是否更新数据:

slave1:

ede6f97c6a1ec91176d92faeadb11c94.png

slave2:

4d5c36a8ad0a80777a3c8f121457a0c4.png

主从复制配置完毕,接下来配置读写分离:

四、读写分离:

1、在Amoeba上安装java环境:

因为Amoeba基于是jdk1.5开发的,所以官方推荐使用jdk1.5或1.6版本,高版本不建议使用

1)、下载jdk的执行程序:

b95453fe537f6c2ec688a48bc109c6bc.png

2)、添加x权限,并执行

chmod +x  jdk-6u14-linux-x64.bin

cp  jdk-6u14-linux-x64.bin  /usr/local/

./jdk-6u14-linux-x64.bin  ##执行此程序

安装过程中提示(yes/no),选择yes安装即可,

mv  jdk1.6.0_14/  /usr/local/jdk1.6

3)、修改/etc/profile配置文件,增加以下配置:

export JAVA_HOME=/usr/local/jdk1.6  //设置jdk的根目录

export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib   //将jdk的程序文件赋予CLASSPATH变量

export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$PATH:$HOME

/bin  //将jdk的程序文件赋予PATH变量

export AMOEBA_HOME=/usr/local/amoeba //定义AMOEBA的根目录

export PATH=$PATH:$AMOEBA_HOME/bin  将amoeba的程序文件复制给PATH变量

如:

96ec1b2e126b91f63f89a7e2ad2f9e24.png

4)、立即生效

77136457b59053012c78f2044f6a26dc.png

2、安装并配置Amoeba软件:

#mkdir  /usr/local/amoeba    //创建amoeba目录

#tar zxf  amoeba-mysql-binary-2.2.0.tar.gz -C  /usr/local/amoeba/

#chmod -R 755 /usr/local/amoeba/

#/usr/local/amoeba/bin/amoeba

e6a93b375495f1b7a829a7163960f00a.png

显示以上内容说明amoeba安装成功。

3、配置amoeba,实现读写分离,master负责写,slave负责读,负载均衡

1)、在主从三台服务器上登录mysql,创建amoeba用户并授权

用户amoeba,密码amoeba(因为之前配置了主从复制,所以在slave1 slave2也会存在授权用户,可以查看)

7efabe9d3c5edfa18f9d322d63126598.png

2)、修改amoeba.xml文件:

定义两个配置,第一是应用程序使用什么用户连接amoeba访问到后端的mysql数据库,第二个是定义默认写池以及读池。

在Amoeba上操作:

vim  /usr/local/conf/amoeba.xml

1)、修改连接amoeba的用户和密码

57b31a2123671af9560b21eb7360b2d6.png

2)、定义读写池

ba186eb1bd8457942e0862ae97fd0565.png

3)、编辑dbServers.xml配置文件

25a32d514f4f5b98921121c57e13e074.png

1)、修改连接mysql的用户和密码:

用户amoeba 密码amoeba    ###注意删除注释   -->

53a16bbdb2a035acc15c8035dd61c0aa.png

指定master slave1 slave2主机地址:

c1aabf3330062b96488e20d4426b878b.png

定义slave的负载均衡:

4285e7eec4e401dcca87b0d79db3b220.png

4)、启动amoeba:

7829cbdf5552a7dbc565ad13b2022d61.png

4、测试读写分离:

1)、在client上安装mysql,用于远程连接数据库测试  (安装过程略,可以使用yum -y install mysql)

2)、在master salve1 slave2分别开启3306端口,防火墙添加例外

a74f6035da28778e55005d042fb127ce.png

在Amoeba上开启8066端口:

firewall-cmd  --permanent  --add-port=8066/tcp;

firewall-cmd  --reload

3)、在client上执行mysql命令登录amoeba

357ad7e869a335fcbcecaad3c6553e09.png

1)、创建数据库test

130689e262115a2ef1a8d21e56c31b80.png

2)、创建表student;

e228f570d351c86b7f64ca5977498bab.png

查看主从同步情况:

master:

89f81727a76ceb0ff05dafd2fe580dea.png

slave1:

644bcbc0cbaaf1b5132c7dcdc25c620e.png

slave2:

398b8d6a0c2b297ae8b431217edd8fb0.png

在client上插入数据到student表中,查看从是否同步:

24e57daeebef274f2eb85e2508d431dd.png

slave1:

35b655f70d654f70af48c72b294b2c60.png

slave2

ff18d81cfe2f287ebfdffdff94cf3a3f.png

2)、将slave1 slave2执行 stop slave,停止主从复制

分别在slave1 和salve2 向student表中插入不同的数据,用于在client上测试读的负载均衡:

slave1:

47b15c6d3b4ab70a53ee5d094c8b747d.png

slave2:

400d565da3055d2c64900e9c5230e552.png

在client上进行查询:

792409f8f19ca47dba60876e4530014a.png

可以看到,第一次查询的数据是slave2的数据库,第二次查询是slave1的数据库,实现了轮询算法的负载均衡

3)、在client上写入数据,测试写数据只有在master上会写入:

7446d7ecc4bc5fbae2db2122f7b898e4.png

从上面可以看出,在client上向student表写入数据,查询时,没有此数据,因为写操作只在master上生效,读是在slave上

在master上查看是否有刚写入的数据:

197931bb3310994f1feae05156ac90df.png

通过以上测试,mysql的主从复制与读写分离部署已完成。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐