Mysql的读写分离

mysql读写分离

什么是读写分离

在数据库集群架构中,让主库负责处理事务性查询,而从库只负责处理select查询,让两者分工明确达到提高数据库整体读写性能。当然,主数据库另外一个功能就是负责将事务性查询导致的数据变更同步到从库中,也就是写操作。即主从复制和读写分离是离不开的。

原理

在这里插入图片描述

  • 应用:当服务器的业务压力过大时,如果对该服务器既读又写,会影响用户体验。所以我们采取读写分离的方式,对只读库(配置低一点),对读写库(配置高速存储:固态硬盘等。)
  • 读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全。
读写分离的好处
  • 分摊服务器压力,提高机器的系统处理效率
    读写分离适用于读远比写的场景,如果有一台服务器,当select很多时,update和delete会被这些select访问中的数据堵塞,等待select结束,并发性能并不高,而主从只负责各自的写和读,极大程度的缓解X锁和S锁争用;
  • 增加冗余,提高服务可用性,当一台数据库服务器宕机后可以调整另外一台从库以最快速度恢复服务。
实现方式
  • 目前较为常见的Mysql读写分离分为两种:
  • 基于程序代码内部实现
    在代码中根据select 、insert进行路由分类,这类方法也是目前生产环境下应用最广泛的。优点是性能较好,因为程序在代码中实现,不需要增加额外的硬件开支,缺点是需要开发人员来实现,运维人员无从下手。
  • 基于中间代理层实现
    代理一般介于应用服务器和数据库服务器之间,代理数据库服务器接收到应用服务器的请求后根据判断后转发到后端数据库,有以下代表性的程序。
    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应用,如果在程序代码中实现读写分离对代码的改动就较大,所以,像这种应用一般会考虑使用代理层来实现。

实验环境

主机(ip)功能
server1(172.25.24.1)读写主机
server2(172.25.24.2)只读主机
server3(172.25.24.3)proxy
真机(172.25.24.24)客户端

实验过程

server1和server2恢复gtid主从复制状态
  • 因为做了组复制,先关闭组复制,关闭服务,删除目录下的文件,再开启服务。
  • 以下步骤server1和server2相同。
[root@server1 mysql]# systemctl stop mysqld.service 
[root@server1 mysql]# rm -fr *
[root@server1 mysql]# ls
[root@server1 mysql]# systemctl start mysqld

获取密码:[root@server1 mysql]# cat /var/log/mysqld.log | grep password
安全初始化:[root@server1 mysql]# mysql_secure_installation 
  • server1,并修改配置文件,重启服务:
[root@server1 mysql]# mysql -uroot -p
mysql> CREATE USER 'repl'@'172.25.24.%' IDENTIFIED BY 'Wsp+123ld';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.25.24.%';
mysql> flush privileges;
mysql> show master status;

[root@server1 mysql]# vim /etc/my.cnf

 29 log-bin=mysql-bin
 30 server_id=1
 31 gtid_mode=ON
 32 enforce_gtid_consistency=ON

[root@server1 mysql]# systemctl restart mysqld
  • server2,并修改配置文件,重启服务:
mysql> change master to master_host='172.25.24.1',master_user='repl',master_password='Wsp+123ld',master_auto_position=1;
mysql> start slave;
mysql> show slave status\G;

[root@server2 mysql]# vim /etc/my.cnf
 29 server_id=2
 30 gtid_mode=ON
 31 enforce_gtid_consistency=ON
[root@server2 mysql]# systemctl restart mysqld
  • server1上建表插入数据检测,gtid主从复制有没有成功。
mysql> create database westos;
mysql> use westos;
Database changed
mysql> create table userlist(
    -> username varchar(10) not null,
    -> password varchar(10) not null);
mysql> desc userlist;
mysql> show master status\G;

在这里插入图片描述
在这里插入图片描述

server3
  • 如果mysqld服务是开启的状态,首先关闭mysqld,保证3306端口没有被占用。
  • 获取安装包:mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
    在这里插入图片描述
  • 解压到指定目录,并重命名:
[root@server3 ~]# tar zxf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local/
[root@server3 ~]# cd /usr/local/
[root@server3 local]# mv mysql-proxy-0.8.5-linux-el6-x86-64bit mysql-proxy

在这里插入图片描述

  • 新建日志目录,配置文件目录
[root@server3 local]# cd mysql-proxy/
[root@server3 mysql-proxy]# ls
bin  include  lib  libexec  licenses  share
[root@server3 mysql-proxy]# mkdir conf
[root@server3 mysql-proxy]# cd conf/
[root@server3 mysql-proxy]# mkdir logs
  • 根据–help查看帮助,写配置文件
[root@server3 mysql-proxy]# vim conf/mysql-proxy.conf

[mysql-proxy]
proxy-address=0.0.0.0:3306
proxy-backend-addresses=172.25.24.1:3306
proxy-read-only-backend-addresses=172.25.24.2:3306
proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
pid-file=/usr/local/mysql-proxy/logs/mysql-proxy.pid
log-file=/usr/local/mysql-proxy/logs/mysql-proxy.log
plugins=proxy
log-level=debug
keepalive=true
daemon=true
  • 修改lua源文件:
