在我们的业务系统中,随着业务的增长,数据库的压力也随之产生,特别对于查询多于写入的业务环境下,迫切需要对读操作和写操作分离开来,这篇博文,主要描述mysql官方提供的mysql-proxy软件来实现读写分离[其实主要是通过lua脚本实现的],再结合mysql的主从复制,可以提升数据库的并发负载能力。但其稳定性较差,不建议使用,如果公司可以对lua脚本的读写分离重新定制开发,倒可以尝试,从途牛的招聘来看,途牛可能用的这一套,仅是推测。
附上简要原理图:
下面描述一下实验环境:
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
- [root@centos tmp]# yum -y install gcc-c++.x86_64
- [root@centos tmp]# tar -xf pkg-config-0.23.tar.gz
- [root@centos tmp]# cd pkg-config-0.23
- [root@centos pkg-config-0.23]# ./configure
- [root@centos pkg-config-0.23]# make
- [root@centos pkg-config-0.23]# make install
- # 确保PKG_CONFIG_PATH环境变量包含了相关的pkg-config配置文件路径:
- [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
- [root@centos tmp]# tar -xf libevent-1.4.11-stable.tar.gz
- [root@centos tmp]# cd libevent-1.4.11-stable
- [root@centos libevent-1.4.11-stable]# ./configure
- [root@centos libevent-1.4.11-stable]#make
- [root@centos libevent-1.4.11-stable]#make install
4.安装glib-2.20.0.tar.bz2
- [root@centos tmp]# tar -xf glib-2.20.0.tar.bz2
- [root@centos tmp]# cd glib-2.20.0
- [root@centos glib-2.20.0]# ./configure
- [root@centos glib-2.20.0]#make
- [root@centos glib-2.20.0]#make install
5.安装lua-5.1.4.tar.gz
- [root@centos lua-5.1.4]# yum -y install readline-devel.x86_64
- [root@centos tmp]# tar -xf lua-5.1.4.tar.gz
- [root@centos tmp]#cd lua-5.1.4
- # 如果你的服务器是64位的,这时要调整一下Makefile:vi src/Makefile,在CFLAGS里加上-fPIC,否则会出错
- # 接下来不用执行常见的configure,直接make,如下:
- [root@centos lua-5.1.4]# make linux
- [root@centos lua-5.1.4]# make install
- # 复制相应文件到指定目录
- [root@centos lua-5.1.4]# cp etc/lua.pc /usr/local/lib/pkgconfig/lua5.1.pc
6.安装mysql,我这里的mysql使用rpm安装mysql-devel[我这里已经安装好了,这一步我省略了]
- 注:编译安装完成后,要声明PATH变量,这样可以保证系统能找到mysql_config,后面编译mysql-proxy会用到它
- export PATH=$PATH:/usr/local/mysql/bin
- 同时,还要保证系统能找到mysql库文件:
- vi /etc/ld.so.conf
- 加入/usr/local/mysql/lib目录
- 执行:/sbin/ldconfig /etc/ld.so.conf
7.安装mysql-proxy-0.8.3.tar.gz
- [root@centos tmp]# tar -xf mysql-proxy-0.8.3.tar.gz
- [root@centos tmp]# cd mysql-proxy-0.8.3
- [root@centos mysql-proxy-0.8.3]# ./configure
- [root@centos mysql-proxy-0.8.3]# make
- [root@centos mysql-proxy-0.8.3]# make install
- # 创建相应目录
- [root@centos mysql-proxy-0.8.3]# mkdir -p /usr/local/mysql-proxy/share/doc/mysql-proxy
- # 复制读写分离脚本 和 管理接口脚本
- [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/
- [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/
- # 手动启动mysql-proxy测试
- [root@centos ~]# mysql-proxy --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"
- #/* --daemon 采用daemon方式启动
- #/* --proxy-backend-addresses=** 指定读写都可以的mysql数据库的IP地址和端口
- #/* --proxy-read-only-backend-addresses=**指定只读mysql数据库的IP地址和端口#/* --proxy-lua-script=** 指定读写分离脚本的位置
- #/* --admin-username=** 指定mysql-proxy管理的用户
- #/* --admin-password=** 指定mysql-proxy管理用户的密码
- #/* --admin-lua-script=** 指定mysql-proxy管理接口lua脚本的位置
- #/* --log-level=debug 定义log日志级别,由高到低分别有(error|warning|info|message|debug)
- #/* --log-file=** 定义log日志文件路径
- #/* --admin-address=:4041 指定mysql proxy的管理端口,在这里,表示本机的4041端口[可以省略]
- #/* --proxy-address=:3307 指定mysql proxy的监听端口(默认4040),也可以用 127.0.0.1:3307表示[可以省略],此接口是提供给应用访问数据库的地址和端口
8.启动数据库[记的关闭防火墙,不然会有问题,也可以添加防火墙策略]
- [root@client102 ~]# mysqld_multi start
- [root@client102 ~]# mysqld_multi report
- Reporting MySQL servers
- MySQL server from group: mysqld3306 is running
- MySQL server from group: mysqld3307 is running
- # 登陆数据库 授予mysql-proxy服务器的访问
- [root@client102 ~]# mysql -uroot -S /usr/local/mysql/mysqld3306.sock -p
- mysql> GRANT all privileges ON *.* TO 'kongzhong'@'192.168.1.104' IDENTIFIED BY 'kongzhong';
- mysql> flush privileges;
- [root@client102 ~]# mysql -uroot -S /usr/local/mysql/mysqld3307.sock -p
- mysql> GRANT all privileges ON *.* TO 'kongzhong'@'192.168.1.104' IDENTIFIED BY 'kongzhong';
- mysql> flush privileges;
- [root@centos lib]# /etc/init.d/mysqld start
- [root@centos lib]# mysql -u root -p
- mysql> GRANT all privileges ON *.* TO 'kongzhong'@'192.168.1.104' IDENTIFIED BY 'kongzhong';
- mysql> flush privileges;
9.登陆测试
- # 这里是mysql-proxy服务器所在的iP地址和提供给外面的访问端口[使用任何一台提供mysql登陆功能的机器,记得关闭防火墙]
- [root@client102 ~]# mysql -ukongzhong -p -h192.168.1.104 --port=4040
- # 正常登陆基本上就证明mysql-proxy已经配置成功
- # 测试的话,使用下面的语句,但需要反复测试,没有压力是没法测出读写分离效果的
- [root@client102 ~]# mysql -ukongzhong -p -h192.168.1.104 --port=4040 -e "select * from mysql.user"
- [root@client102 ~]# mysql -ukongzhong -p -h192.168.1.104 --port=4040 -e "create database kongzhong"
- # 管理接口[此接口也仅能执行这一条命令,查看读写分离状态]
- [root@client102 ~]# mysql -h192.168.1.104 --port=4041 -uadmin -p
- mysql> select * from backends;
- +-------------+--------------------+---------+------+------+-------------------+
- | backend_ndx | address | state | type | uuid | connected_clients |
- +-------------+--------------------+---------+------+------+-------------------+
- | 1 | 192.168.1.104:3306 | up | rw | NULL | 0 |
- | 2 | 192.168.1.102:3306 | unknown | ro | NULL | 0 |
- | 3 | 192.168.1.102:3307 | unknown | ro | NULL | 0 |
- +-------------+--------------------+---------+------+------+-------------------+
- 注意: 在测试读写分离的时候,我们可以分布测试,比如先测试读的语句,查看读写状态是否UP ,然后在测试写的语句,反反复复多测试几次才能看出效果,本人在测试的时候也出现过读的状态不能up 解决办法是 多测试即便就出来了。
- # 因为我们现在还没有写启动脚本,所以只能手动杀掉进程
- [root@centos mysql-proxy]# killall mysql-proxy
10.配置启动脚本和启动配置文件
- # mysql-proxy启动脚本配置
- [root@centos run]# vim /etc/init.d/mysql-proxy
- # 脚本内容如下
- #!/bin/sh
- # Source function library.
- . /etc/rc.d/init.d/functions
- # PROXY_PATH 这里需要指向你mysql-proxy命令所在的路径
- PROXY_PATH=/usr/local/bin
- prog="mysql-proxy"
- # Source networking configuration.
- . /etc/sysconfig/network
- # Check that networking is up.
- [ ${NETWORKING} = "no" ] && exit 0
- # Set default mysql-proxy configuration.
- PROXY_OPTIONS="--daemon"
- PROXY_PID=/var/run/mysql-proxy.pid
- # Source mysql-proxy configuration.
- if [ -f /etc/sysconfig/mysql-proxy ] ; then
- . /etc/sysconfig/mysql-proxy
- fi
- PATH=$PATH:/usr/bin:/usr/local/bin:$PROXY_PATH
- # By default it's all good
- RETVAL=0
- # See how we were called.
- case "$1" in
- start)
- # Start daemon.
- echo -n $"Starting $prog: "
- daemon $NICELEVEL $PROXY_PATH/mysql-proxy $PROXY_OPTIONS --pid-file $PROXY_PID
- RETVAL=$?
- echo
- if [ $RETVAL = 0 ]; then
- touch /var/lock/subsys/mysql-proxy
- fi
- ;;
- stop)
- # Stop daemons.
- echo -n $"Stopping $prog: "
- killproc $prog
- RETVAL=$?
- echo
- if [ $RETVAL = 0 ]; then
- rm -f /var/lock/subsys/mysql-proxy
- rm -f $PROXY_PID
- fi
- ;;
- restart)
- $0 stop
- sleep 3
- $0 start
- ;;
- condrestart)
- [ -e /var/lock/subsys/mysql-proxy ] && $0 restart
- ;;
- status)
- status mysql-proxy
- RETVAL=$?
- ;;
- *)
- echo "Usage: $0 {start|stop|restart|status|condrestart}"
- RETVAL=1
- ;;
- esac
- exit $RETVAL
- # 写配置文件 启动脚本会读取此配置文件:
- [root@centos run]# vim /etc/sysconfig/mysql-proxy
- # 文件内容如下[此内容需写在一行,不可主从换行,不然会有错]
- 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"
- # 赋予脚本执行权限
- [root@centos run]# chmod +x /etc/init.d/mysql-proxy
- # 测试脚本使用:
- [root@centos run]# /etc/init.d/mysql-proxy start
- Starting mysql-proxy: [ OK ]
- [root@centos run]# netstat -tulnap|grep mysql
- tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 5454/mysql-proxy
- tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 5454/mysql-proxy
- [root@centos run]# /etc/init.d/mysql-proxy stop
- Stopping mysql-proxy: [ OK ]
- # 以上mysql-proxy就配置好了,读写分离的效果需要有压力,大家需要反复测试,才能在管理接口上看到
- # mysql的主从搭建,这里就不配置,各位可以参考上面的文章,如果有疑问,可在下面留言反馈。