Centos6.4 x86_64下MySQL Proxy0.8.5安装测试实现读写分离

来源:互联网 发布:激战2网络错误 编辑:程序博客网 时间:2024/04/28 02:08

一、mysql-proxy简介
MySQL Proxy是一个处于MySQL Client端和MySQL Server端之间的简单程序,是mysql官方提供的MySQL中间件服务,可以将其理解为一个连接池,负责将前台应用的连接请求转发给后台的数据库,并且通过使用lua脚本,可以实现复杂的连接控制和过滤,从而实现读写分离和负载平衡。对于应用来说,MySQL Proxy是完全透明的,应用则只需要连接到MySQL Proxy的监听端口即可。当然,这样proxy机器可能成为单点失效,但完全可以使用多个proxy机器做为冗余,在应用服务器的连接池配置中配置到多个proxy的连接参数即可。MySQL Proxy更强大的一项功能是实现“ 读写分离”,基本原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性查询导致的变更同步到集群中的从库。在生成Mysql的M-S结构后,为了实现读写分离,需要使用Mysql Proxy。本文Mysql Proxy的版本为0.8.5 。
这里写图片描述
二、安装MySQL Proxy0.8.5:
yum安装必须的库,同时解决pkg-config、libtool和Mysql开发库,由于mysql-proxy实际并不需要在本机上运行mysql实例,因此在这里用yum安装,源码Mysql Proxy安装之前有先决条件,如下:检查系统所需软件包
通过 rpm -qa | grep name 的方式验证以下软件包是否已全部安装:
gcc* gcc-c++* autoconf* automake* zlib* libxml* ncurses-devel* libmcrypt* libtool* flex* pkgconfig* libevent* glib*
其他依赖软件包:libevent 1.x 或更高;glib2 2.6.0 或更高;lua 5.1.x 或更高;pkg-config;libtool 1.5 或更高;MySQL 5.0.x 或更高的开发库
这里写图片描述
本实验采用已经编译好的二进制版本解压安装,解压缩的目录为: /usr/local
这里写图片描述
将命令路径添加到PATH环境变量方便使用,这里安装的版本为0.8.5
这里写图片描述
三、配置测试MySQL Proxy
MySQL Proxy环境设置说明
Master MySQL服务器:10.33.100.88
Slave MySQL服务器:10.33.100.77
MySQL Proxy服务器:10.33.100.55
这里写图片描述
mysql-proxy的配置选项大致可分为帮助选项、管理选项、代理选项及应用程序选项几类。
这里写图片描述
mysql proxy的各配置参数请参见官方文档http://dev.mysql.com/doc/refman/5.6/en/mysql-proxy-configuration.html
管理功能选项:
–admin-address=host:port 指定一个mysqo-proxy的管理端口,默认是4041;
–admin-username = < string > username to allow to log in
–admin-password =< string > password to allow to log in
–admin-lua-script=< filename > script to execute by the admin plugin
代理功能选项:
–proxy-skip-profiling 关闭查询分析功能, 缺省是打开的;
-r,–proxy-read-only-backend-addresses=< file > 只读Slave的地址和端口,缺省为不设置;
-P,–proxy-address=< host:port > 是mysql-proxy 服务器端的监听端口,缺省是4040,建议改为3306,方便开发人员写代码。
-b,–proxy-backend-addresses=< host:port > 远程Master地址和端口,可设置多个做failover和load balance,默认127.0.0.1:3306;
-s,–proxy-lua-script=< host:port > 指定一个Lua脚本来控制mysql-proxy的运行和设置,该脚本在每次新建连接和脚本发生修改的的时候将重新调用;
应用选项:
–daemon mysql-proxy以守护进程方式运行;
–pid-file=< file > 设置mysql-proxy的存储PID文件的路径;
–user=user_name运行mysql-proxy进程的用户;
–plugins=plugin,.. 在mysql-proxy启动时加载的插件;
–proxy-skip-profiling 禁用profile;
–proxy-lua-script=< file > 完成mysql代理功能的Lua脚本;
–defaults-file= < file > mysql-proxy的参数信息默认置入的配置文件路径;其配置段使用[mysql-proxy]标识;
–keepalive try to restart the proxy if it crashed,保持连接启动进程会有2个, 一号进程用来监 视二号进程, 如果二号进程死掉自动重启proxy,这是新版MySQL Proxy的增加的Keepalived功能,它修正了以前MySQL Proxy容易死掉的bug,建议开启。
1.在Master/Slave建立一个测试用户,因为以后客户端发送的SQL都是通过mysql-proxy服务器来转发,所以要确保可以从mysql-proxy服务器上登录MySQL主从库,分别在主和从MySQL服务器上授权远程连接测试用户
这里写图片描述
2.将mysql-proxy启动选项编辑到配置文件中:
这里写图片描述
这里写图片描述
3.修改读写分离lua脚本,让测试更容易,Lua脚本默认最小4个最大8个以上的客户端连接才会实现读写分离(这是因为mysql-proxy会检测客户端连接, 当连接没有超过min_idle_connections预设值时,不会进行读写分离,即查询操作会发生到Master上),现改为最小1个最大2个,改动内容如下所示:
这里写图片描述
4.启动MySQL Proxy进行测试,注意:使用配置文件的形式启动,注意配置文件必须是660权限,否则无法启动。如果有多个Slave的话,proxy-read-only-backend-addresses参数可以配置多个以逗号分隔的IP:Port从库列表。
这里写图片描述
更改配置文件权限在重新以守护进程的方式启动,监测MySQL Proxy的日志可以发现MySQL Proxy已成功启动了端口,(注意之前要成功启动Master和Slave上的mysqld服务)但是试了很多次,admin模块都无法启动,只能正常启动proxy
这里写图片描述
这里写图片描述
5.客户端连接测试,先停止Slave的复制进程
这里写图片描述
多开些MySQL客户端,连接Proxy端口, 对数据进行读写操作,发现insert操作成功, 但是select不出刚插入的数据, 说明连接到了Slave, 读写分离成功.

