Mysql读写分离配置

1、what 读写分离 
读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。

2、why 那么为什么要读写分离呢? 
因为数据库的“写”(写10000条数据到oracle可能要3分钟)操作是比较耗时的。 
但是数据库的“读”(从oracle读10000条数据可能只要5秒钟)。 
所以读写分离,解决的是,数据库的写入,影响了查询的效率。

3、when 什么时候要读写分离? 
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用,利用数据库 主从同步 。可以减少数据库压力,提高性能。当然,数据库也有其它优化方案。memcache 或是 表折分,或是搜索引擎。都是解决方法。

4、主从复制与读写分离

在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。有点类似于前面我们学习过的rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据、语句做备份。


5、 mysql读写分离原理

读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全。

6、前较为常见的Mysql读写分离分为以下两种:

1)基于程序代码内部实现

 在代码中根据select 、insert进行路由分类,这类方法也是目前生产环境下应用最广泛的。优点是性能较好,因为程序在代码中实现,不需要增加额外的硬件开支,缺点是需要开发人员来实现,运维人员无从下手。

2) 基于中间代理层实现

    代理一般介于应用服务器和数据库服务器之间,代理数据库服务器接收到应用服务器的请求后根据判断后转发到,后端数据库,有以下代表性的程序。

(1)mysql_proxy。mysql_proxy是Mysql的一个开源项目,通过其自带的lua脚本进行sql判断。

(2)Atlas。是由 Qihoo 360, Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。

(3)Amoeba。由阿里巴巴集团在职员工陈思儒使用序java语言进行开发,阿里巴巴集团将其用户生产环境下,但是他并不支持事物以及存储过程。

经过上述简单的比较,不是所有的应用都能够在基于程序代码中实现读写分离,像一些大型的java应用,如果在程序代码中实现读写分离对代码的改动就较大,所以,像这种应用一般会考虑使用代理层来实现,那么今天就使用Amoeba为例,完成主从复制和读写分离。

MySQLProxy介绍  
下面使用MySQL官方提供的数据库代理层产品MySQLProxy搭建读写分离。 

MySQLProxy实际上是在客户端请求与MySQLServer之间建立了一个连接池。所有客户端请求都是发向MySQLProxy,然后经由MySQLProxy进行相应的分析,判断出是读操作还是写操作,分发至对应的MySQLServer上。对于多节点Slave集群,也可以起做到负载均衡的效果。


# 准备:

主: 192.168.137.128
从:192.168.137.129
proxy:192.168.137.130
两台数据库配置好主从复制

# 在官网下载对应版本(我这里为ubuntu)   https://downloads.mysql.com/archives/proxy/

mysql-proxy-0.8.5-linux-debian6.0-x86-64bit.tar.gz

# MySQL-Proxy的读写分离主要是通过rw-splitting.lua脚本实现的,因此需要安装lua。

apt-get install lua5.1

# http://www.lua.org/download.html  源码下载地址(可选源码安装)

# 上传到服务器并解压

tar xf mysql-proxy-0.8.5-linux-debian6.0-x86-64bit.tar.gz
mv mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit /usr/local/mysql-proxy

1、配置mysql-proxy主配置文件

vim /etc/mysql-proxy.cnf
[mysql-proxy]
admin-username = proxy   #主从mysql共有的用户
admin-password = 123456  #用户的密码
daemon = true            #以守护进程方式运行
keepalive = true         #mysql-proxy崩溃时,尝试重启
proxy-backend-addresses = 192.168.137.128               #指定写入数据数据库ip(主从: master)
proxy-read-only-backend-addresses = 192.168.137.131     #指定读取数据数据库ip(主从: slave)
proxy-lua-script = /usr/local/mysql-proxy/lib/mysql-proxy/lua/rw-splitting.lua   #指定读写分离配置文件位置
admin-lua-script = /usr/local/mysql-proxy/lib/mysql-proxy/lua/admin-sql.lua      #指定管理脚本
log-file = /var/log/proxy-mysql/cn.log                  #日志位置
log-level = debug
# 保存退出
chmod 660 /etc/mysql-porxy.cnf

2、修改读写分离配置文件

vim /usr/local/mysql-proxy/lib/mysql-proxy/lua/rw-splitting.lua
if not proxy.global.config.rwsplit then
 proxy.global.config.rwsplit = {
  min_idle_connections = 1, #默认超过4个连接数时,才开始读写分离,改为1
  max_idle_connections = 1, #默认8,改为1
  is_debug = false
 }
end

3、配置mysql-proxy启动管理脚本

#!/bin/bash
# mysql-proxy start/stop 

case $1 in
    start)
        /var/www/program/mysql-proxy/bin/mysql-proxy --defaults-file=/etc/mysql-proxy.cnf &
        if [ $? -eq 0 ];then
            echo "Mysql-proxy start success"
        fi
    ;;
    stop)
        killall -9 mysql-proxy &>>/var/log/syslog
    ;;
    restart)
        if $0 stop;then
            $0 start &>>/var/log/syslog
        else
            echo  "Restart failed!"
	    exit 1
	fi
    ;;
    status)
        ps -C mysql-proxy --no-header
    ;;
    *)
        echo "Usage: $0 {start|stop|restart|status}"
        exit 0
    ;;        
esac

exit 0
# 保存退出
chmod +x /etc/init.d/mysql-proxy

4、启动mysql-proxy

/etc/init.d/mysql-proxy start
netstat -tupln | grep 4040 
5、测试读写分离效果
# 创建用于读写分离的数据库连接用户

# 登陆主数据库服务器192.168.137.128,通过命令行登录管理MySQL服务器

mysql -uroot -p'new-password'
mysql> GRANT ALL ON *.* TO 'proxy'@'192.168.10.130' IDENTIFIED BY 'password';

由于我们配置了主从复制功能,因此从数据库服务器192.168.137.129上已经同步了此操作

# 为了清晰的看到读写分离的效果,需要暂时关闭MySQL主从复制功能

# 登陆从数据库服务器192.168.137.129,通过命令行登录管理MySQL服务器

mysql -uroot -p'new-password'
# 关闭Slave同步进程
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

# 客户端连接MySQL-Proxy并插入数据

mysql -uproxy -p'password' -P4040 -h192.168.10.130
# 登陆成功后,在test数据的test_tb表中插入两条记录
mysql> use test;
Database changed
mysql> insert into test_tb values (007,’first’);
Query Ok, 1 row affected (0.00 sec)
mysql> insert into test_tb values (110,’second’);
Query Ok, 1 row affected (0.00 sec)

# 查询记录

mysql> select * from test_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
1 rows in set (0.00 sec)
=============================
# 通过读操作并没有看到新记录

mysql> quit
退出MySQL-Proxy
# 下面,分别登陆到主从数据库服务器,对比记录信息
# 首先,检查主数据库服务器
mysql> select * from test_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
| 007 | first |
+------+------+
| 110 | second |
+------+------+
3 rows in set (0.00 sec)
=============================
两条新记录都已经存在

# 然后,检查从数据库服务器

mysql> select * from test_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
1 rows in set (0.00 sec)
=============================
没有新记录存在
由此验证,我们已经实现了MySQL读写分离,目前所有的写操作都全部在Master主服务器上,用来避免数据的不同步;
另外,所有的读操作都分摊给了其它各个Slave从服务器上,用来分担数据库压力。




猜你喜欢

转载自blog.csdn.net/weixin_39845407/article/details/81014356