主从复制
主从复制架构图和数据流向
主从复制:主MySQL上的数据,新增、修改库、表、表里的数据,都会同步到从MySQL上
Q:MySQL的主从复制模式
A:1、异步复制:MySQL的默认复制,就是异步复制
异步:类似于udp。只要执行完之后,客户提交事务,主MySQL会立即把结果返回给从服务器,主MySQL并不关心从MySQL是否已经接受并且处理。
主一旦崩溃,主MySQL的事务可能没有传到从MySQL,这个时候强行把从提升为主,可能新的主MySQL数据不完整。(很少见,工作中都是异步复制)
2、全同步复制
主库执行完成一个事务之后,所有的从库都执行了该事务,才会返回客户端。
因为需要等待所有从库全部执行完成,性能必然下降(适用于:对数据一致性和数据完成要求很好的场景)
3、半同步复制
介于异步复制和全同步复制之间。主库执行完一个客户端提交的事务之后,至少等待一个从库接收并处理完成之后才会返回给客户端。
半同步在一定程度上提高了数据的安全性,也会有一定的延迟(延迟:一般是一个tcp/ip的往返时间)(从发送到接收的时间,单位是毫秒)【半同步复制最好在低延时的网络中使用】
时间=20ms:round-trip time RTT
---------------------------------------------------------------------------------------------------------------------------------
主从复制的实验
架构主从复制和读写分离
MySQL1 主 10
MySQL2 从 20
MySQL3 从 30
test1 读写分离的服务器 40
test2 客户端 50
主:
vim /etc/ntp.cnf
server 127.127.233.0
fudge 127.127.233.0 stratum 8
数字越小,时间精确度越高,设置fudge 8 时间级是8 最高到15。从本地获取时间源同步
systemctl restart ntpd
主从同步
date
主
vim /etc/my.cnf
log-bin=master-bin
打开二进制日志
binlog_format=MIXED
log-salve-updates=true
允许从服务器复制数据时,可以从主的二进制日志写到自己的二进制日志当中
mysql -u root -p123456
grant replication slave on *.* to ‘myslave’@’192.168.233.%’ identified by ‘123456’;
flush privileges;
show master status;
然后去从20
vim /etc/my.cnf
server -id = 2
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
relay_log_recovery=1
#默认是0,1是开启中继服务器的恢复。从服务器出现异常或者崩溃时,从服务器会从主服务器的二进制日志的争取读取和应用中继日志。同步
:wq!
systemctl restart mysql
从3
vim /etc/my.cnf
server -id = 3
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
relay_log_recovery=1
:wq!
systemctl restart mysql
从2、3
mysql -u root -p123456
change master to master_host='192.168.233.10',master_user='myslave',master_password='123456',master_log_file='master-bin.000010',master_log_pos=604;
start slave;
shoow slave status\G;
负责和主库的IO通信
负责自己的slave mysql进程是否开启
两个必须都是YES
Q:如果slave_IO-running=NO
A:1、网络问题
2、my.cnf配置文件写错了
3、CHANGE master to
master_host='192.168.233.10',master_user='myslave',master_password='123456',master_log_file='master-bin.000010',master_log_pos=604;要么是文件名错了,要么就是位置偏移量不对
4、防火墙和安全机制的问题
navicat 主
create database kgc;
create table test (name varchaer(10));
vavicat 从
create databaes abc;
注意:
主从复制是单向的,只能从主复制到从,不会从从复制到主
---------------------------------------------------------------------------------------------------------------------------------
Q:主从复制的延迟问题
A:1、网络延迟
2、主从的硬件设备【CPU的主频率、内存的IO、硬件的IO】
3、使用同步复制而不是异步复制
解决方案:
1、硬件方面
主库一般不需要动的太多,从库的硬件配置要更好。提升他的随机写的性能。硬盘可以换成固态的、升级CPU的核数、扩展一下内存。尽量使用物理机(不要用云服务器)2、网络层面
2、网络层面
主从服务器都配置在一个局域网内,尽量避免跨网段和跨机房
3、架构方面
做读写分离,把写入控制在主库,从库只负责读
4、配置方面
MySQL配置。从配置文件的角度实现性能最大化
追求安全性的配置:
innodb_flush_log_at_trx_commit=1
1 默认值。每次事务提交时,都会刷新事务日志,以确保持久性。最高级别的数据安全性,但是会影响性能。
0 事务提交时不会立刻刷新,而是每秒刷新一次,可以提高性能,但是发生故障会导致数据丢失
2 事务提交时,事务日志不会写入硬盘,而是保存在系统缓存,也不会进行刷新,提供了一定的安全性和性能,但是对内存要求比较高
生产中默认是1
sync binlog=1
1 也是默认值。每次事务提交之后,直接把二进制日志刷新到磁盘,以确保日志的持久性。占用比较高的性能,但是安全性高
0 把二进制日志写入缓存,也不会刷新日志。故障发生,数据会丢失。对内存的要求高
N 自定义数字。每提交N次事务执行一次刷新到磁盘。可以提高性能,但是一旦崩溃,数据会大量丢失
追求性能化:
sync binlog=0
innodb_flush_log_at_trx_commit=2
logs-slave-updates=0
从库的更新不会写入二进制日志
innodb_buffer_pool_size 300M 8888G
size后面的随便写。innodb存储引擎的缓冲池大小,设置的数值越高,可以提高innodb的性能
更多的数据和所引都可以缓存在内存中。减少磁盘的访问次数,对系统内存要求比较高
主从复制的工作过程
1、主节点的数据记录发生变化都会记录在二进制日志
2、slave节点会一定时间内对主库的二进制文件进行探测,看其是否发生变化。如果有变化,从库会开启I/O的线程,请求的主库的二进制事件
3、主库会给每一个I/O的线程启动一个dump(mysqldump),用于发送二进制事件给从库,从库通过I/O线程获取更新,slave_sql负责将更新写入到从库本地,实现主从一致
主从复制的问题
1、只能在主库上发生变化,然后同步到从
2、复制过程是串行化过程,在从库上复制是串行的,主库的并行更新不能在从库上并行操作
3、主从复制的设计目的就是为在主库上写,在从库上查。读写分离,实现高可用
读写分离
读写分离
要实现读写分离,就必须要实现主从复制
读写分离:所有的写入操作都在主库,从库只负责读。(select)如有更新,是从主库复制到从库
为什么要有读写分离?
1、数据库在写入数据时比较耗时
以MySQL为例:写10000条数据,需要3分左右
2、读比较快
以MySQL为例:读10000条需要4.96s
读写分离之后,数据的写入和读取是分开的,哪怕写入的数据量比较大,但是不影响查询的效率
什么场景下需要读写分离?
数据库不是一定需要读写分离的,只有在某些程序在使用数据库过程中,更新少,但是查询较多,这种情况可以考虑读写分离
读和查的需求差不多,也可以考虑读写分离
生产库一般都会做读写分离,测试库一般不会
在工作中,数据库的读写不会在同一个库中完成。这样既不安全,也不能满足高可用,也不能实现高并发。工作中都会做读写分离
MySQL读写分离的原理
1、根据脚本实现
在代码当中实现路由分类。对开发的要求较高,在select或者insert中进行路由分类。这种方式是最多的。
优点:性能好,在代码中就可以实现,不需要额外的硬件设备
缺点:①开发实现的,和咱无关;②如果大型的复杂的应用,设计改动的代码非常多
2、基于中间代理层实现
mysql-proxy 是MySQL自带的开源项目,基于自带的lua脚本。这些lua脚本不是现成的,要自己写,不熟悉他的内置变量写不出来
3、atlas(阿特拉斯)
360内部的自己使用的代理工具。每天的读写请求承载量可以达到几十亿条。支持事务、支持存储过程
4、Amoeba
开发人:陈思儒,之前在阿里就职。是由Java开发的一个开源软件。不支持事务、不支持存储过程。但是Amoeba还是用的最多的,功能比较强大的软件
Amoeba来实现读写分离
---------------------------------------------------------------------------------------------------------------------------------
读写分离的实验
MySQL1 主 10
MySQL2 从 20
MySQL3 从 30
test1 读写分离的服务器 40
test2 客户端 50
读写分离的数据流向
---------------------------------------------------------------------------------------------------------------------------------
Q1:主从复制的原理
A1:
Q2:读写分离的实现方式
A2:amoeba实现、mycat实现
通过amoeba代理服务器,实现只在主服务器上写,只在从服务器上读;
主数据库处理事务性查询,从数据库处理select 查询;
数据库复制被用来把事务查询导致的变更同步的集群中的从数据库
Q3:如何查看主从同步的状态是否成功
A3:
在从服务器上内输入 show slave status\G; 查看主从信息查看里面有IO线程的状态信息,还有master服务器的IP地址、端口事务开始号。
当 Slave_IO_Running和Slave_SQL_Running都是YES时 ,表示主从同步状态成功
或者
在主库创建一个库或者表,看是否能同步到从库
Q4:如果slave_IO_running=NO,排查思路是什么?
A4:首先排查网络问题,使用ping 命令查看从服务器是否能与主服务器通信
再查看防火墙和核心防护是否关闭(增强功能)
接着查看从服务slave是否开启
两个从服务器的server-id 是否相同导致只能连接一台
master_log_file master_log_pos的值跟master值是否一致
Q5:show slave status\G;能看到的信息有哪些?【⭐⭐⭐】
A5:
1、IO和sql的线程状态信息
2、master服务的ip地址,端口,事务开始的位置
3、最近一次的错误信息和错误的位置
4、最近一次的IO报错信息
5、最近一次的sql的报错信息
Q6:主从复制的延迟如何解决
A6:
mysql语句过多
网络延迟
mysql主从复制对版本的要求:若主从版本不一致,从的版本一定要高于主,保证可以向下兼容。因为若主的版本更新,低版本的从无法兼容的