[root@server3 mysql-proxy]# cd /usr/local/mysql-proxy/share/doc/mysql-proxy/
[root@server3 mysql-proxy]# vim rw-splitting.lua

 37 -- connection pool
 38 if not proxy.global.config.rwsplit then
 39         proxy.global.config.rwsplit = {
 40                 min_idle_connections = 1,   #为了实验效果明显修改为1和2
 41                 max_idle_connections = 2,
 42 
 43                 is_debug = false
 44         }
 45 end

在这里插入图片描述

  • 开启服务:
[root@server3 conf]# /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conf/mysql-proxy.conf
  • 查看进程,日志,端口,目的是查看mysql-proxy服务有没有成功开启。
[root@server3 mysql-proxy]# cd logs/
[root@server3 logs]# ls
mysql-proxy.log  mysql-proxy.pid
[root@server3 logs]# cat mysql-proxy.log 

2019-07-28 12:50:15: (message) proxy listening on port 0.0.0.0:3306
2019-07-28 12:50:15: (message) added read/write backend: 172.25.24.1:3306
2019-07-28 12:50:15: (message) added read-only backend: 172.25.24.2:3306

[root@server3 logs]# netstat -antlupe | grep 3306
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      0          26473      2094/mysql-proxy   

在这里插入图片描述
在这里插入图片描述

  • server3安装lsof:[root@server3 logs]# yum install lsof -y
server1
  • 登陆之后,新建从真机登陆的用户
mysql> grant insert,update,select on *.* to zyw@'%' identified by 'Wsp+123ld';  #除了删除delete,数据只能多不能少
mysql> flush privileges;
mysql> select * from mysql.user;
测试读
  • 真机打开一个shell,登陆数据库。
[kiosk@foundation24 ~]$ mysql -h 172.25.24.3 -uzyw -pWsp+123ld
  • server3查看
[root@server3 logs]# lsof -i:3306
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2094 root   10u  IPv4  26473      0t0  TCP *:mysql (LISTEN)
mysql-pro 2094 root   11u  IPv4  26697      0t0  TCP server3:mysql->foundation24.ilt.example.com:38366 (ESTABLISHED)
mysql-pro 2094 root   12u  IPv4  26698      0t0  TCP server3:56648->server1:mysql (ESTABLISHED)

在这里插入图片描述

  • 真机再打开一个shell,登陆数据库。
[kiosk@foundation24 ~]$ mysql -h 172.25.24.3 -uzyw -pWsp+123ld
  • server3查看
[root@server3 logs]# lsof -i:3306
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2094 root   10u  IPv4  26473      0t0  TCP *:mysql (LISTEN)
mysql-pro 2094 root   11u  IPv4  26697      0t0  TCP server3:mysql->foundation24.ilt.example.com:38366 (ESTABLISHED)
mysql-pro 2094 root   12u  IPv4  26698      0t0  TCP server3:56648->server1:mysql (ESTABLISHED)
mysql-pro 2094 root   13u  IPv4  26952      0t0  TCP server3:mysql->foundation24.ilt.example.com:38368 (ESTABLISHED)
mysql-pro 2094 root   14u  IPv4  26953      0t0  TCP server3:56654->server1:mysql (ESTABLISHED)

在这里插入图片描述

  • 真机再打开一个shell,登陆数据库。
[kiosk@foundation24 ~]$ mysql -h 172.25.24.3 -uzyw -pWsp+123ld
  • server3查看。
[root@server3 logs]# lsof -i:3306
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 2094 root   10u  IPv4  26473      0t0  TCP *:mysql (LISTEN)
mysql-pro 2094 root   11u  IPv4  26697      0t0  TCP server3:mysql->foundation24.ilt.example.com:38366 (ESTABLISHED)
mysql-pro 2094 root   12u  IPv4  26698      0t0  TCP server3:56648->server1:mysql (ESTABLISHED)
mysql-pro 2094 root   13u  IPv4  26952      0t0  TCP server3:mysql->foundation24.ilt.example.com:38368 (ESTABLISHED)
mysql-pro 2094 root   14u  IPv4  26953      0t0  TCP server3:56654->server1:mysql (ESTABLISHED)
mysql-pro 2094 root   15u  IPv4  26977      0t0  TCP server3:mysql->foundation24.ilt.example.com:38370 (ESTABLISHED)
mysql-pro 2094 root   16u  IPv4  26978      0t0  TCP server3:46060->server2:mysql (ESTABLISHED)

在这里插入图片描述

  • 真机登陆,<=2个shell,都没有开启读写分离模式,我们打开第三个shell登陆时,才是从server2上读。
测试写
  • server2,停止gtid主从复制。
mysql> stop slave;
  • 真机写入数据:
MySQL [(none)]> insert into westos.userlist values('user2','111');

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 写成功,但真机和server2都查不到刚写入的数据,server1可以查看到。所以读写分离成功。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值