[root@DQ ~]# mysql -uroot -p -h10.33.100.55 --port=4040 

MySQL Proxy很容易的利用Lua脚本实现读写分离功能,停掉Master上的MySQL时发现,MySQL Proxy直接不允许连接数据了。
MySQL Proxy启动后,如果看到网站页面全是乱码,可在主从数据库的配置文件my.cnf加进如下代码以避免这个问题:

    [mysqld]      skip-character-set-client-handshake      init-connect='SET NAMES utf8'    default-character-set=utf8 

6. 为mysql-proxy提供SysV服务脚本,内容如下所示
这里写图片描述
/etc/sysconfig/mysql-proxy
这里写图片描述
/etc/rc.d/init.d/mysql-proxy
这里写图片描述
这里写图片描述
这里写图片描述
四、他人经验分享:
1、当MySQL主从复制在 show slave status\G 时出现Slave_IO_Running或Slave_SQL_Running 的值不为YES时,需要首先通过 stop slave 来停止从服务器,然后reset slave,再重新执行命令

change master to master_host='hostname',master_user='username',master_password='passwd',matser_auto_position=1

然后再执行一次slave start即可
2、MySQL-Proxy的rw-splitting.lua脚本在网上有很多版本,但是最准确无误的版本仍然是源码包中所附带的lib/rw-splitting.lua脚本,如果有lua脚本编程基础的话,可以在这个脚本的基础上再进行优化;
3、MySQL-Proxy实际上非常不稳定,在高并发或有错误连接的情况下,进程很容易自动关闭,因此打开–keepalive参数让进程自动恢复是个比较好的办法,但还是不能从根本上解决问题,因此通常最稳妥的做法是在每个从服务器上安装一个MySQL-Proxy供自身使用,虽然比较低效但却能保证稳定性;
4、一主多从的架构并不是最好的架构,通常比较优的做法是通过程序代码和中间件等方面,来规划,比如设置对表数据的自增id值差异增长等方式来实现两个或多个主服务器,但一定要注意保证好这些主服务器数据的完整性,否则效果会比多个一主多从的架构还要差;
5、生产环境中如果想要读写分离并且读集群、写集群机器比较多情况下,用mysql proxy 需要相当大的工作量。mysql proxy没有配置文件, lua脚本就是它的全部,需要编写大量的脚本才能完成一个复杂的配置。Amoeba for MySQL 是一款优秀的中间件软件,只需要进行相关的配置同样可以实现读写分离,负载均衡等功能,并且稳定性要大大超过MySQL-Proxy,建议大家用来替代MySQL-Proxy,甚至MySQL-Cluster。
五、mysql-proxy脚本编程
mysql-proxy实现分析与修改请求,拦截查询和修改结果,性能分析与监控,读写分离,请求路由等各种功能都需要通过编写Lua脚本来完成。mysql-proxy是个框架,具备很好的扩展性。这个框架提供了6个hook点,能够让用户能够动态的介入到client与server中的通讯中去。mysql-proxy允许用户指定Lua脚本对请求进行拦截,对请求进行分析与修改,它还允许用户指定Lua脚本对服务器的返回结果进行修改,加入一些结果集或者去除一些结果集均可。
connect_server()
mysql-client向proxy发起连接时,proxy会调用这个函数。用户可以实现该函数,来做一些负载均衡的事情,例如选择将要连向那个mysql-server。假设有多个mysql-server后端,而用户又没有实现这个函数,proxy默认采用轮询(round-robin)策略。
read_handshake()
mysql-server向proxy返回“初始握手信息”时,proxy会调用这个函数。用户可以实现这个函数,来做更多的权限验证工作。
read_auth()
mysql-client向proxy发送认证报文(user_name, password,database)时,proxy会调用这个函数。
read_auth_result()
mysql-server向proxy返回认证结果时,proxy会调用这个函数。
read_query()
认证完成后,mysql-client每次经过proxy向mysql-server发送query报文时,proxy会调用这个函数。用户如果要拦截请求,就可以模拟mysql-server直接返回了,当然用户亦可以实现各种策略,修改请求,路由请求等各种不同的业务逻辑。
read_query_result()
认证完成后,mysql-server每次经过proxy向mysql-client返回query结果时,proxy会调用这个函数。需要注意,如果用户没有显示实现read_query()函数,则read_query_result()函数是不会被调用的。用户可以在此处实现各种合并策略,或者对结果集进行修改。
【下图是一个各hook函数的触发图(请注意请求方向)】
这里写图片描述
【可以发现,最重要的两个函数其实是read_query()和read_query_result(),各种sql的改写与结果集的改写逻辑,都是在这两个函数中实现的,更细节的query过程如下图】
这里写图片描述

0 0
原创粉丝点击