基于mysql-proxy实现mysql数据库的读写分离

在我们的业务系统中,随着业务的增长,数据库的压力也随之产生,特别对于查询多于写入的业务环境下,迫切需要对读操作和写操作分离开来,这篇博文,主要描述mysql官方提供的mysql-proxy软件来实现读写分离[其实主要是通过lua脚本实现的],再结合mysql的主从复制,可以提升数据库的并发负载能力。但其稳定性较差,不建议使用,如果公司可以对lua脚本的读写分离重新定制开发,倒可以尝试,从途牛的招聘来看,途牛可能用的这一套,仅是推测。

附上简要原理图:

MY-PROXY

下面描述一下实验环境:

mysql-proxy:192.168.1.104

mysql1:192.168.1.104(master -- w)

mysql2:192.168.1.102(slave -- r)

mysql3:192.168.1.100(slave -- r)

为能看到读写分离的效果,我这里就不配置数据库之间的主从关系,仅做mysql-proxy的配置[这里采用编译安装]

1.编译安装需要安装如下几个软件:[以下几个软件我都解压放在/tmp下]

glib,libenent,lua,pkg-config,mysql-proxy

软件共享下载地址:http://www.kuaipan.cn/file/id_119710994921422889.htm

2.安装pkg-config-0.23.tar.gz

  1. [root@centos tmp]# yum -y install gcc-c++.x86_64  
  2. [root@centos tmp]# tar -xf pkg-config-0.23.tar.gz  
  3. [root@centos tmp]# cd pkg-config-0.23  
  4. [root@centos pkg-config-0.23]# ./configure  
  5. [root@centos pkg-config-0.23]# make  
  6. [root@centos pkg-config-0.23]# make install  
  7. # 确保PKG_CONFIG_PATH环境变量包含了相关的pkg-config配置文件路径:  
  8. [root@centos pkg-config-0.23]# export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig  

3.安装libevent-1.4.11-stable.tar.gz

  1. [root@centos tmp]# tar -xf libevent-1.4.11-stable.tar.gz  
  2. [root@centos tmp]# cd libevent-1.4.11-stable  
  3. [root@centos libevent-1.4.11-stable]# ./configure  
  4. [root@centos libevent-1.4.11-stable]#make  
  5. [root@centos libevent-1.4.11-stable]#make install  

4.安装glib-2.20.0.tar.bz2

  1. [root@centos tmp]# tar -xf glib-2.20.0.tar.bz2  
  2. [root@centos tmp]# cd glib-2.20.0  
  3. [root@centos glib-2.20.0]# ./configure  
  4. [root@centos glib-2.20.0]#make  
  5. [root@centos glib-2.20.0]#make install  

5.安装lua-5.1.4.tar.gz

  1. [root@centos lua-5.1.4]# yum -y install readline-devel.x86_64  
  2. [root@centos tmp]# tar -xf lua-5.1.4.tar.gz  
  3. [root@centos tmp]#cd lua-5.1.4  
  4. # 如果你的服务器是64位的,这时要调整一下Makefile:vi src/Makefile,在CFLAGS里加上-fPIC,否则会出错  
  5. # 接下来不用执行常见的configure,直接make,如下:  
  6. [root@centos lua-5.1.4]# make linux  
  7. [root@centos lua-5.1.4]# make install  
  8. # 复制相应文件到指定目录  
  9. [root@centos lua-5.1.4]# cp etc/lua.pc /usr/local/lib/pkgconfig/lua5.1.pc  

6.安装mysql,我这里的mysql使用rpm安装mysql-devel[我这里已经安装好了,这一步我省略了]

  1. 注:编译安装完成后,要声明PATH变量,这样可以保证系统能找到mysql_config,后面编译mysql-proxy会用到它  
  2. export PATH=$PATH:/usr/local/mysql/bin  
  3. 同时,还要保证系统能找到mysql库文件:  
  4. vi /etc/ld.so.conf  
  5. 加入/usr/local/mysql/lib目录  
  6. 执行:/sbin/ldconfig /etc/ld.so.conf  

