读写分离
什么是读写分离
读写分离,基本的原理是让主数据库处理事务性境、改、删操作 (INSERT、UPDATE、DELETB),而从数据库处理SBLECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
为什么要写读写分离
- 因为数据库的"写”(写10000条数据可能要3分钟) 操作是比较耗时的。
- 但是数据库的"读”(读10000条数据可能只要5秒钟)。所以读写分离,解决的是,数据库的写入,影响了查询的效率。
什么时候需要读写分离
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。
主从复制与读写分离
在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。有点类似于rsync,但是不同的是rsync是对磁盘文件做备份,而mysg1主从复制是对数据库中的数据、语句做备份。
mysql支持的复制类型
- STATEMENT:基于语句的复制。在服务器上执行sl语句,在从服务器上执行同样的语句,mysl默认采用基于语句的复制,执行效率高。
- ROW: 基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
- MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。
读写分离原理
- 只在术服务器上写,只在从服务器上读
- 主数据库处理事务查询,从数据库处理select查询
- 数据库复制用于将事务性查询的变更同步到集群中的从数据库
- 读写分离方案
- 基于程序代码内部实现
- 基于中间代理层实现
- mysql-proxy
- amoeba
读写分离实验
读写分离流程图
实验环境
- master服务器:192.168.42.16,mysql5.7
- slave1服务器:192.168.42.17,mysql5.7
- slave2服务器:192.168.42.18,mysql5.7
- amoeba服务器:192.168.42.14,jdk1.6,amoeba
原理图
amoeba服务器配置
安装java环境
[root@localhost ~]# hostnamectl set-hostname amoeba
#修改名字,不会混
[root@amoeba ~]# cd /opt/
#下载jdk到opt目录
[root@amoeba opt]# cp jdk-6u14-linux-x64.bin /usr/local/
#先将jdk的二进制文件上传到/opt/目录下,之后复制到/usr/local/目录下
[root@amoeba opt]# cd /usr/local/
[root@amoeba local]# chmod +x jdk-6u14-linux-x64.bin
#为二进制文件添加执行权限
[root@amoeba local]# ./jdk-6u14-linux-x64.bin
#运行
一路回车挥着空格,直到出现选择,输入yes,等待之后按enter(回车)
[root@amoeba local]# mv jdk1.6.0_14/ /usr/local/jdk1.6
#将jdk重命名
[root@amoeba local]# vim /etc/profile.d/java.sh
#添加环境变量
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
[root@amoeba local]# source /etc/profile.d/java.sh
#刷新文件,让添加内容立刻生效
安装amoeba软件
[root@amoeba ~]# mkdir /usr/local/amoeba
#先创建amoeba的解压目录
将压缩包下载到opt目录
[root@amoeba ~]# cd /opt/
[root@amoeba opt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
#将压缩包解压到刚创建的目录
[root@amoeba opt]# chmod -R 755 /usr/local/amoeba/
#给安装目录权限
[root@amoeba opt]# /usr/local/amoeba/bin/amoeba
#开启amoeba
显示amoeba start|stop说明已经安装成功
配置Amoeba读写分离,两个Slave读负载均衡
要先在master、slave1、slave2的mysql上开放权限给amoeba访问
注意:这里授权的用户名和密码,会在下一步写入数据库配置文件
[root@master ~]# mysql -u root -p
#登录mysql
执行:
grant all on *.* to shiyan@'192.168.42.%' identified by '123456';
#@前面的名字,可以自定义
master
slave1
slave2
配置amoeba服务
[root@amoeba opt]# cd /usr/local/amoeba/conf/
#切换目录
[root@amoeba conf]# cp amoeba.xml amoeba.xml.bak
#将amoeba配置文件备份
[root@amoeba conf]# vim amoeba.xml
···········
#授权客户端用于登录amoeba的账号和密码
30 <property name="user">amoeba</property>
#修改30行
32 <property name="password">123456</property>
#修改32行
···········
115 <property name="defaultPool">master</property>
#修改115行
116
117
#将117行的注释取消;设置默认服务器池
118 <property name="writePool">master</property>
#修改118行;定义写的服务器池名称
119 <property name="readPool">slaves</property>
#修改119行;定义读的服务器池名称
[root@amoeba conf]# cp dbServers.xml dbServers.xml.bak
#备份数据库配置文件,之后修改数据库配置文件
[root@amoeba conf]# vim dbServers.xml
·············
23 <!-- <property name="schema">test</property> -->
#注释掉第23行
26 <property name="user">shiyan</property>
#修改26行并且修改
28 mysql password
29 <property name="password">123456</property>
#修改29行
30
#将28-30行的注释去掉
45 <dbServer name="master" parent="abstractServer">
#修改45行,设置主服务器的名称master
48 <property name="ipAddress">192.168.42.16</property>
#修改48行,地址改为master地址
52 <dbServer name="slave1" parent="abstractServer">
#修改52行,名称改为slave1
55 <property name="ipAddress">192.168.42.17</property>
#修改55行,地址修改为slave1地址
将从52行开始复制6行,粘贴到58行,并且修改为slave2的名称与地址
59 <dbServer name="slave2" parent="abstractServer">
60 <factoryConfig>
61 <!-- mysql ip -->
62 <property name="ipAddress">192.168.42.18</property>
63 </factoryConfig>
64 </dbServer>
65 <dbServer name="slaves" virtual="true">
#修改65行
71 <property name="poolNames">slave1,slave2</property>
#修改71行
修改的时候,一定要注意,去掉注释时候,注意是哪条去掉注释,哪条需要加上!!!!!
[root@amoeba conf]# /usr/local/amoeba/bin/amoeba start &
#后台启动Amoeba软件,按ctrl+c 返回
[root@amoeba conf]# netstat -anpt | grep java
#查看8066端口是否开启,默认端口为TCP 8066
amoeba上安装mariadb数据库
[root@amoeba ~]# yum install -y mariadb-server mariadb
#安装mariadb服务
[root@amoeba ~]# systemctl start mariadb.service
#开启服务
[root@amoeba ~]# mysql -u amoeba -p123456 -h 192.168.42.14 -P8066
#通过amoeba服务器登录数据库,之后向库中写入数据
MySQL [(none)]> use shiyan;
MySQL [shiyan]> create table duxie(id int,name char(10));
MySQL [shiyan]> insert into duxie values(1,'zly');
#通过amoeba服务器代理访问mysql ,再通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器
查看master
[root@master ~]# mysql -u root -p
#登录
mysql> use shiyan;
mysql> show tables;
mysql> select * from duxie;
查看slave
[root@slave1 ~]# mysql -u root -p
mysql> use shiyan;
mysql> show tables;
mysql> select * from duxie;
slave1
slave2
测试读写分离
#在两台slave服务器上关闭同步
mysql> stop slave;
master
mysql> insert into duxie values(4,'nih');
mysql> select * from duxie;
slave1
mysql> insert into duxie values('2','zhangsan');
mysql> select * from duxie;
客户机查看
MySQL [shiyan]> select * from duxie;
客户端查看数据只有从服务器添加的数据,
没有主服务器添加的数据,说明读写是分离的,只从slave中读取数据
开启slave1和slave2同步
mysql> start slave;
服务器查看
MySQL [shiyan]> select * from duxie;
这样就可以看见主服务器添加的内容