文章目录
前言
一:MySQL读写分离原理
1.1:原理
- 读写分离就是只在主服务器上写,只在从服务器上读
- 主数据库处理事务性査询,而从数据库处理 select査询
- 数据库复制被用来把事务性査询导致的变更同步到集群中的从数据库
1.2:为什么会形成读写分离?
- 在企业应用中,在大量的数据请求下,单台数据库将无法承担所有的读写操作
- 配置多台数据库服务器以实现读写分离
- 读写分离建立在主从复制的基础上
二:读写分离的基础:主从复制
2.1:主从复制是如何形成的?
- 在企业网站中,后端MySQL数据库只有一台时,会有以下问题:
- 遇到单点故障,服务不可用
- 无法处理大量的并发数据请求
- 数据丢失将会造成很大损失
2.2:主从复制的解决方案
2.2.1:解决办法
- 增加MySQL数据库服务器,对数据进行备份,形成主备
- 确保主备MySQL数据库服务器数据是一样的
- 主服务器宕机了,备份服务器继续工作,数据有保障
- MySQL主从复制与读写分离是密切相关的
2.2.2:更高级的解决办法
-
通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力
-
Amoeba:是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy,外号变形虫
读取请求发送给从服务器时,采用轮询调度算法
-
主服务器挂掉,我们会采用MHA解决(此实验用不到)
-
此实验涉及到的账号权限
- 主从同步账号
- 节点服务器开放调度账号
- Amoeba代理账号
三:主从读写分离实验
3.1:环境
-
VMware软件
-
环境依赖上一篇博客做的主从复制的结果
-
主从复制的搭建详情可以看我的博客:
https://blog.csdn.net/CN_TangZheng/article/details/103897251
-
一台centos7服务器当做client
-
一台centos7服务器作为Amoeba服务器
-
三台centos7服务器作为mysql数据库服务器,一主二从
3.2:拓扑图
3.3:实验目的
- 通过向mysql主服务器和从服务器写东西,验证:
- 客户机通过amoeba服务器写入是写入mysql主服务器
- 客户机通过amoeba服务器读取数据是从两个slave从服务器上轮询读取数据的
3.4:实验过程
3.4.1:防火墙设置
-
和主从同步一样,确定都关闭
systemctl stop firewalld.service setenforce 0
3.4.2:搭建mysql主从复制环境
3.4.3:Amoeba服务器环境安装
-
安装jdk(因为amoeba是Java写的,所以我们需要安装jdk)
-
我已经下载好了,直接挂在宿主机复制到服务器就行
[root@amoeba ~]# mount.cifs //192.168.100.3/ccc /mnt Password for root@//192.168.100.3/ccc: [root@amoeba ~]# cd /mnt [root@amoeba mnt]# cp jdk-6u14-linux-x64.bin /usr/local/ [root@amoeba mnt]# cd /usr/local [root@amoeba local]# ./jdk-6u14-linux-x64.bin ...期间一直空格,直到要输入yes Do you agree to the above license terms? [yes or no] yes '//输入yes' '//遇到它,按回车' Press Enter to continue..... Done. [root@amoeba local]# mv jdk1.6.0_14/ jdk1.6 '//重命名一下' [root@amoeba local]# echo '//设置环境变量' > export JAVA_HOME=/usr/local/jdk1.6 > export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib > export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$PATH:$HOME/bin > export AMOEBA_HOME=/usr/local/amoeba > export PATH=$PATH:$AMOEBA_HOME/bin' >> /etc/profile [root@amoeba local]# source /etc/profile [root@amoeba mnt]# cd /mnt [root@amoeba mnt]# mkdir /usr/local/amoeba [root@amoeba mnt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ [root@amoeba mnt]# chmod -R 755 /usr/local/amoeba '//设置权限' [root@amoeba mnt]# /usr/local/amoeba/bin/amoeba '//查看是否安装成功' amoeba start|stop
3.4.4:配置Amoeba读写分离,两个slave读负载均衡
-
三台mysql服务器添加权限和用户开放给amoeba访问
mysql> grant all on *.* to test@'192.168.79.%' identified by '123.com'; Query OK, 0 rows affected, 1 warning (0.00 sec) '//通过192.168.79.0段的test用户拥有所有权限对于所有的库和表都可以使用123.com来访问' '//三台mysql服务器都要设置'
-
配置amoeba服务器
[root@amoeba mnt]# cd /usr/local/amoeba/conf/ [root@amoeba conf]# vim amoeba.xml '//编辑amoeba主配置文件' '//此段设置的是客户端通过amoeba用户和123456密码访问amoeba服务器' <property name="user">amoeba</property> '//第30行开始修改用户名' <property name="password">123456</property> '//使用123456密码访问amoeba服务器' '//移动到117行,开启读写功能池设定' <property name="defaultPool">master</property> '//115行修改' <!-- --> '//117行取消注释' <property name="writePool">master</property> '//118行修改' <property name="readPool">slaves</property> '//119行修改' '//120行删除-->注释符号' [root@amoeba conf]# vim dbServers.xml '//编辑数据库配置文件' <property name="schema">mysql</property> '//23行test修改为mysql' '//设置amoeba访问mysql数据库的用户和密码' <property name="user">test</property> '//26行修改用户名' <!-- mysql password--> '//28行-30行取消注释' <property name="password">123.com</property> '//29行修改密码' <dbServer name="master" parent="abstractServer"> '//45行主mysql服务器名称修改为master' <property name="ipAddress">192.168.79.135</property> '48行//修改主服务器IP' <dbServer name="slave1" parent="abstractServer"> '//52行修改从服务器名称' <property name="ipAddress">192.168.79.135</property> '//55行修改从服务器IP' '//第一个从服务器段后插入第二个从服务器配置' <dbServer name="slave2" parent="abstractServer"> <factoryConfig> <!-- mysql ip --> <propertyname="ipAddress">192.168.79.136</property> </factoryConfig> </dbServer> '//修改数据库从服务器池' <dbServer name="slaves" virtual="true"> '//66行修改服务器吃名称为slaves' <property name="poolNames">slave1,slave2</property> '//72行添加两个从服务器名称slave1,slave2'
3.4.5:启动Amoeba软件
-
开启amoeba软件,放到后台运行
[root@amoeba conf]# /usr/local/amoeba/bin/amoeba start & [1] 63847 [root@amoeba conf]# log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml 2020-01-08 23:38:40,817 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0 log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf 2020-01-08 23:38:41,113 INFO net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066. 2020-01-08 23:38:41,122 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:23097. '//此时处于持续监控状态,无法输入命令'
3.5:实验验证
3.5.1:客户端安装mysql
-
由于是用来验证,所以可以直接用yum安装
'//先关闭防火墙,且确认所有服务器的防火墙都已关闭' [root@client ~]# systemctl stop firewalld.service [root@client ~]# setenforce 0 [root@client ~]# yum install mysql -y [root@client ~]# mysql -u amoeba -p123456 -h 192.168.79.100 -P8066 MySQL [(none)]> create database sanku; '//创建一个库' '//进入主从服务器查看,发现mysql主从服务器都已经自动同步'
-
测试读写分离,关闭主从复制功能
两台从服务器关闭slave功能 mysql> stop slave; Query OK, 0 rows affected (0.00 sec) mysql> show slave status\G; ...省略内容 Slave_IO_Running: No '//发现功能已被关闭' Slave_SQL_Running: No ...省略内容
-
从服务器配置数据,验证读写分离
MySQL [(none)]> create database siku; '//客户端创建库' '//会发现主服务器有,但是从服务器没有,说明主从复制功能已经关闭' '//slave1从服务器设置:都有erku的库,所以各自在erku创建yibiao并插入不同数据' mysql> use erku; Database changed mysql> create table yibiao (id int not null,name char(10)); Query OK, 0 rows affected (0.01 sec) mysql> insert into yibiao values(1,'zhangsan'); '//添加zhangsan记录' Query OK, 1 row affected (0.02 sec) mysql> select * from yibiao; +----+----------+ | id | name | +----+----------+ | 1 | zhangsan | +----+----------+ 1 row in set (0.00 sec) '//slave1从服务器设置:' mysql> use erku; Database changed mysql> create table yibiao(id int not null,name char(10)); Query OK, 0 rows affected (0.01 sec) mysql> insert into yibiao values(2,'lisi'); '//添加lisi记录' Query OK, 1 row affected (0.02 sec) mysql> select * from yibiao; +----+------+ | id | name | +----+------+ | 2 | lisi | +----+------+ 1 row in set (0.00 sec)
-
验证
'//进入客户端测试' MySQL [(none)]> use erku; '//进入库' Database changed MySQL [erku]> select * from yibiao; +----+------+ | id | name | +----+------+ | 2 | lisi | +----+------+ 1 row in set (0.01 sec) MySQL [erku]> select * from yibiao; +----+----------+ | id | name | +----+----------+ | 1 | zhangsan | +----+----------+ 1 row in set (0.01 sec) '//发现每一次查询都会轮询在slave1和slave2上查询数据,如果开启主从复制,则数据都会相同' '//读写分离试验成功'