7.安装mysql-proxy-0.8.3.tar.gz

  1. [root@centos tmp]# tar -xf mysql-proxy-0.8.3.tar.gz  
  2. [root@centos tmp]# cd mysql-proxy-0.8.3  
  3. [root@centos mysql-proxy-0.8.3]# ./configure  
  4. [root@centos mysql-proxy-0.8.3]# make  
  5. [root@centos mysql-proxy-0.8.3]# make install  
  6. # 创建相应目录  
  7. [root@centos mysql-proxy-0.8.3]# mkdir -p /usr/local/mysql-proxy/share/doc/mysql-proxy  
  8. # 复制读写分离脚本 和 管理接口脚本  
  9. [root@centos mysql-proxy-0.8.3]#cp /tmp/mysql-proxy-0.8.3/lib/rw-splitting.lua /usr/local/mysql-proxy/share/doc/mysql-proxy/  
  10. [root@centos mysql-proxy-0.8.3]#cp /tmp/mysql-proxy-0.8.3/lib/admin.lua /usr/local/mysql-proxy/share/doc/mysql-proxy/  
  11. # 手动启动mysql-proxy测试  
  12. [root@centos ~]# mysql-proxy --daemon --log-level=debug --log-file=/var/log/mysql-proxy.log \  
  13. > --plugins="proxy" --proxy-backend-addresses="192.168.1.104:3306" \  
  14. > --proxy-read-only-backend-addresses="192.168.1.102:3306" \  
  15. > --proxy-read-only-backend-addresses="192.168.1.102:3307" \  
  16. > --proxy-lua-script="/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua" \  
  17. > --plugins=admin \  
  18. > --admin-username="admin" \  
  19. > --admin-password="admin" \  
  20. > --admin-lua-script="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"  
  21.   
  22. #/* --daemon 采用daemon方式启动  
  23. #/* --proxy-backend-addresses=** 指定读写都可以的mysql数据库的IP地址和端口  
  24. #/* --proxy-read-only-backend-addresses=**指定只读mysql数据库的IP地址和端口#/* --proxy-lua-script=** 指定读写分离脚本的位置  
  25. #/* --admin-username=** 指定mysql-proxy管理的用户  
  26. #/* --admin-password=** 指定mysql-proxy管理用户的密码  
  27. #/* --admin-lua-script=** 指定mysql-proxy管理接口lua脚本的位置  
  28. #/* --log-level=debug 定义log日志级别,由高到低分别有(error|warning|info|message|debug)  
  29. #/* --log-file=** 定义log日志文件路径  
  30. #/* --admin-address=:4041 指定mysql proxy的管理端口,在这里,表示本机的4041端口[可以省略]  
  31. #/* --proxy-address=:3307 指定mysql proxy的监听端口(默认4040),也可以用 127.0.0.1:3307表示[可以省略],此接口是提供给应用访问数据库的地址和端口  

8.启动数据库[记的关闭防火墙,不然会有问题,也可以添加防火墙策略]

  1. [root@client102 ~]# mysqld_multi start  
  2. [root@client102 ~]# mysqld_multi report  
  3. Reporting MySQL servers  
  4. MySQL server from group: mysqld3306 is running  
  5. MySQL server from group: mysqld3307 is running  
  6. # 登陆数据库 授予mysql-proxy服务器的访问  
  7. [root@client102 ~]# mysql -uroot -S /usr/local/mysql/mysqld3306.sock -p  
  8. mysql> GRANT all privileges ON *.* TO 'kongzhong'@'192.168.1.104' IDENTIFIED BY 'kongzhong';  
  9. mysql> flush privileges;  
  10. [root@client102 ~]# mysql -uroot -S /usr/local/mysql/mysqld3307.sock -p  
  11. mysql> GRANT all privileges ON *.* TO 'kongzhong'@'192.168.1.104' IDENTIFIED BY 'kongzhong';  
  12. mysql> flush privileges;  
  13. [root@centos lib]# /etc/init.d/mysqld start  
  14. [root@centos lib]# mysql -u root -p  
  15. mysql> GRANT all privileges ON *.* TO 'kongzhong'@'192.168.1.104' IDENTIFIED BY 'kongzhong';  
  16. mysql> flush privileges;  

9.登陆测试

  1. # 这里是mysql-proxy服务器所在的iP地址和提供给外面的访问端口[使用任何一台提供mysql登陆功能的机器,记得关闭防火墙]  
  2. [root@client102 ~]# mysql -ukongzhong -p -h192.168.1.104 --port=4040  
  3. # 正常登陆基本上就证明mysql-proxy已经配置成功  
  4. # 测试的话,使用下面的语句,但需要反复测试,没有压力是没法测出读写分离效果的  
  5. [root@client102 ~]# mysql -ukongzhong -p -h192.168.1.104 --port=4040 -e "select * from mysql.user"  
  6. [root@client102 ~]# mysql -ukongzhong -p -h192.168.1.104 --port=4040 -e "create database kongzhong"  
  7. # 管理接口[此接口也仅能执行这一条命令,查看读写分离状态]  
  8. [root@client102 ~]# mysql -h192.168.1.104 --port=4041 -uadmin -p  
  9. mysql> select * from backends;  
  10. +-------------+--------------------+---------+------+------+-------------------+  
  11. | backend_ndx | address | state | type | uuid | connected_clients |  
  12. +-------------+--------------------+---------+------+------+-------------------+  
  13. | 1 | 192.168.1.104:3306 | up | rw | NULL | 0 |  
  14. | 2 | 192.168.1.102:3306 | unknown | ro | NULL | 0 |  
  15. | 3 | 192.168.1.102:3307 | unknown | ro | NULL | 0 |  
  16. +-------------+--------------------+---------+------+------+-------------------+  
  17. 注意: 在测试读写分离的时候,我们可以分布测试,比如先测试读的语句,查看读写状态是否UP ,然后在测试写的语句,反反复复多测试几次才能看出效果,本人在测试的时候也出现过读的状态不能up 解决办法是 多测试即便就出来了。  
  18. # 因为我们现在还没有写启动脚本,所以只能手动杀掉进程  
  19. [root@centos mysql-proxy]# killall mysql-proxy  

