实现MySQL读写分离的前提是我们已经将MySQL主从复制配置完毕,可参考上一篇关于MySQL数据库集群实战(2)——MySQL主从复制之异步复制(传统复制postion与GTID)的文章。配置基于GTID的异步复制。
当我们的数据量很大时,数据库服务器的压力变大,这时候我们需要从架构方面来解决这一问题,在一个网站中读的操作很多,写的操作很少,这时候我们需要配置读写分离,把读操作和写操作分离出来,最大程度的利用好数据库服务器。
读写分离的实现原理就是在执行SQL语句的时候,判断到底是读操作还是写操作,把读的操作转向到读服务器上(从服务器,一般是多台),写的操作转到写的服务器上(主服务器,一般是一台,视数据量来看)。
mysql-proxy是mysql官方提供的mysql中间件服务,上游可接入若干个mysql-client,后端可连接若干个mysql-server。
它使用mysql协议,任何使用mysql-client的上游无需修改任何代码,即可迁移至mysql-proxy上
进一步的,mysql-proxy可以分析与修改请求。拦截查询和修改结果,需要通过编写Lua脚本来完成。
mysql-proxy允许用户指定Lua脚本对请求进行拦截,对请求进行分析与修改,它还允许用户指定Lua脚本对服务器的返回结果进行修改,加入一些结果集或者去除一些结果集均可。
所以说,根本上,mysql-proxy是一个官方提供的框架,具备良好的扩展性,可以用来完成:
sql拦截与修改
性能分析与监控
读写分离
请求路由
主机名 | ip | 服务 |
---|---|---|
server1 | 172.25.1.1 | master |
server2 | 172.25.1.2 | slave |
server3 | 172.25.1.3 | proxy |
Mysql的主从复制和Mysql的读写分离两者有着紧密联系,首先部署主从复制,只有主从复制完了,才能在此基础上进行数据的读写分离。
上篇实验已经部署好了主从复制,使用的是mysql基于gtid的异步复制,这里不再赘述了。具体部署方法参考MySQL数据库集群实战(2)——MySQL主从复制之异步复制(传统复制postion与GTID)
在server3上:
步骤一:先到网上下载安装包
由于没有el7版本的mysql-proxy,所以还是下载el6的
下载地址:mysql-proxy下载地址
步骤二:查看3306端口是否被占用,proxy使用的是3306端口
netstat -antupe | grep 3306
tar zxf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local
cd /usr/local/
ln -s mysql-proxy-0.8.5-linux-el6-x86-64bit/ mysql-proxy
cd /usr/local/mysql-proxy
mkdir conf ##建立配置文件目录
vim mysql-proxy.conf
配置文件内容:
[mysql-proxy]
proxy-address=0.0.0.0:3306 #mysql-proxy运行的端口
proxy-backend-addresses=172.25.1.1:3306 #master节点:可读可写
proxy-read-only-backend-addresses=172.25.1.2:3306 #slave节点:只读
proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua #lua脚本的路径
pid-file=/usr/local/mysql-proxy/log/mysql-proxy.pid #进程pid的位置
plugins=proxy
log-file=/usr/local/mysql-proxy/log/mysql-proxy.log #日志位置
log-level=debug #定义日志级别
keepalive=true #mysql-proxy崩溃时尝试重启
daemon=true #打入后台
mkdir /usr/local/mysql-proxy/log
步骤六:修改lua脚本
vim /usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
#把原来的4和8改为1和2,默认超过4个连接才会启动读写分离,改为1个好测试
min_idle_connections = 1,
max_idle_connections = 2,
进入到/usr/local/mysql-proxy/bin可以看到启动脚本
/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/mysql-proxy.conf
chmod 660 /usr/local/mysql-proxy/conf/mysql-proxy.conf
/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/mysql-proxy.conf
/local/mysql-proxy/conf/mysql-proxy.conf
2020-02-06 16:54:39: (critical) Key file contains key ‘keepalive’ which has value that cannot be interpreted.
2020-02-06 16:54:39: (message) Initiating shutdown, requested from mysql-proxy-cli.c:367
2020-02-06 16:54:39: (message) shutting down normally, exit code is: 1
修改方法:
将配置文件mysql-proxy.conf 中
daemon=1
keepalive=1
重新启动
/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/mysql-proxy.conf
cat /usr/local/mysql-proxy/log/mysql-proxy.log
在master(server1)上:
创建新用户并授于读写权限
mysql> grant insert,update,delete on *.* to wsp@'%' identified by 'Westos+007';
mysql> flush privileges;
mysql -h 172.25.1.3 -uwsp -pWestos+007
在server3上:
下载lsof工具
yum install lsof-4.87-4.el7.x86_64 -y
lsof -i:3306
在物理机上再打开一个shell来连接数据库:
在server3上看到连接已经建立:
由于在同一个shell中连接两次,所有lsof -i:3306查看到第一次连接到server1,第二次连接到server2。
到此,server1与server2均被连接到,说明读写分离启用
。
在物理机上插入数据:
MySQL [yan]> insert into test values('user3','23');
MySQL [yan]> select * from test;
mysql> select * from test;
mysql> select * from test;
发现server1和server2都能看到,看不出读写分离,因为存在主从复制
在server2上关闭复制:
mysql> stop slave;
MySQL [yan]> insert into test values ('user4','19');
MySQL [yan]> select * from test;
mysql> select * from test;
mysql> select * from test;
发现插入的数据在server2上看不到,但是在server1上可以看到,客户端(真机)也查看不到数据,这就说明了它在读的时候读的是server2上的数据,而写操作却写在了server1上。