MySQL读写分离

438 阅读6分钟

前言

在开发项目过程中,当数据库的数据量较大、并大量较高的时候,所有的读写操作都在同一个数据库可能会导致事务处理较为缓慢;

所以,我们有时候就需要对数据库进行主从配置,进行读写分离,增删改的时候用主库,读取的时候用从库,这样也能有效提高数据库的读写效率;

一、什么是读写分离?

在数据库集群架构中,让主库负责处理事务性查询,而从库只负责处理select查询,让两者分工明确达到提高数据库整体读写性能。当然,主数据库另外一个功能就是负责将事务性查询导致的数据变更同步到从库中,也就是写操作。

二、为什么要读写分离呢

因为数据库的“写”(写10000条数据可能要3分钟)操作是比较耗时的。 但是数据库的“读”(读10000条数据可能只要5秒钟)。 所以读写分离,解决的是,数据库的写入,影响了查询的效率。

三、什么时候要读写分离?

数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。

四、目前比较常见的MySQL读写分离分为二种

第一种

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

第二种

基于中间代理层实现 代理一般位于客户端和服务器之间,代理服务器接受到客户端的请求后通过判断后转发到后端数据库,有二个代表性程序:

MySQL-Proxy。 ----MySQL的开源项目,通过自带的lua脚本进行SQL判断,MySQL官方不建议用这个在生产环境中

Amoeba(变形虫) ----由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。\

Amoeba是一个以MySql为底层数据存储,并对应提供MySQL协议接口的proxy(代理),外号变形虫
读取请求发送给从服务器是,采用轮询调度算法
amoeba使用的java语言编写,配置文件为xml
amoeba主要负责对外的一个代理IP
访问这个IP时,发送的请求为“写”请求,则会转给主服务器
当发送的请求为“读”时,会通过调度转发给从服务器,使用轮询算法,轮流分配给两台从服务器
amoeba可以视为调度器,如果主服务器挂掉(单点故障),则会有MHA解决这个问题

五、读写分离案例(使用Amoeba)

实验环境:

Master 服务器: 192.168.10.22 mysql5.7

Slave1 服务器: 192.168.10.33 mysql5.7

Slave2 服务器: 192.168.10.44 mysql5.7

Amoeba 服务器:192.168.10.11 JDK1.6、Amoeba

1、Amoeba服务器配置 192.168.10.11

1)安装 Java 环境

 #因为 Amoeba 基于是 jdk1.5 开发的,所以官方推荐使用 jdk1.5 或 1.6 版本,高版本不建议使用。
 ​
 #先将jdk的二进制文件上传到/opt/目录下,之后复制到/usr/local/目录下
 [root@amoeba ~]# cd /opt/
 [root@amoeba opt]# cp jdk-6u14-linux-x64.bin /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
 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     #刷新文件,使立即生效
 [root@amoeba local]# java -version           #查看jdk版本

image.png

image.png

image.png

image.png

image.png

image.png

2)安装 Amoeba软件

 -------1、安装 Amoeba软件---------
 #创建Amoeba的解压目录
 [root@amoeba ~]# mkdir /usr/local/amoeba/
 #将Amoeba安装包上传到/opt/目录,解压安装包
 [root@amoeba opt]# 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/
 #开启Amoeba
 [root@amoeba opt]# /usr/local/amoeba/bin/amoeba      #如显示amoeba start|stop说明安装成功
 ​
 ​
 -------2、配置 Amoeba读写分离,两个 Slave 读负载均衡----------
 ​
 #先在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问。注意:这里授权的用户名和密码,会在下一步写入数据库配置文件。
 grant all on *.* to test@'192.168.10.%' identified by 'abc123';
 ​
 #再回到amoeba服务器配置amoeba服务:
 [root@amoeba opt]# cd /usr/local/amoeba/conf/
 ​
 #备份配置文件,修改amoeba配置文件
 [root@amoeba conf]# cp amoeba.xml amoeba.xml.bak
 [root@amoeba conf]# vim amoeba.xml
 --30行--
 <property name="user">amoeba</property>     #30行和32行,授权客户端用于登录amoeba的账号和密码
 --32行-- 
 <property name="password">123456</property>
 ​
 --115行--
 <property name="defaultPool">master</property>  #设置默认服务器池
 --117-去掉注释-
 <property name="writePool">master</property>   #定义写的服务器池名称
 <property name="readPool">slaves</property>    #定义读的服务器池名称
 ​
 ​
 #备份数据库配置文件,之后修改数据库配置文件dbServers.xml
 [root@amoeba conf]# cp dbServers.xml dbServers.xml.bak
 [root@amoeba conf]# vim dbServers.xml  
 --23行--注释掉  作用:默认进入test库,注释掉以防mysql中没有test库时,会报错
 <!-- <property name="schema">test</property> -->
 ​
 ##26-30行,此用户就是之前在3台主从服务器上授权的用户,授权amoeba服务器用来登录mysql数据库的用户和密码。
 --26行--修改
 <property name="user">test</property>  
 --28-30行--去掉注释
 <property name="password">abc123</property>
 ​
 --45行--修改,设置主服务器的名称master和地址
 <dbServer name="master"  parent="abstractServer">
 --48行--修改,设置主服务器的地址
 <property name="ipAddress">192.168.10.22</property>
 ​
 --52行--修改,设置从服务器1的名称slave1
 <dbServer name="slave1"  parent="abstractServer">
 --55行--修改,设置从服务器1的地址
 <property name="ipAddress">192.168.10.33</property>
 --58行--复制上面6行粘贴,设置从服务器2的名称slave2和地址
 <dbServer name="slave2"  parent="abstractServer">
 <property name="ipAddress">192.168.10.44</property>
 ​
 --65行--修改
 <dbServer name="slaves" virtual="true">
 --71行--修改
 <property name="poolNames">slave1,slave2</property>
 ​
 ​
 [root@amoeba conf]# /usr/local/amoeba/bin/amoeba start &  #后台启动Amoeba软件,按ctrl+c 返回
 [root@amoeba conf]# netstat -anpt | grep java            #查看8066端口是否开启,默认端口为TCP 8066

image.png

image.png

先在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问:

image.png 再回到amoeba服务器配置amoeba服务:

修改amoeba的配置文件amoeba.xml

image.png

image.png

image.png 修改数据库配置文件dbServers.xml

image.png

image.png

image.png

后台启动Amoeba软件,并查看端口是否已开启:

image.png

2、客户端安装mariadb数据库

 [root@localhost ~]# yum install -y mariadb-server mariadb   #安装mariadb数据库
 [root@localhost ~]# systemctl start mariadb.service         #启动mariadb
 ​
 ​
 #客户端通过amoeba服务器登录数据库,之后向库中写入数据:
 mysql -u amoeba -pabc123 -h 192.168.10.11 -P8066        
 use zhoujian;
 create table class(id int,name char(10));
 #通过amoeba服务器代理访问mysql ,再通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器

在主服务上创建表并插入数据,并在客户端以及从服务器上查看表

image.png

image.png

image.png 关闭slave1、slave2的同步,再分别插入数据,再次在客户端查看

image.png

image.png

image.png 再次在客户端写入数据,然后分别在主从服务器上查看

image.png