10.配置启动脚本和启动配置文件

  1. # mysql-proxy启动脚本配置  
  2. [root@centos run]# vim /etc/init.d/mysql-proxy  
  3. # 脚本内容如下  
  4. #!/bin/sh  
  5. # Source function library.  
  6. . /etc/rc.d/init.d/functions  
  7. # PROXY_PATH 这里需要指向你mysql-proxy命令所在的路径  
  8. PROXY_PATH=/usr/local/bin  
  9. prog="mysql-proxy"  
  10. # Source networking configuration.  
  11. . /etc/sysconfig/network  
  12. # Check that networking is up.  
  13. [ ${NETWORKING} = "no" ] && exit 0  
  14. # Set default mysql-proxy configuration.  
  15. PROXY_OPTIONS="--daemon"  
  16. PROXY_PID=/var/run/mysql-proxy.pid  
  17. # Source mysql-proxy configuration.  
  18. if [ -f /etc/sysconfig/mysql-proxy ] ; then  
  19. . /etc/sysconfig/mysql-proxy  
  20. fi  
  21. PATH=$PATH:/usr/bin:/usr/local/bin:$PROXY_PATH  
  22. # By default it's all good  
  23. RETVAL=0  
  24. # See how we were called.  
  25. case "$1" in  
  26. start)  
  27. # Start daemon.  
  28. echo -n $"Starting $prog: "  
  29. daemon $NICELEVEL $PROXY_PATH/mysql-proxy $PROXY_OPTIONS --pid-file $PROXY_PID  
  30. RETVAL=$?  
  31. echo  
  32. if [ $RETVAL = 0 ]; then  
  33. touch /var/lock/subsys/mysql-proxy  
  34. fi  
  35. ;;  
  36. stop)  
  37. # Stop daemons.  
  38. echo -n $"Stopping $prog: "  
  39. killproc $prog  
  40. RETVAL=$?  
  41. echo  
  42. if [ $RETVAL = 0 ]; then  
  43. rm -f /var/lock/subsys/mysql-proxy  
  44. rm -f $PROXY_PID  
  45. fi  
  46. ;;  
  47. restart)  
  48. $0 stop  
  49. sleep 3  
  50. $0 start  
  51. ;;  
  52. condrestart)  
  53. [ -e /var/lock/subsys/mysql-proxy ] && $0 restart  
  54. ;;  
  55. status)  
  56. status mysql-proxy  
  57. RETVAL=$?  
  58. ;;  
  59. *)  
  60. echo "Usage: $0 {start|stop|restart|status|condrestart}"  
  61. RETVAL=1  
  62. ;;  
  63. esac  
  64. exit $RETVAL  
  65.   
  66. # 写配置文件 启动脚本会读取此配置文件:  
  67. [root@centos run]# vim /etc/sysconfig/mysql-proxy  
  68. # 文件内容如下[此内容需写在一行,不可主从换行,不然会有错]
  69. PROXY_OPTIONS="--daemon --log-level=debug --log-file=/var/log/mysql-proxy.log --plugins=proxy --proxy-backend-addresses=192.168.1.104:3306 --proxy-read-only-backend-addresses=192.168.1.102:3306 --proxy-read-only-backend-addresses=192.168.1.102:3307 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua --plugins=admin --admin-username=admin --admin-password=admin --admin-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"  
  70. # 赋予脚本执行权限  
  71. [root@centos run]# chmod +x /etc/init.d/mysql-proxy  
  72. # 测试脚本使用:  
  73. [root@centos run]# /etc/init.d/mysql-proxy start  
  74. Starting mysql-proxy: [ OK ]  
  75. [root@centos run]# netstat -tulnap|grep mysql  
  76. tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 5454/mysql-proxy  
  77. tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 5454/mysql-proxy  
  78. [root@centos run]# /etc/init.d/mysql-proxy stop  
  79. Stopping mysql-proxy: [ OK ]  
  80. # 以上mysql-proxy就配置好了,读写分离的效果需要有压力,大家需要反复测试,才能在管理接口上看到  
  81. # mysql的主从搭建,这里就不配置,各位可以参考上面的文章,如果有疑问,可在下面留言反馈。

你可能感兴趣的:(基于mysql-proxy实现mysql数据库的读写分离)