目录
Mysql主从复制原理
MySQL 的主从复制和 MySQL 的读写分离两者有着紧密联系,首先要部署主从复制,只有主从复制完成了,才能在此基础上进行数据的读写分离。
Mysql支持的复制类型
基于语句的复制(STATEMENT):在主服务器上执行的 SQL 语句,在从服务器上执行同样的语句。MySQL 默认采用基于语句的复制,效率比较高。
基于行的复制(ROW):把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
混合类型的复制(MIXED):默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制
Mysql主从复制工作过程
(1)Master节点将数据的改变记录成二进制日志(bin log),当Master上的数据发生改变时,则将其改变写入二进制日志中。
(2)Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求Master的二进制事件。
(3)同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relaylog)中,Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成sql语句逐一执行,使得其数据和Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒。
MySQL读写分离
1、读写分离的概念
读写分离基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
2、读写分离存在意义
因为数据库的“写”(写10000条数据可能要3分钟)操作是比较耗时的。
但是数据库的“读”(读10000条数据可能只要5秒钟)。
所以读写分离,解决的是,数据库的写入,影响了查询的效率
3、什么时候要读写分离
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。
4、MySQL 读写分离原理
读写分离就是只在主服务器上写,只在从服务器上读。
基本的原理是让主数据库处理事务性查询,而从数据库处理 select 查询。
数据库复制被用来把主数据库上事务性查询导致的变更同步到集群中的从数据库。
5、常见的 MySQL 读写分离
1)基于程序代码内部实现
在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。
优缺点:
优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;
缺点是需要开发人员来实现,运维人员无从下手。
并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大。
2)基于中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序:
MySQL-Proxy:MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。
Atlas:是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。
Amoeba:由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。
由于使用MySQL Proxy需要写大量的Lua脚本,这些Lua脚本不是现成的,而需要自己编写,这对于并不熟悉MySQL Proxy内置变量和MySQL Protocol的人来说是非常困难的。
Amoeba是一个非常容易使用,可移植性非常强的软件,因此它在生产环境中被广泛用于数据库的代理层。
Mysql主从复制的几个同步模式
●异步复制(Asynchronous replication)
MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
●全同步复制(Fully synchronous replication)
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
●半同步复制(Semisynchronous replication)
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
Mysql主从配置
主:192.168.100.130 /24
从1:192.168.100.129 /24
从2:192.168.100.131 /24
主服务器设置192.168.100.130
设置时间同步
[root@zzz ~]# vim /etc/ntp.conf
[root@zzz ~]# systemctl start ntpd
从服务器1设置192.168.100.129 /24
从服务器2设置192.168.100.128 /24
主从设置
主服务器设置192.168.100.130
[root@zzz ~]# vim /etc/my.cnf
[root@zzz ~]# systemctl restart mysqld
[root@zzz ~]# mysql -uroot -pabc123
从服务器1设置192.168.100.129 /24
[root@send ~]# systemctl restart mysqld.service
从2:192.168.100.131 /24
vim /etc/my.cnf
[root@localhost ~]# systemctl restart mysqld.service
[root@localhost ~]# mysql -uroot -pabc123
切换到主服务器192.168.100.130
从1:192.168.100.129 /24
切换到数据库,查看
从2:192.168.100.131 /24
切换到数据库,查看
半同步配置
主服务器设置192.168.100.130
从 服务器1 设置192.168.100.129 /24
[root@send ~]# systemctl restart mysqld
半同步状态已经开启
主服务器设置192.168.100.130
重启从数据库上的IO线程
在主库查询半同步状态
表示当前是异步模式还是半同步模式 on为半同步
当半同步复制发生超时〈由rpl_semi_sync_master_timeout参数控制,默认为10000ms,即10s),会暂时关闭半同步复制,转而使用异步复制,也就是会自动降为异步工作。
当master dump线程发送完一个事务的所有事件之后,如果在 rpl_ semi_sync_master timeout 内,收到了从库的响应,则主从又重新恢复为半同步复制。
Amoeba代理读写分离
主服务器:192.168.100.130
从服务器1:192.168.100.129
从服务器2:192.168.100.131
AMmoeba代理:192.168.100.40
客户端:192.168.100.128
AMmoeba代理服务器
配置环境
安装 Amoeba软件
在主服务器 两个从服务器的mysql上开放权限给 Amoeba访问
grant all on *.* to [email protected].% identified by abc123;
再回到amoeba服务器配置 amoeba服务
切换到客户端 192.168.100.128
Mysql远程登陆
[root@bogon ~]# yum install -y mariadb mariadb-server
切换到主服务器mysql查看数据是否更新
验证负载均衡
分别在两个从服务器上插入不同数据,最后在客户端查询
从1: mysql> insert into db_test.ky16 values(4,aa);
从2: mysql> insert into db_test.ky16 values(4,cc);
在客户端上查询
那如何判断写入是在哪个服务器上写的呢,很简单,只需在两个从服务器上关闭同步即可
mysql> stop slave;
再从客户端写入数据
mysql> insert into ky16 values(5,tiechui);