MySQL主从复制与读写分离

目录

前言

一、MySQL主从复制的理解

1、MySQL的复制类型

2、MySQL主从复制的工作流程

3、MySQL架构(一主多备) 

3.1 一主多备 

3.2 M-S-S 

 3.3 M-M/双主互备 (互为主从)

3.4 M-M-M 

4、MySQL主从复制延迟原因

5、MySQL主从复制延迟的优化

二、搭建MySQL主从复制

1、配置主从服务器时间同步

1.1 主服务器时间同步配置 

 1.2 从服务器时间同步配置

2、mysql配置文件配置 

2.1 主服务器配置

2.2 从服务器配置 

 3、验证

三、对于读写分离的三个问题

1、什么是读写分离?       

2、为什么要读写分离?

3、什么时候要读写分离?       

4、主从复制与读写分离       

5、mysql支持的复制类型

6、主从复制的的工作过程

7、MySQL读写分离原理

8、目前较为常见的MySQL读写分离

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

(2) 居于中间代理层实现     

四、总结

1、读写分离使用的是什么方式?

2、如何查看主从同步状态是否成功

3、如果I/O不是yes呢,你如何排查?

4、show slave status能看到哪些消息(比较重要)

5、主从复制慢(延迟)会有哪些可能?怎么解决?

6、若主从版本不一致


前言

  • 在企业应用中,成熟的业务通常数据量都比较大
  • 单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求
  • 配置多台主从数据库服务器以实现读写分离

 横向扩展:集群化,压力分摊

一、MySQL主从复制的理解

1、MySQL的复制类型

statement:基于语句的复制。在主服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高
row: 基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍
mixed:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制
数据一般放在二进制日志文件中

2、MySQL主从复制的工作流程

master 节点将数据的改变记录成二进制日志(bin log),当master上的数据发生改变时,则将其改变写入二进制日志中。
slave节点会在一定时间间隔内对master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求
同时master节点为每个I/O 线程启动一个dump线程,用于向其发送二进制事件,并保存值slave节点本地的中继日志(relay log)中,slave节点将启动sql线程从中继日志中读取二进制日志,在本地重放,即解析成sql语句逐一执行,使得其数据和master节点的保持一致,最后,I/O线程和sql线程进入睡眠状态,等待下一次被唤醒。

3、MySQL架构(一主多备) 

3.1 一主多备 

 一般用来做读写分离的master 写 其他 salve 读这种架构最大问I/O 压力集在master 上 多台同步影响IO

3.2 M-S-S 

中继:分担master压力,slave中继需要开启bin-log并配置log-savle-update

总结:slave中继可以使用black-hole存储引擎,不会把数据存储到磁盘,值记录在二进制日志

 3.3 M-M/双主互备 (互为主从)

 (很多人误以为这样可以做到mysql负载均衡,实际没什么好处,每个服务器需要同样的同步更新,破坏了事务隔离性和数据一致性)

3.4 M-M-M 

监控三台机器互相做对方master

 天生的缺陷:复制延迟,salve上同步要慢于master,如果大并发的情况那么延迟更严重mysql5.6 已经自身可以实现fail over故障切换

4、MySQL主从复制延迟原因

  • master服务器高并发,形成大量事务
  • 网络延迟
  • 主从硬件设备导致(cpu主频、内存io、硬盘io)
  • 本来就不是同步复制、而是异步复制

5、MySQL主从复制延迟的优化

从库优化Mysql参数。比如增大innodb buffer pool size,让更多操作在Mysql内存中完成,减少磁盘操作。
从库使用高性能主机。包括cpu强悍、内存加大。避免使用虚拟云主机,使用物理主机,这样提升了i/o方面性。
从库使用SSD磁盘
网络优化,避免跨机房实现同步 

二、搭建MySQL主从复制

master:192.168.157.10 mysq5.7
slave 1:192.168.157.45 mysql5.7
slave 2:192.168.157.55 mysql5.7
客户端:192.168.157.65 mysql
关闭服务器的 firewalld和selinux设置

1、配置主从服务器时间同步

配置时间同步,可以使用chrony ,也可以使用ntp,但是两者只能使用其一

1.1 主服务器时间同步配置 

yum -y install ntp
vim /etc/ntp.conf
#在文件末尾添加
server 127.127.157.0  #设置时间源为本地
fudge 127.127.157.0 stratum 8  #设置时间层级(15以内)
 
#启动ntpd服务
service ntpd start 
#查看udp123端口
netstat -naup | grep :123

 

 

 1.2 从服务器时间同步配置

yum -y install ntp
 service  ntpd start 
 #进行时间同步,同步主服务器的时间
 /usr/sbin/ntpdate  192.168.23.10
 
 #配置周期性同步时间
 crontab -e 
 */30 * * * * /usr/sbin/ntpdate 192.168.23.103

 

2、mysql配置文件配置 

2.1 主服务器配置

 systemctl stop firewalld
 setenforce 0
 
 
vim /etc/my.cnf
.....
server-id = 10          #配置server id,集群内mysql服务器server -id不可以重复
log-bin=mysql-bin        #主服务器开启二进制日志
binlog_format=mixed      #使用混合模式
log-slave-updates=true    #允许从服务器更新二进制日hi
 
#重启mysql服务
systemctl restart mysqld
#进入数据库
mysql -uroot -123456
 
#刷新二进制日志
flush logs;  
 
#创建主从复制授权用户
grant  replication slave on *.* to 'myslave'@'192.168.157.%'  identified by '123456';
 
#查看当前 二进制日志名file和偏移量position
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

 

2.2 从服务器配置 

