简介
对于很多大型网站(pv值百万、千万)来说,在所处理的业务中,其中有70%的业务是查询(select)相关的业务操作(新闻网站,插入一条新闻。查询操作),剩下的则是写(insert、update、delete,只要能对MySQL的数据造成更改的操作都叫写操作)操作。在使用负载均衡集群之后,可以很大程度的提升网站的整体性能,但是最终的数据处理的压力还是会落到MySQL数据库上,所有很有必要使用一些技术来提升MySQL的负载能力。(读写分离)
写专门交给写服务器处理(一般网站来说写是比较少的 读写比 4:1) 那么需要把读的任务分配多台服务器来完成的架构,就叫做读写分离。
实现方式
第一种:php程序上自己做逻辑判断,写php代码的时候,自己在程序上做逻辑判读写匹配。select,insert、update、delete做正则匹配,根据结果选择写服务器(主服务器)。如果是select操作则选择读服务器(从服务器器) mysql_connect(‘读写的区分’)
第二种:MySQL- Proxy是实现"读写分离(Read/Write Splitting)"的一个软件(MySQL官方提供 ,也叫中间件),基本的原理是让主数据库处理写操作(insert、update、delete),而从数据库处理查询操作(select)。而数据库的一致性则通过主从复制来实现。所以说主从复制是读写分离的基础。
注意:MySQL-proxy 它能实现读写语句的区分主要依靠的是内部一个lua脚本(能实现读写语句的判断)。
注意:如果只在主服务器(写服务器)上完成数据的写操作话;这个时候从服务器上没有执行写操作,是没有数据的。这个时候需要使用另外一个技术来实现主从服务器的数据一致性,这个技术叫做 主从复制技术。 所以说主从复制是读写分离的基础。
我们将在下面演示MySQL- Proxy读写分离配置过程
读写分离(MySQL- Proxy)是指让master处理写操作,让slave处理读操作,非常适用于读操作量比较大的场景,可减轻master的压力。
使用mysql-proxy实现mysql的读写分离,mysql-proxy实际上是作为后端mysql主从服务器的代理,它直接接受客户端的请求,对SQL语句进行分析,判断出是读操作还是写操作,然后分发至对应的mysql服务器上。
因为数据库的写操作相对读操作是比较耗时的,所以数据库的读写分离,解决的是数据库的写入,影响了查询的效率。
实验环境:
1.
主机名 | IP | 角色 | 服务 |
---|---|---|---|
server1 | 172.25.6.1 | master | mysqld |
server2 | 172.25.6.2 | slave | mysqld |
server3 | 172.25.6.3 | 代理端 | mysql-proxy |
2.server1和server2先配置主从复制
具体配置这里不再重述,可参考 https://blog.csdn.net/meltsnow/article/details/90649169
测试
mysql> SHOW SLAVE STATUS\G
1.下载安装包,解压
mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
2.将解压出来的目录移动到/usr/local目录下
[root@server3 ~]# mv mysql-proxy-0.8.5-linux-el6-x86-64bit /usr/local/
[root@server3 ~]# ll /usr/local
[root@server3 local]# ln -s mysql-proxy-0.8.5-linux-el6-x86-64bit mysql-proxy
[root@server3 local]# ls
[root@server3 local]# cd mysql-proxy
[root@server3 mysql-proxy]# ls
bin include lib libexec licenses share
[root@server3 mysql-proxy]# mkdir conf
[root@server3 mysql-proxy]# ls
bin conf include lib libexec licenses share
[root@server3 mysql-proxy]# cd conf
[root@server3 conf]# ls
[root@server3 conf]# vim mysql-proxy.conf
写入:
1 [mysql-proxy]
2 proxy-address=0.0.0.0:3306 ##mysql-proxy运行的端口
3 proxy-read-only-backend-addresses=172.25.6.2:3306 ##slave:只读
4 proxy-backend-addresses=172.25.6.1:3306 ##master:可读可写
5 proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua ##lua脚本的路径
6 pid-file=/usr/local/mysql-proxy/log/mysql-proxy.pid
7 log-file=/usr/local/mysql-proxy/log/mysql-proxy.log ##日志位置
8 plugins=proxy
9 log-level=debug ##定义日志级别
10 keepalive=true ##mysql-proxy崩溃时尝试重启
11 daemon=true ##打入后台
[root@server3 mysql-proxy]# pwd
/usr/local/mysql-proxy/share/doc/mysql-proxy
[root@server3 mysql-proxy]# vim rw-splitting.lua
40 min_idle_connections = 1, 最小连接数
41 max_idle_connections = 2, 最大连接数
6.创建日志所在的目录
[root@server3 conf]# mkdir /usr/local/mysql-proxy/log
[root@server3 conf]# cd ..
[root@server3 mysql-proxy]# ls
bin conf include lib libexec licenses log share
7.修改配置文件的权限
[root@server3 ~]# cd /usr/local/mysql-proxy
[root@server3 mysql-proxy]# ls
bin conf include lib libexec licenses log share
[root@server3 mysql-proxy]# cd conf/
[root@server3 conf]# ll
total 4
-rw-r--r-- 1 root root 374 Jun 5 22:49 mysql-proxy.conf
[root@server3 conf]# chmod 660 /usr/local/mysql-proxy/conf/mysql-proxy.conf
[root@server3 conf]# ll
total 4
-rw-rw---- 1 root root 374 Jun 5 22:49 mysql-proxy.conf
8.启动mysql-proxy
[root@server3 conf]# /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/mysql-proxy.conf
[root@server3 conf]# cat /usr/local/mysql-proxy/log/ ##查看日志
9.server3安装lsof
[root@server3 conf]# yum install -y lsof
[root@server3 conf]# lsof -i:3306
测试:
1.server1:创建新的用户并且授权,创建test数据库
mysql> show databases;
##查看数据库信息
mysql> grant insert,update,select on *.* to zhou@'%' identified by 'ZHOUpeng123.';
##新建一个用户yan并对他授权
mysql> flush privileges;
##刷新授权表
mysql> CREATE DATABASE test;
##创建test库
mysql> USE test;
mysql> CREATE TABLE usertb (
-> username varchar(10) not null,
-> password varchar(15) not null);
创建usertb表
mysql> desc usertb;
##查看表结构
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| username | varchar(10) | NO | | NULL | |
| password | varchar(15) | NO | | NULL | |
+----------+-------------+------+-----+---------+-------+
[root@foundation6 ~]# yum install -y mysql
[kiosk@foundation6 ~]$ mysql -h 172.25.6.3 -uzhou -pZHOUpeng123.
4.可以查看到数据——表usertb为空
MySQL [(none)]> USE test;
MySQL [test]> SELECT * FROM usertb;
Empty set (0.00 sec)
5.插入一个数据
MySQL [westos]> INSERT INTO usertb VALUES ('user1','123'); ##插入成功
插入成功,并且物理机可以查看到
6.server1: master可以查看到
7.server2: slave可以查看到
总结:server1(master)上能看到数据说明写操作是在master上,而slave可以查看到数据是因为server1(master)和server2(slave)是主从复制的关系,不能说明server2上可以进行写操作,为了更清楚的验证读写分离,我们做下面的实验
1.server2停止slave
mysql> start slave;
2.物理机继续插入数据,物理机可以查看到
MySQL [test]> INSERT INTO usertb VALUES ('user2','456');
Query OK, 1 row affected (0.01 sec)
MySQL [test]> SELECT * FROM usertb;
+----------+----------+
| username | password |
+----------+----------+
| user1 | 123 |
| user2 | 456 |
+----------+----------+
2 rows in set (0.00 sec)
3.server1:master可以查看到
4.server2:slave查看不到新插入的数据
注意:如果你在slave节点上查询本次数据插入操作之前退出过数据过(在关闭了slave进程后),那么依然可以查看插入的数据
总结:当前server2的slave是关闭的所以不能进行主从复制,测试端插入数据server1(master)可以看到说明写操作是在server1上进行的,server2上没有新插入的数据,读操作是在server2上,所以读写分离了
1.关闭server1(master)的mysql服务
[root@server1 mysql]# systemctl stop mysqld
2.开启server2的slave
总结:当前环境中server1上mysql服务关闭(master关闭),server2上slave开启,在物理机上进行数据插入时失败,证明数据库的写操作实际上是在server1上进行的,由此证明读写分离!