Mysql的主从复制和Mysql的读写分离两者有着紧密联系,首先部署主从复制,只有主从复制完了,才能在此基础上进行数据的读写分离。Master数据库处理事务性增、删除、修改、更新操作(CREATE、INSERT、UPDATE、DELETE),而让Slave数据库处理SELECT操作,MYSQL读写分离前提是基于MYSQL主从复制,这样可以保证在Master上修改数据,Slave同步之后,WEB应用可以读取到Slave端的数据。 简单来说,读写分离就是只在主服务器上写,只在从服务器上读,基本的原理是让主数据库处理事务性查询,而从数据库处理select查询,数据库复制被用来把事务性查询导致的改变更新同步到集群中的从数据库。
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有两个代表性程序。
(1)mysql-proxy 为mysql开源项目,通过其自带的lua脚本进行SQL判断,虽然是mysql的官方产品,但是mysql官方不建议将其应用到生产环境
(2)Amoeba (变形虫)由陈思儒开发,曾就职与阿里巴巴,该程序由java语言进行开发,阿里巴巴将其应用于生成环境,它不支持事物和存储过程
实验环境:基于gtid的异步复制(主从复制),再开一台server3(ip=172.25.7.3)做proxy,相当于代理
在server3上
1、解压mysql-proxy的tar包到/usr/local:tar zxf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local
2、进入到/usr/local,创建软链接,便于访问 ln -s mysql-proxy-0.8.5-linux-el6-x86-64bit/ mysql-proxy
进入到/usr/local/mysql-proxy/bin可以看到启动脚本
3、进入到/usr/local/mysql-proxy,自己手动建立配置文件目录和配置文件
[mysql-proxy]
proxy-address=0.0.0.0:3306 ##mysql-proxy运行的端口
proxy-backend-addresses=172.25.7.1:3306 ##master节点:可读可写
proxy-read-only-backend-addresses=172.25.7.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 ##打入后台
4、修改lua脚本**vim /usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua**
把原来的4和8改为1和2,默认超过4个连接才会启动读写分离,改为2个便于测试。
5、启动mysql-proxy:/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/mysql-proxy.conf
此时报错:
(critical) mysql-proxy-cli.c:326: loading config from '/usr/local/mysql-proxy/conf
/mysql-proxy.conf' failed:permissions of /usr/local/mysql-proxy/conf/mysql-proxy.conf
aren't secure (0660 or stricter required)
原因:配置文件权限过大
更改方法:修改文件权限 chmod 660 /usr/local/mysql-proxy/conf/mysql-proxy.conf
再次启动
此时又报错:不能打开日志文件/usr/local/mysql-proxy/log/mysql-proxy.log
更改方法:创建日志目录 :mkdir -p /usr/local/mysql-proxy/log
再次启动成功。
6、查看日志:cat /usr/local/mysql-proxy/log/mysql-proxy.log,可以看到两个节点都加进来了。
7、在server1上,授权新用户ran读写权限
mysql> grant insert,update,select on *.* to ran@'%' identified by 'Westos==123';
mysql> flush privileges;
8、在物理机上,打开一个shell以ran用户来连接数据库
mysql -h 172.25.7.3 -uran -pWestos123==
9、在server3上,用lsof命令对mysql的端口3306进行监测,列出谁在使用3306端口:lsof -i:3306
此时,可以看到已经建立了一个连接
我们在物理机上再打开两个shell来连接数据库,就可以看到 前两次的连接都指向server1,第三次的连接指向server2,说明启动了读写分离。
MySQL [ranran]> insert into usertb values ('user3','333');
MySQL [ranran]> select * from usertb;
发现server1和server2都能看到,看不出读写分离,这是因为存在主从复制。
在server2上,关闭主从复制
在物理机上 ,再次插入数据,发现插入的数据在物理机上看不到
MySQL [ranran]> insert into usertb values ('user4','456');
MySQL [ranran]> insert into usertb values ('user7','999');
MySQL [ranran]> select * from usertb;
但是在server1上可以看到,这就说明了它在读的时候读的是server2上的数据,而写操作却写在了server1上
此时,在server2上,开启主从复制,就可以看到物理机插入的信息了
这就再次说明了它在读的时候读的是server2上的数据
通过mysql-proxy来实现读写分离,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而且没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,且mysql-proxy的性能不高。利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单