#关闭firewalld和selinux
systemctl stop firewalld
setenforce 0
 
 
vim /etc/my.cnf
....
#配置slave1的server id为45,slave 2 的server-id为55
server-id= 45 (server-id=13 #slave2)
 
relay-log=relay-log-bin                  #开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index    #定义中继日志的路径
relay_log_recovery=1
 
 
#重启mysqld服务
systemctl restart mysqld

 

 #进入数据库
mysql -uroot -123456
 
#配置同步
change master to
master_host='192.168.157.10',master_user='myslave',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=154;
 
change master to
    master_host='192.168.157.10',   #主服务器地址
    master_user='myslave',          #使用的用户
    master_password='123456',        #密码
    master_log_file='mysql-bin.000003',   #当前二进制日志名
    master_log_pos=154;                #二进制日志偏移量
     
start slave;        #启动同步。如果报错,执行reset  slave,然后重新设置
 
#查看slave状态,Slave_IO_Running和Slave_SQL_Running 状态都是yes
#如果状态不对,则stop slave;停止同步,然后再使用change命令重新配置
show slave status \G   
 

 

 3、验证

#在主服务器上进行增删改操作
#创建数据库test02
mysql> create database test02;
Query OK, 1 row affected (0.01 sec)
 
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| bank               |
| mysql              |
| performance_schema |
| sys                |
| test               |
| test02             |
+--------------------+
 
 
 
#从服务器上进行查看
#此时,从服务器上自动创建了数据库 test02
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test02             |
+--------------------+
5 rows in set (0.00 sec)
  

 

三、对于读写分离的三个问题

1、什么是读写分离?
       

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

2、为什么要读写分离?

因为数据库的"写”(写10000条数据可能要3分钟)操作是比较耗时的。
但是数据库的读”(读10000条数据可能只要5秒钟)。
所以读写分离,解决的是,数据库的写入,影响了查询的效率。

3、什么时候要读写分离?
       

数据库不一定要读写分离,如果程序使用数据库较多时,而史新少,查询多的情况下会考虑使用。利用数据库主从同步,冉通过速写分离可以分扣数据库压力,提高性能。

4、主从复制与读写分离
       

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

5、mysql支持的复制类型

(1)STATEMENT:基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysgl默认采用基于讲句的复制,执行效率高。
(2) ROW: 基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
(3)MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

6、主从复制的的工作过程

(1)Master节点将数据的改变记录成一进制日志(bin log),当Master上的数据发生改变时,则将其改变写入一进制日志中。

(2) slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求 Master的一进制事件。

(3)同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存slave节点本地的中继日志(Relay log)中,Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成 5ql语句逐一执行,使得其数据和 aster节点的保持一致,最后I/0线程和SOL线程将进入睡眠状态,等待下一次被唤醒。

首先,客户端将数据写入到master主服务器的数据库的磁盘中,master节点会通知存储引擎,会提交数据的事务,同时会将数据以基于行,sql,混合三种模式保存在二进制日志中;

从它会开启I/o线程用来监听mysql中binary log二进制文件,一旦二进制数据有更新的内容时,则会响应master,i/o线程发送请求,dump thread会读取binary log中的二进制文件的更新的内容并发送给I/o线程;

从接到数据后会保存在relay log(中继日志)中,同时sql thread线程会读取中继日志,并更新到本地的mysql中,达到主从的效果;

7、MySQL读写分离原理

只在主服务器上写,只在从服务器上读主数据库处理事务性查询,从数据库处理SELECT查询数据库复制用于将事务性查询的变更同步到集群中的从数据库
读写分离方案
基于程序代码内部实现
基于中间代理层实现
MySQL-Proxy
Amoeba

8、目前较为常见的MySQL读写分离

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

  在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。

        优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。

        但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大。

(2) 居于中间代理层实现
     

  代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。

MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项口,通过其自带的 lua 脚本进行SQL 判断。
Atlas。是山奇虎360的web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用atlas运行的mysq1业务,每大承载的读写请求数达儿十亿条。支持事物以及存储过程。
Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序Java诺言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。
由于使用MysQL Proxy 需要写大量的Lua脚本,这些Lua并不是现成的,而是需要自己去写。这对于并不熟悉MysQL Proxy内置变量和MysQL Protocol 的人来说是非常困难的。
Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层。

四、总结

1、读写分离使用的是什么方式?

amoeba、代理、mycat、sql_proxy
通过amoeba代理服务器,实现只在主服务器上写,只在从服务器上读;
主数据库处理事务性查询,从数据库处理select 查询;
数据库复制被用来把事务查询导致的变更同步的集群中的从数据库

2、如何查看主从同步状态是否成功

在从服务器上内输入  show slave status\G  查看主从信息看里面有IO线程的状态信息,还有master服务器的IP地址、端口事务开始号。
当slave_IO_Running和Slave_SQL_Running都是YES时,表示主从同步状态成功

3、如果I/O不是yes呢,你如何排查?

首先排查网络问题,使用ping 命令查看从服务器是否能与主服务器通信
再查看防火墙和核心防护是否关闭(增强功能)
接着查看从服务slave是否开启
两个从服务器的server-id 是否相同导致只能连接一台
master_log_file master_log_pos的值跟master值是否一致

4、show slave status能看到哪些消息(比较重要)

I/O线程的状态信息
master服务器的IP地址、端口、事务开始的位置
最近一次的错误信息和错误位置
最近一次的I/O报错信息和ID
最近一次的SQL报错信息和ID

5、主从复制慢(延迟)会有哪些可能?怎么解决?

主服务器的负载过大,被多个睡眠或僵尸线程占用
导致系统负载过大,从库硬件比主库差,导致复制延迟
主从复制单线程,如果主库写作并发太大,来不及传送到从库,就会到导致延迟
慢sql语句过多
网络延迟

6、若主从版本不一致

从的版本一定要高于主,保证可以向下兼容
因为若主的版本更新,低版本的从无法兼容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值