Mysql进阶(3)——读写分离(mysql-proxy)

前言

简介

对于很多大型网站(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
    

Mysql进阶(3)——读写分离(mysql-proxy)_第1张图片

代理端server3配置过程

1.下载安装包,解压

mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz

Mysql进阶(3)——读写分离(mysql-proxy)_第2张图片

2.将解压出来的目录移动到/usr/local目录下

[root@server3 ~]# mv mysql-proxy-0.8.5-linux-el6-x86-64bit /usr/local/ 
[root@server3 ~]# ll /usr/local

Mysql进阶(3)——读写分离(mysql-proxy)_第3张图片
3.制作软链接

[root@server3 local]# ln -s mysql-proxy-0.8.5-linux-el6-x86-64bit mysql-proxy
[root@server3 local]# ls

Mysql进阶(3)——读写分离(mysql-proxy)_第4张图片
4.新建一个配置文件的目录,创建配置文件

[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

Mysql进阶(3)——读写分离(mysql-proxy)_第5张图片

写入:

 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        ##打入后台

Mysql进阶(3)——读写分离(mysql-proxy)_第6张图片
5.修改数据库发生读写分离时的最大和最小连接数

[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,   最大连接数

Mysql进阶(3)——读写分离(mysql-proxy)_第7张图片
Mysql进阶(3)——读写分离(mysql-proxy)_第8张图片

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

Mysql进阶(3)——读写分离(mysql-proxy)_第9张图片

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

Mysql进阶(3)——读写分离(mysql-proxy)_第10张图片

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/     ##查看日志

Mysql进阶(3)——读写分离(mysql-proxy)_第11张图片

9.server3安装lsof

[root@server3 conf]# yum install -y lsof
[root@server3 conf]# lsof -i:3306

Mysql进阶(3)——读写分离(mysql-proxy)_第12张图片
Mysql进阶(3)——读写分离(mysql-proxy)_第13张图片
10.3306端口正在使用

Mysql进阶(3)——读写分离(mysql-proxy)_第14张图片

测试:


  • 测试一:master和slave都开启,主从复制模式

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    |       |
    +----------+-------------+------+-----+---------+-------+

Mysql进阶(3)——读写分离(mysql-proxy)_第15张图片
Mysql进阶(3)——读写分离(mysql-proxy)_第16张图片
2.物理机安装mysql

[root@foundation6 ~]# yum install -y mysql

Mysql进阶(3)——读写分离(mysql-proxy)_第17张图片
3.新建用户登陆server3

[kiosk@foundation6 ~]$ mysql -h 172.25.6.3 -uzhou -pZHOUpeng123.

能看到这个数据库
Mysql进阶(3)——读写分离(mysql-proxy)_第18张图片

4.可以查看到数据——表usertb为空

MySQL [(none)]> USE test;
MySQL [test]> SELECT * FROM usertb;
Empty set (0.00 sec)

Mysql进阶(3)——读写分离(mysql-proxy)_第19张图片

5.插入一个数据

MySQL [westos]> INSERT INTO usertb VALUES ('user1','123');		##插入成功

Mysql进阶(3)——读写分离(mysql-proxy)_第20张图片

插入成功,并且物理机可以查看到

6.server1: master可以查看到

Mysql进阶(3)——读写分离(mysql-proxy)_第21张图片

7.server2: slave可以查看到

Mysql进阶(3)——读写分离(mysql-proxy)_第22张图片

总结:server1(master)上能看到数据说明写操作是在master上,而slave可以查看到数据是因为server1(master)和server2(slave)是主从复制的关系,不能说明server2上可以进行写操作,为了更清楚的验证读写分离,我们做下面的实验


  • 测试二:master开启,slave关闭

1.server2停止slave

mysql> start slave;

Mysql进阶(3)——读写分离(mysql-proxy)_第23张图片

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)

Mysql进阶(3)——读写分离(mysql-proxy)_第24张图片

3.server1:master可以查看到

Mysql进阶(3)——读写分离(mysql-proxy)_第25张图片

4.server2:slave查看不到新插入的数据

注意:如果你在slave节点上查询本次数据插入操作之前退出过数据过(在关闭了slave进程后),那么依然可以查看插入的数据
Mysql进阶(3)——读写分离(mysql-proxy)_第26张图片

总结:当前server2的slave是关闭的所以不能进行主从复制,测试端插入数据server1(master)可以看到说明写操作是在server1上进行的,server2上没有新插入的数据,读操作是在server2上,所以读写分离了


  • 测试三:master关闭,slave开启

1.关闭server1(master)的mysql服务

[root@server1 mysql]# systemctl stop mysqld

在这里插入图片描述

2.开启server2的slave

在这里插入图片描述
3.物理机再次插入数据,插入失败

在这里插入图片描述

总结:当前环境中server1上mysql服务关闭(master关闭),server2上slave开启,在物理机上进行数据插入时失败,证明数据库的写操作实际上是在server1上进行的,由此证明读写分离!

你可能感兴趣的:(运维企业部分)