MySQL5.5读写分离之mysql-proxy
通常一个网站在初期访问量都比较小,所以一般的小架构足以支撑。但是,当网站逐渐发展起来后,随之而来的是大量的访问,这时候最先出现的瓶颈就是数据库了。因为数据的写入读取操作(I/O)是集群中响应速度最慢的,所以在集群建设时就要规划好后端存储架构。
后端存储数据库架构普遍是主从复制,这样解决了数据备份问题。但是,由前端来的读写请求都要经过主库,量小没问题,当量大到超过主库的性能极限时,主库分分钟会宕机。
为了避免主库宕机这种灾难性事件的发生,读写分离的设计诞生了!把写的请求只交给主库,读的请求由主库和从库一起分摊,这样就大大减轻了主库的负担。
大部分公司会由开发部门在软件层面实现对数据库的读写分离,其次可以选择读写分离的中间件如:TDDL、amoeba、cobar、MySQL-proxy、Atlas、MyCat。
本次测试采用MySQL官方发布的MySQL-proxy。
官网下载地址(二进制包):https://downloads.mysql.com/archives/get/file/mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
测试环境:
[root@SQL-M ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@SQL-M ~]# uname -r
2.6.32-642.el6.x86_64
MySQL-proxy IP:192.168.0.86
MySQL-master IP:192.168.0.88
MySQL-slave IP:192.168.0.90
前提:MySQL主库与从库已经实现主从复制。
实现主从复制请参考我的前一篇博文:http://yuyicong.blog.51cto.com/11274530/1919158
接下来的操作在proxy服务器上:
[root@SQL-proxy ~]# cd /usr/local/src/
[root@SQL-proxy src]# wget https://downloads.mysql.com/archives/get/file/mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
[root@SQL-proxy src]# ll -h
total 12M
-rw-r--r-- 1 root root 12M Aug 19 2014 mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
[root@SQL-proxy src]# tar zxf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local/
[root@SQL-proxy src]# cd ..
[root@SQL-proxy local]# mv mysql-proxy-0.8.5-linux-el6-x86-64bit/ mysql-proxy-0.8.5
[root@SQL-proxy local]# ll -d mysql-proxy-0.8.5
drwxr-xr-x 8 7161 wheel 4096 Aug 19 2014 mysql-proxy-0.8.5 # 看到所属用户和组有问题
[root@SQL-proxy local]# chown -R root:root mysql-proxy-0.8.5/ # 改为root
[root@SQL-proxy local]# ln -s mysql-proxy-0.8.5/ mysql-proxy # 必备软连接
[root@SQL-proxy local]# cd mysql-proxy
[root@SQL-proxy mysql-proxy]# mkdir etc # 创建 lua 脚本存放目录
[root@SQL-proxy mysql-proxy]# mkdir logs # 创建日志目录
把实现读写分离的 lua 脚本复制到 etc 目录下
[root@SQL-proxy mysql-proxy]# cp share/doc/mysql-proxy/rw-splitting.lua etc/
[root@SQL-proxy mysql-proxy]# cp share/doc/mysql-proxy/admin-sql.lua etc/
创建启动参数文件,启动服务时命令行就不用老长老长的。
[root@SQL-proxy ~]# vim /etc/mysql-proxy.cnf
[mysql-proxy] admin-username=proxy # 连接主从mysql共有的用户 admin-password=123 # 连接用户的密码 proxy-address=192.168.0.86:3306 # mysql-proxy监听本地工作ip和端口,不加端口默认是4040,为了方便管理这里用3306 proxy-backend-addresses=192.168.0.87:3306 # 指定后端主库 proxy-read-only-backend-addresses=192.168.0.90:3306 # 指定后端只读从库 proxy-lua-script=/usr/local/mysql-proxy/etc/rw-splitting.lua # 指定实现读写分离的lua脚本 admin-lua-script=/usr/local/mysql-proxy/etc/admin-sql.lua # 指定管理脚本 pid-file=/var/run/mysql-proxy.pid log-file=/usr/local/mysql-proxy/logs/mysql-proxy.log # 日志位置 log-level=info # 定义log日志级别,由高到低分别有(error|warning|info|message|debug) daemon=true # 以守护进程方式运行 keepalive=true # work进程崩溃时,尝试重启
启动服务
[root@SQL-proxy ~]# /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/etc/mysql-proxy.cnf
2017-04-24 16:40:19: (critical) mysql-proxy-cli.c:326: loading config from '/etc/mysql-proxy.cnf' failed: permissions of /etc/mysql-proxy.cnf aren't secure (0660 or stricter required)
2017-04-24 16:40:19: (message) Initiating shutdown, requested from mysql-proxy-cli.c:328
2017-04-24 16:40:19: (message) shutting down normally, exit code is: 1
!!看到无法启动,文件权限要改,因为文件里面有账号密码。
[root@SQL-proxy ~]# chmod 660 /etc/mysql-proxy.cnf # 改权限
[root@SQL-proxy ~]# ll /etc/mysql-proxy.cnf
-rw-rw---- 1 root root 432 Apr 24 16:31 /etc/mysql-proxy.cnf
[root@SQL-proxy ~]# /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/etc/mysql-proxy.cnf # 重新启动
[root@SQL-proxy ~]# netstat -lntup # 查看服务
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.0.86:3306 0.0.0.0:* LISTEN 3086/mysql-proxy
老是命令行敲一长串命令肯定不科学了,直接上服务管理脚本。
[root@SQL-proxy ~]# vim /etc/init.d/mysql-proxy #!/bin/bash # # mysql-proxy This script starts and stops the mysql-proxy daemon # # chkconfig: - 78 30 # processname: mysql-proxy # description: mysql-proxy is a proxy daemon for mysql# Source function library. . /etc/rc.d/init.d/functionsprog="/usr/local/mysql-proxy/bin/mysql-proxy"# Source networking configuration. if [ -f /etc/sysconfig/network ]; then. /etc/sysconfig/network fi# Check that networking is up. [ ${NETWORKING} = "no" ] && exit 0DEFAULT_FILE=/etc/mysql-proxy.cnf PROXY_PID=/var/run/mysql-proxy.pidRETVAL=0start() {echo -n $"Starting MySQL-proxy... : "daemon $prog --defaults-file=$DEFAULT_FILERETVAL=$?echoif [ $RETVAL -eq 0 ]; thentouch /var/lock/subsys/mysql-proxy.lockfi }stop() {echo -n $"Stopping MySQL-proxy... : "killproc -p $PROXY_PID -d 3 $progRETVAL=$?echoif [ $RETVAL -eq 0 ]; thenrm -f /var/lock/subsys/mysql-proxy.lockrm -f $PROXY_PIDfi } # See how we were called. case "$1" instart)start;;stop)stop;;restart)stopstart;;condrestart|try-restart)if status -p $PROXY_PIDFILE $prog >&/dev/null; thenstopstartfi;;status)status -p $PROXY_PID $prog;;*)echo "Usage: $0 {start|stop|restart|reload|status|condrestart|try-restart}"RETVAL=1;; esacexit $RETVAL
[root@SQL-proxy ~]# chmod +x /etc/init.d/mysql-proxy # 给执行权限
[root@SQL-proxy ~]# chkconfig mysql-proxy on # 可以加入开机启动
测试一下脚本:
[root@SQL-proxy ~]# /etc/init.d/mysql-proxy status mysql-proxy (pid 3086) is running... [root@SQL-proxy ~]# [root@SQL-proxy ~]# /etc/init.d/mysql-proxy stop Stopping MySQL-proxy... : [ OK ] [root@SQL-proxy ~]# [root@SQL-proxy ~]# /etc/init.d/mysql-proxy status mysql-proxy is stopped [root@SQL-proxy ~]# netstat -lntup Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1079/sshd tcp 0 0 :::22 :::* LISTEN 1079/sshd [root@SQL-proxy ~]# /etc/init.d/mysql-proxy start Starting MySQL-proxy... : [ OK ] [root@SQL-proxy ~]# /etc/init.d/mysql-proxy restart Stopping MySQL-proxy... : [ OK ] Starting MySQL-proxy... : [ OK ] [root@SQL-proxy ~]# [root@SQL-proxy ~]# netstat -lntup Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 192.168.0.86:3306 0.0.0.0:* LISTEN 3143/mysql-proxy
以上MySQL-proxy服务器搭建完成,但是用于连接后端数据库的用户:proxy还需要在数据库端创建
数据库Master端:创建proxy用户,给增删改查权限
[root@SQL-M ~]# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.5.55-log MySQL Community Server (GPL)Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.Master> Master> grant insert,delete,update,select on *.* to proxy@'192.168.0.86' identified by '123'; Query OK, 0 rows affected (0.00 sec)Master> select user,host from mysql.user; +-------+--------------+ | user | host | +-------+--------------+ | root | 127.0.0.1 | | rep | 192.168.0.% | | proxy | 192.168.0.86 | | root | localhost | +-------+--------------+ 4 rows in set (0.00 sec)Master> show grants for proxy@'192.168.0.86'; +------------------------------------------------------------------------------------------------------------------------------------------+ | Grants for proxy@192.168.0.86 | +------------------------------------------------------------------------------------------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'proxy'@'192.168.0.86' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' | +------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
Slave端:此时已经与主库一致拥有了proxy用户,但是从库只能读(select),所以要对proxy回收权限。
Slave> show grants for proxy@'192.168.0.86'; +------------------------------------------------------------------------------------------------------------------------------------------+ | Grants for proxy@192.168.0.86 | +------------------------------------------------------------------------------------------------------------------------------------------+ | GRANT SELECT, INSERT, UPDATE, DELETE ON *.* TO 'proxy'@'192.168.0.86' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' | +------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)Slave> revoke insert,update,delete on *.* from proxy@'192.168.0.86'; # 只留查询权限 Query OK, 0 rows affected (0.00 sec)Slave> show grants for proxy@'192.168.0.86'; +------------------------------------------------------------------------------------------------------------------+ | Grants for proxy@192.168.0.86 | +------------------------------------------------------------------------------------------------------------------+ | GRANT SELECT ON *.* TO 'proxy'@'192.168.0.86' IDENTIFIED BY PASSWORD '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257' | +------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
测试读写分离
为了方便测试,修改 rw-splitting.lua 脚本里触发读写分离参数
[root@SQL-proxy ~]# vim /usr/local/mysql-proxy/etc/rw-splitting.lua -- connection pool if not proxy.global.config.rwsplit thenproxy.global.config.rwsplit = {min_idle_connections = 1, # 默认超过4个连接数时,才开始读写分离,改为1max_idle_connections = 8, # 默认最大连接数8,不动它is_debug = false} end[root@SQL-proxy ~]# /etc/init.d/mysql-proxy restart # 重启一下 Stopping MySQL-proxy... : [ OK ] Starting MySQL-proxy... : [ OK ]
数据库Master端
Master> create database proxy; # 建个库 Query OK, 1 row affected (0.00 sec)Master> create table master(id int(2),name char(10)); # 停掉从库 IO线程后再建个表 Query OK, 0 rows affected (0.18 sec)Master> desc master; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(2) | YES | | NULL | | | name | char(10) | YES | | NULL | | +-------+----------+------+-----+---------+-------+ 2 rows in set (0.00 sec)
Slave端
Slave> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | proxy | # 新建的库已经有了 | school | | test | +--------------------+ 6 rows in set (0.00 sec)Slave> stop slave io_thread; # 停掉 IO 线程 Query OK, 0 rows affected (0.00 sec)Slave> show slave status\G *************************** 1. row ***************************Slave_IO_State: Master_Host: 192.168.0.88Master_User: repMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000019Read_Master_Log_Pos: 351Relay_Log_File: relay-bin.000011Relay_Log_Pos: 497Relay_Master_Log_File: mysql-bin.000019Slave_IO_Running: NoSlave_SQL_Running: YesSlave> use proxy; Database changedSlave> create table slave(id int(2),name char(10)); # 建个表 Query OK, 0 rows affected (0.00 sec)Slave> desc slave; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(2) | YES | | NULL | | | name | char(10) | YES | | NULL | | +-------+----------+------+-----+---------+-------+ 2 rows in set (0.00 sec)Slave> insert into slave values(90,'slave'); # 插入一条数据 Query OK, 1 row affected (0.00 sec)Slave> select * from slave; +------+-------+ | id | name | +------+-------+ | 90 | slave | +------+-------+ 1 row in set (0.00 sec)
模拟远程连接MySQL-proxy服务器进行读写操作
[root@SQL-proxy ~]# mysql -h192.168.0.86 -uproxy -P3306 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 12 Server version: 5.5.55-log MySQL Community Server (GPL)Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> mysql> use proxy; Database changed mysql> mysql> show tables; # show 出来的只有master这个表 +-----------------+ | Tables_in_proxy | +-----------------+ | master | +-----------------+ 1 row in set (0.01 sec)mysql> desc master; +-------+----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+-------+ | id | int(2) | YES | | NULL | | | name | char(10) | YES | | NULL | | +-------+----------+------+-----+---------+-------+ 2 rows in set (0.00 sec)mysql> insert into master values(88,'master'); # 往master表里插入数据 Query OK, 1 row affected (0.00 sec) <<--- 写入是 OK 的mysql> select * from master; ERROR 1146 (42S02): Table 'proxy.master' doesn't exist # 明显查不到的,因为去找从库了,从库上没有这表。mysql> show tables; # 我们show时只能看到 master 表,好像show只能找主库。 +-----------------+ | Tables_in_proxy | +-----------------+ | master | +-----------------+ 1 row in set (0.00 sec)mysql> select * from slave; # 我们直接查 slave 表 +------+-------+ | id | name | +------+-------+ | 90 | slave | <<--- 查到了,读操作成功 +------+-------+ 1 row in set (0.00 sec)mysql>
恢复 slave IO 线程
Slave> start slave io_thread; Query OK, 0 rows affected (0.00 sec)Slave> show slave status\G *************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.0.88Master_User: repMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000019Read_Master_Log_Pos: 1566Relay_Log_File: relay-bin.000012Relay_Log_Pos: 1468Relay_Master_Log_File: mysql-bin.000019Slave_IO_Running: YesSlave_SQL_Running: Yes
再次模拟远程连接MySQL-proxy服务器查 master 表
[root@SQL-proxy ~]# mysql -h192.168.0.86 -uproxy -P3306 -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 12 Server version: 5.5.55-log MySQL Community Server (GPL)Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> mysql> use proxy; Database changed mysql> mysql> select * from master; +------+--------+ | id | name | +------+--------+ | 88 | master | <<----由于从库恢复后开始复制主库数据,所以可以查到了。 +------+--------+ 1 row in set (0.00 sec)
以上MySQL-proxy读写分离完成。
存在的问题:
当模拟前端连接MySQL-proxy服务器并进行数据库操作时,MySQL-proxy服务器端屏幕有信息输出,不知道为什么?
信息如下:
[root@SQL-proxy ~]# server default db: proxy
client default db: school
syncronizing
server default db: proxy
client default db: school
syncronizing
server default db: school
client default db: proxy
syncronizing
转载于:https://blog.51cto.com/yuyicong/1919799
MySQL5.5读写分离之mysql-proxy相关推荐
- mysql读写分离(MySQL Proxy 安装和使用)
一.必备软件: 1.LUA 可以去LUA的官方下载:www.lua.org 2.MySQL Proxy 这里有好多二进制版本. http://mysql.cdpa.nsysu.ed ...
- DBA(四):数据读写分离,MySQL多实例操作
数据读写分离 MySQL读写分离 概念:把客户端查询数据的请求和存储数据的SQL命令,分别给不同的数据库服务器处理 读写分离的原理 由MySQL代理面向客户端提供服务 收到SQL的写请求时,交给mas ...
- mysql5.7 读写分离_mysql5.7的主从复制+读写分离
Mysql主从复制与读写分离 目录: 1.mysql主从复制工作原理 2.mysql读写分离原理,使用Amoeba中间代理层实现读写分离 3.在vmware中实现mysql主从复制+读写分离 一.My ...
- ShardingSphere(六) 读写分离之mysql 主从同步配置
概述:本周介绍mysql的主从同步配置,为下一步的Sharding 读写分离提供操作环境.mysql 主从同步主要通过主库开启binlog文件功能,然后从库通过监听binlog中内容进行数据在从库的实 ...
- Mycat原理详解,Mycat 实现 MySQL 的读写分离(Mysql主从复制)
文章目录 1 Mycat 介绍 2 Mycat 安装 2.1下载安装JDK 2.2下载安装mycat 2.3启动和连接 3 Mycat 主要配置文件说明 4 利用 Mycat 实现 MySQL 的读写 ...
- 项目性能优化(MySQL读写分离、MySQL主从同步、Django实现MySQL读写分离)
当项目中数据库表越来越多,数据量也逐渐增多时,需要做数据库的安全和性能的优化.对于数据库的优化,可以选择使用MySQL读写分离实现. 1.MySQL主从同步 1.主从同步机制 1.1.主从同步介绍和优 ...
- mysql读写分离6_6\MySQL 主从同步 、 MySQL 读写分离 、 MySQL 性能调优
day06 一.mysql主从同步 二.数据读写分离 三.MySQL优化 ++++++++++++++++++++++++++++++++ 一.mysql主从同步 1.1 主从同步介绍?从库服务器自动 ...
- 使用Spring实现读写分离(MySQL实现主从复制)
我们一般应用对数据库而言都是"读多写少",也就说对数据库读取数据的压力比较大,有一个思路就是说采用数据库集群的方案, 其中一个是主库,负责写入数据,我们称之为:写库: 其它都是从库 ...
- Mysql5.7读写分离
主库ip:192.168.31.106 从库ip:192.168.31.162 设置允许远程连接:/etc/mysql/mysql.conf.d 注释bind-address = 127.0.0. ...
最新文章
- ci框架 mysql_CodeIgniter (CI)框架中的数据库查询汇总
- xgboost不能解决哪些问题?为什么?进而说明树模型有哪些缺陷?那种模型能够树模型的这种缺陷?
- SQLite学习手册(命令行工具)
- intellij2018使用2019的主题
- 数据仓库项目分析_数据分析项目:仓库库存
- PyCharm光标变粗的解决办法
- 正确使用PresentModalViewController
- CSS——id 和 class 选择器
- 程序员必知的mysql插件_程序员必知的技术官网系列--mysql篇
- Flex4.5中检测网络连接类型
- Spring mvc Interceptor 解决Session超时配置流程
- 静态反编译软件:IDA Pro for Mac
- 自动驾驶汽车技术介绍【硬件+软件】
- matlab怎么创建数组对象,数组 – matlab初始化对象数组
- 最新自用pdf免费在线去水印全套方案
- PCL5打印机命令语言功能参考
- 干货!2018年你值得一看的网页设计作品集赏析
- 微信公众号与微信小程序相辅相成
- 云澈找到了鸿蒙生死印了吗,逆天邪神:洛孤邪、千叶影儿再出手,云澈遭放逐外混沌生死未卜!...
- mysql安装2503,无法安装msi格式软件提示错误代码2502、2503怎么办?
热门文章
- 克隆虚拟机启动网卡提示错误 Device eth0 does not seem to be present, delaying initialization...
- WPF 窗体边框处理
- HTML/CSS/JavaScript学习总结(转)
- 使用Java高速实现进度条
- 推荐一个ASP.NET的资源网站
- Linux有趣指令(一)
- 使用arm混合汇编计算两个64位的和_混合使用C、C++和汇编语之: C、C++ 和 ARM 汇编语言之间的调用...
- java删除一级域名下cookie_java操作cookie示例(删除cookie)
- 面试题 为什么用线程池?解释下线程池参数
- mysql 查询时间转换_数据库查询时日期的转换