mysql-proxy代理加mysql主从实现读写分离
一:实验目标
MySQL Proxy(代理) 服务概述
MySQL Proxy 实现读写分离
MySQL Proxy+mysql主从实现读写分离
二:实验环境:
关闭防火墙
mysql-proxy服务端: xuegod62.cn IP:192.168.1.62
mysql服务器(主,负责写)服务端:xuegod63.cn IP:192.168.1.63
mysql服务器(从,负责读)客户端:xuegod64.cn IP:192.168.1.64
端口: mysql-proxy 默认端口:4040
三:实验概述
主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy)来提升数据库的并发负载能力 这样的方案来进行部署实施的。
工作原理:
1:MySQL Proxy概述
MySQL Proxy是一个处于你的client端和MySQL server端之间的简单程序,它可以监测、分析或改变它们的通信。它使用灵活,没有限制,常见的用途包括:负载平衡,故障、查询分析,查询过滤和修改等等。
MySQL Proxy就是这么一个中间层代理,简单的说,MySQL Proxy就是一个连接池,负责将前台应用的连接请求转发给后台的数据库,并且通过使用lua脚本,可以实现复杂的连接控制和过滤,从而实现读写分离和负载平衡。对于应用来说,MySQL Proxy是完全透明的,应用则只需要连接到MySQL Proxy的监听端口即可。当然,这样proxy机器可能成为单点失效,但完全可以使用多个proxy机器做为冗余,在应用服务器的连接池配置中配置到多个proxy的连接参数即可。
MySQL Proxy更强大的一项功能是实现“读写分离”,基本原理是让主数据库处理事务性查询,让从库处理SELECT查询。数据库复制被用来把事务性查询导致的变更同步到集群中的从库。
Lua概述:
Lua 是一个小巧的脚本语言。Lua的速度是最快的。Lua由标准C编写而成,几乎在所有操作系统和平台上都可以编译,运行。Lua并没有提供强大的库,这是由它的定位决定的。所以Lua不适合作为开发独立应用程序的语言。
2:读写分离的好处
1)增加冗余
2)增加了机器的处理能力
3)对于读操作为主的应用,使用读写分离是最好的场景,因为可以确保写的服务器压力更小,而读又可以接受点时间上的延迟。
3:读写分离提高性能之原因
1)物理服务器增加,负荷增加
2)主从只负责各自的写和读,极大程度的缓解X锁和S锁争用
3)从库可配置myisam引擎,提升查询性能以及节约系统开销
4)从库同步主库的数据和主库直接写还是有区别的,通过主库发送来的binlog恢复数据,但是,最重要区别在于主库向从库发送binlog是异步的,从库恢复数据也是异步的
5)读写分离适用与读远大于写的场景,如果只有一台服务器,当select很多时,update和delete会被这些select访问中的数据堵塞,等待select结束,并发性能不高。 对于写和读比例相近的应用,应该部署双主相互复制
6)可以在从库启动是增加一些参数来提高其读的性能,例如--skip-innodb、--skip-bdb、--low-priority-updates以及--delay-key-write=ALL。当然这些设置也是需要根据具体业务需求来定得,不一定能用上
7)分摊读取。假如我们有1主3从,不考虑上述1中提到的从库单方面设置,假设现在1 分钟内有10条写入,150条读取。那么,1主3从相当于共计40条写入,而读取总数没变,因此平均下来每台服务器承担了10条写入和50条读取(主库不 承担读取操作)。因此,虽然写入没变,但是读取大大分摊了,提高了系统性能。另外,当读取被分摊后,又间接提高了写入的性能。所以,总体性能提高了,说白 了就是拿机器和带宽换性能。MySQL官方文档中有相关演算公式:官方文档 见6.9FAQ之“MySQL复制能够何时和多大程度提高系统性能”
8)MySQL复制另外一大功能是增加冗余,提高可用性,当一台数据库服务器宕机后能通过调整另外一台从库来以最快的速度恢复服务,因此不能光看性能,也就是说1主1从也是可以的。
============================================================
四:实验代码
1:MySQL-proxy实现读写分离
第一块:安装mysql-proxy
1:安装mysql-proxy ---安装前需要系统支持LUA语言环境。
[root@xuegod62 ~]# rpm -ivh /mnt/Packages/lua-5.1.4-4.1.el6.x86_64.rpm
2:在xuegod62上安装mysql-proxy: 上传mysql-proxy
[root@xuegod62~ ]# tar zxvf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
[root@xuegod62 ~]# mv mysql-proxy-0.8.5-linux-el6-x86-64bit /usr/local/mysql-proxy
3:修改系统命令环境变量:
[root@xuegod62 ~]#export PATH=$PATH:/usr/local/mysql-proxy/bin/ #或者
[root@xuegod62 ~]# vim /etc/bashrc #在最后添加以下内容 :
PATH=$PATH:/usr/local/mysql-proxy/bin/
[root@xuegod62 ~]#source /etc/bashrc
4:mysql-proxy 脚本配置文件位置:
[root@xuegod62 ~]# ls /usr/local/mysql-proxy/share/doc/mysql-proxy/* #下有各种各样的脚本
rw-splitting.lua #这个就是支持读写分离的脚本
5:修改配置文件 实现:读写分离
[root@xuegod62 ~]# vim /usr/local/mysql-proxy/share/doc/mysql-proxy
/rw-splitting.lua
改:
40 min_idle_connections = 2,
41 max_idle_connections = 8,
为:
min_idle_connections = 1,
max_idle_connections = 1,
#现改为最小1个最大1个。为了验证试验效果将他改成1 .就是当有一个链接的时候,就实现读写分离的功能。为了清晰的看到读写分离的效果,需要暂时关闭MySQL主从复制功能。
第二块:搭建mysql服务器
1:xuegod63上创建数据库和表,用于查看读写分离:
[root@xuegod63 ~]#yum install mysql-server -y
[root@xuegod63 ~]# service mysqld start
[root@xuegod63 ~]# mysql
mysql> create database db;
mysql> use db;
mysql> create table test(id int);
mysql> insert into test values(6363);
mysql> grant all on db.* to user1@'%' identified by '123456' ;
#给普通用户 user1 登录访问数据库权限及密码
注:% 表示任意远程客户端 ,不包括localhost和本地IP地址
2:xuegod64上创建数据库和表,用于查看读写分离:
[root@xuegod64 ~]# yum install mysql-server -y
[root@xuegod64 ~]# service mysqld start
[root@xuegod64 ~]# mysql
mysql> create database db;
mysql> use db;
mysql> create table test(id int);
mysql> insert into test values(6464);
mysql> grant all on db.* to user1@'%' identified by '123456' ;
3:客户端测试普通用户登录mysql主从数据库
[root@xuegod61 ~]# mysql -u user1 -p123456 -h 192.168.1.63
mysql> use db
[root@xuegod61 ~]# mysql -u user1 -p123456 -h 192.168.1.64
mysql> use db
4:启动服务mysql-proxy服务
[root@xuegod62 ~]# ls /usr/local/mysql-proxy/bin/
mysql-binlog-dump mysql-myisam-dump mysql-proxy
[root@xuegod62 ~]# mysql-proxy --proxy-read-only-backend-addresses=192.168.1.64:3306 --proxy-backend-addresses=192.168.1.63:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua &
(1)参数说明:
--proxy-read-only-backend-addresses=192.168.1.64:3306 # 定义后端只读服务器
--proxy-backend-addresses=192.168.1.63:3306 #定义后端只写服务器地址
--proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua & #指定lua脚本,在这里,使用的是rw-splitting脚本,用于读写分离
当有多个只读服务器时,可以写多个以下参数:
--proxy-read-only-backend-addresses=192.168.1.66:3306 # 定义后端只读服务器
--proxy-read-only-backend-addresses=192.168.1.65:3306 # 定义后端只读服务器
完整的参数可以运行以下命令查看:
[root@xuegod62 ~]# mysql-proxy --help-all
-?, --help Show help options
--help-all Show all help options
(2)查看proxy是否启动:
[root@xuegod62 ~]# netstat -antup | grep proxy
tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 2991/mysql-proxy
(3)关闭mysql-proxy服务
[root@xuegod63 ~]# pkill proxy
第三块:测试mysql-proxy读写功能
1:客户端测试写功能:
[root@xuegod61 ~]# mysql -u user1 -p123456 -P4040 -h 192.168.1.6:62
mysql> use db;
#select * from test;的时候,看到了6363,表示mysql-proxy将查看请求连接到xuegod63。mysql-proxy指定了xuegod63只具有写的功能,所以当你插入一天新的数据的时候,你就会查看到你所插入的内容。注:出现的第一次数据都是只写的数据,不会是read-only的。
2:客户端测试读功能:再打开一个客户端测试一下读。
[root@xuegod61 ~]# mysql -u user1 -p123456 -P4040 -h 192.168.1.62
mysql> use db;
#这里elect * from test;的时候,看到了44,表示mysql-proxy将查看请求连接到xuegod64。
mysql> insert into test values(6363);
mysql> select * from test; #现在是读的动作,看不到63数据的。
#mysql-proxy指定了xuegod64只具有读的功能,所以当你插入一个新的数据的时候,你再次查看的时候还是6464,说明你的数据是写不进去的。
3:客户端登录查看:
[root@xuegod61 ~]# mysql –u user1 -p123456 -P4040 -h 192.168.1.62
mysql> show processlist;
列名称 |
作用 |
id |
服务的一个标识 |
user |
显示当前用户,如果不是 root ,这个命令就只显示你权限范围内的 sql 语 句。 |
host |
显示这个语句是从哪个 ip 的哪 个端口上发出的。可以用来追踪出问题语句的用户。 |
db |
显示这个进程目前连接的是哪个数据库 。 |
command |
显示当前连接的执行的命令,一般就是休眠( sleep ),查询( query ),连接( connect )。 |
time |
显示这个进程目前连接的是哪个数据库 。 |
state |
显示使用当前连接的 sql 语句的状态,很重要的列, state 只是语句执行中的某一个状态,一个 sql 语句,以查询为例,可能需要经过 copying to tmp table ,Sorting result , Sending data 等状态才可以完成。 |
info |
显示这个 sql 语句,因为长度有限,所以长的 sql 语句就显示不全,但是一个判断问题语句的重要依据。 |
2:mysql+proxy+mysql主从实现读写分离
1:xuegod63作为 mysql主:
[root@xuegod63 ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
log-bin=mysqllog
server-id=1
binlog-do-db=db
[root@xuegod63~]# mysql
mysql> grant all on *.* to user2@'%' identified by '123456'; #创建一个主从同步用户
mysql>use db;
mysql>drop table test; #为了保持数据完整性,删除删一个表。
[root@xuegod63 ~]# service mysqld restart
2:xuegod64 mysql 从配置
[root@xuegod64 ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
server-id=2
master-host=192.168.1.63
master-user=user2
master-password=123456
[root@xuegod64~]# mysql
mysql> grant all on *.* to user2@'%' identified by '123456';# 创建一个主从同步用户
mysql>use db;
mysql>drop table test; #为了保持数据完整性,删除删一个表。
[root@xuegod64 ~]# service mysqld restart
3:测试主从同步:
1)xuegod63服务器测试同步数据:
[root@xuegod63 ~]# mysql
mysql> use db;
mysql> create table test (id int );
mysql> insert into test values(63);
2)登录xuegod64查看63同步过来的数据:
[root@xuegod64 ~]# mysql
mysql> use db;
4:客户端xuegod61:测试使用mysql-proxy 能否读到同样的数据。
分析:在客户端上利用普通MySQL用户从mysql-proxy上登录,然后插入数据,看看MySQL的主从上是否显示。
[root@xuegod61~]# mysql -u user2 -p123456 -P4040 -h192.168.1.62
mysql>use db;
mysql> select * from test;#可以查看到test中的63记录,说明mysql+proxy+主从读写分离成功。
mysql> insert into test values(64);
[root@xuegod63 ~]# mysql
mysql> use db;
#在xuegod62上登录的mysql数据库中,写的数据也得到了同步。
思考:当slave宕机后,mysql-proxy是如何读取的?
[root@xuegod64 ~]# service mysqld stop
Stopping mysqld: [ OK ]
xuegod62上测试:读写:
[root@xuegod62 ~]# mysql -uuser2 -p123456 -P4040 -h192.168.1.62
mysql> use db;
mysql> insert into test values(6464);
xuegod63上查看xuegod64关闭后的客户端连接:确认读和写都是访问xuegod63
[root@xuegod63 ~]# mysql
mysql> use db;
mysql> show processlist;
+----+-------+--------------------+------+-------------+------+-------------------------------------
总结:当停止掉slave数据库,proxy的查询就会转移到master上,当把slave启动后,proxy依然在读master,当有新的链接进来的时候才会重新去读取slave的数据。有时可能需要重启下mysql-proxy