下载帮

您现在的位置是:首页 > 数据库 > MySQL

MySQL

Mysql数据库_主从复制与读写分离

2022-06-08 15:01MySQL

Mysql-主从复制与读写分离

1.MySQL主从复制与读写分离

1.1主从复制与读写分离

mysql使用主从复制的原因大概由一下三点:

1、在业务复杂的系统中,有这幺一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那幺就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。

2、做数据的热备

3、架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。

mysql主从复制原理

1.2 主从复制的过程

在主从复制过程中涉及到总共3个线程,两个日志

Master 二进制日志

SLAVE I/O线程

Master dump线程

SLAVE 中继日志

SLAVE SQL线程

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

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

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

半同步模式:注意:5.7版本主多了一个ACK_collection线程接受从的ack确认信息

1.3主从复制的同步模式

1.3.1异步复制:

异步复制是mysql 默认 的同步方式

在master为slave开通账号密码、ip授权之后,slave 可以从master进行数据同步,主要依赖的是master的binlog日志

slave会启动两个线程,IO Thread 和 SQL Thread

IO Thread 负责从master拉取binlog 日志,并写入relay中继日志

SQL Thread 负责将relay中继日志中的变更进行重放,更新数据来达到跟master保持数据一致的目的

这个过程中,slave通过IO线程拉取binlog,master无需关注是否有slave需要同步,只做自己的事情,整个复制过程都是异步完成的,这个就是异步复制

异步复制的优势是性能好,缺点是数据的安全性比较差

在某一刻主从之间的数据差异可能较大,主机挂掉之后从机接管,可能会丢失一部分数据。

1.3.2半同步复制

master更新操作写入binlog之后会主动通知slave,slave接收到之后写入relay log 即可应答,master只要收到至少一个ack应答,则会提交事务

可以发现,相比较于异步复制,半同步复制需要依赖至少一个slave将binlog写入relay log,在性能上有所降低,但是可以保证至少有一个从库跟master的数据是一致的,数据的安全性提高。

对于数据一致性要求高的场景,可以采用半同步复制的同步策略,比如主库挂掉时,准备接管的那一个从库,对数据的一致性要求很比较高。

半同步复制的优点是数据的安全性好,缺点是性能比异步复制稍低

1.3.3 全同步复制

全同步复制跟半同步复制的区别是,全同步复制必须收到所有从库的ack,才会提交事务。

主库的事务提交依赖于后面所有的从库,这样一来性能就会明显得下降

除非是对所有从库数据一致性要求非常高的场景,否则我们一般不采用这种策略

全同步复制的数据一致性最好,但是性能也是最差的

mysql主从同步的三种模式_吴小佳同学的博客

2.实验步骤

2.1主从复制配置

环境:centos7

mysql版本:5.7.37

mysql主节点:192.168.80.20

​ mysql从节点1:192.168.80.25

​ mysql从节点2:192.168.80.30

mysql主节点设置

1.ntp服务配置
[root@mysql_master ~]# yum install ntp -y
······
[root@mysql_master ~]# vim /etc/ntp.conf
--末尾添加--
server 127.0.0.1							#设置本地是时钟源,注意修改网段,127.0.0.1是本地回环地址(127.网段中所有ip实际上都是本地回环地址)
fudge 127.0.0.1 stratum 8	                #设置时间层级为8(限制在15内)
--------------------------------------------------------------
2.mysql配置文件
[root@mysql_master ~]# vim /etc/my.cnf
[mysqld]
......
server-id = 1
log-bin=mysql-bin							#添加,主服务器开启二进制日志
binlog_format = MIXED
log-slave-updates=true						#添加,允许slave从master复制数据时可以写入到自己的二进制日志
expire_logs_days = 7						#设置二进制日志文件过期时间,默认值为0,表示logs不过期
max_binlog_size = 500M						#设置二进制日志限制大小,如果超出给定值,日志就会发生滚动,默认值是1GB

:wq
--------------------------------------------------------------
[root@mysql_master ~]# systemctl restart mysqld   #重启msyql服务,使配置生效
[root@mysql_master ~]# mysql -uroot -p            #登录mysql

mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.80.%' IDENTIFIED BY '123456';  #从服务授权

mysql> FLUSH PRIVILEGES;

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      603 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
#File 列显示日志名,Position 列显示偏移量

mysql从节点1配置

1.ntp配置
[root@mysql_slave1 ~]# yum install ntp ntpdate -y
[root@mysql_slave1 ~]# service ntpd start
[root@mysql_slave1 ~]# /usr/sbin/ntpdate 192.168.80.20         #与主节点进行时间同步

[root@mysql_slave1 ~]# crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.80.20
--------------------------------------------------------------
2.mysql配置
[root@mysql_slave1 ~]# vim /etc/my.cnf
server-id = 25								#修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin						#添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index		#添加,定义中继日志文件的位置和名称,一般和relay-log在同一目录
relay_log_recovery = 1                      #选配项
#当 slave 从库宕机后,假如 relay-log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay-log,并且重新从 master 上获取日志,这样就保证了 relay-log 的完整性。默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为 1 时, 可在 slave 从库上开启该功能,建议开启。

:wq
--------------------------------------------------------------
[root@mysql_slave1 ~]# systemctl restart mysqld
[root@mysql_slave1 ~]# mysql -uroot -p

mysql> CHANGE master to master_host='192.168.80.20',master_user='myslave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=603;           #日志名称与偏移点应该与主status中的相同
mysql> start slave;
mysql> show slave status\G                # 查看从状态
//确保 IO 和 SQL 线程都是 Yes,代表同步正常。
Slave_IO_Running: Yes				#负责与主机的io通信
Slave_SQL_Running: Yes				#负责自己的slave mysql进程

#一般 Slave_IO_Running: No/CONNECTING 的可能性:
1、网络不通
2、my.cnf配置有问题
3、密码、file文件名、pos偏移量不对
4、防火墙没有关闭

mysql从节点2配置需要修改server-id

实验截图

主节点配置

1.ntp服务相关配置

2.mysql配置文件

[mysqld]下加入

mysql从节点配置:

1.ntp时间同步设置

2.mysql配置

主从复制效果验证:

2.2 读写分离配置

环境:centos7

mysql版本:5.7.37

​ mysql主节点:192.168.80.20

​ mysql从节点1:192.168.80.25

​ mysql从节点2:192.168.80.30

​ Amoeba 服务器:192.168.80.35 jdk1.6、Amoeba

Amoeba服务器配置

实现准备jdk和amoeba包至opt目录
1.配置java环境
[root@amoeba opt]# cd /opt
[root@amoeba opt]# cp jdk-6u14-linux-x64.bin  /usr/local/
[root@amoeba opt]# cd /usr/local/
[root@amoeba opt]# chmod +x jdk-6u14-linux-x64
[root@amoeba opt]# ./jdk-6u14-linux-x64.bin
//yes,按enter
[root@amoeba local]# mv jdk1.6.0_14/ /usr/local/jdk1.6

[root@amoeba local]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin

[root@amoeba local]# source /etc/profile
[root@amoeba local]# java -version

2.配置Amoeba
[root@amoeba local]# cd /opt
[root@amoeba opt]# mkdir /usr/local/amoeba
[root@amoeba opt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@amoeba opt]# chmod -R 755 /usr/local/amoeba/
[root@amoeba opt]# /usr/local/amoeba/bin/amoeba
##配置 Amoeba读写分离,两个 Slave 读负载均衡##
先将一主两从开放授权
grant all on *.* to test@'192.168.80.%' identified by '123.com';
#再回到amoeba服务器配置amoeba服务:
[root@amoeba opt]# cd /usr/local/amoeba/conf/
[root@amoeba opt]# cp amoeba.xml amoeba.xml.bak
[root@amoeba opt]# vim amoeba.xml		
--30行--
"user">amoeba
--32行-- 
"password">123456
--115行--
"defaultPool">master
--117-去掉注释-
"writePool">master
"readPool">slaves

:wq
--------------------------------------------------------------
[root@amoeba opt]# cp dbServers.xml dbServers.xml.bak
[root@amoeba opt]# vim dbServers.xml
--23行--注释掉  作用:默认进入test库 以防mysql中没有test库时,会报错

--26--修改
"user">test
--28-30--去掉注释
"password">123.com
--45--修改,设置主服务器的名Master
"master"  parent="abstractServer">
--48--修改,设置主服务器的地址
"ipAddress">192.168.80.10
--52--修改,设置从服务器的名slave1
"slave1"  parent="abstractServer">
--55--修改,设置从服务器1的地址
"ipAddress">192.168.80.11
--58--复制上面6行粘贴,设置从服务器2的名slave2和地址
"slave2"  parent="abstractServer">
"ipAddress">192.168.80.12
--65行--修改
"slaves" virtual="true">
--71行--修改
"poolNames">slave1,slave2

[root@amoeba opt]# /usr/local/amoeba/bin/amoeba start&    后台启动amoeba	
[root@amoeba opt]# netstat -anpt | grep java

实验截图

1.配置java环境

2.配置amoeba

先配置mysql一主两从开放授权

grant all on *.* to test@'192.168.80.%' identified by '123.com';

读写分离测试

主机通过Navicat连接数据库

主服务器上创建表

从1从2关闭主从复制

在slave1插入数据

在slave2插入数据

在master插入数据

Navicat查看表数据

关闭表刷新一次,在打开表test

插入一条数据

主查看数据

从1查看数据

从2查看数据

只有主能查看到插入的数据。

从2打开主从复制

可以看到客户端和主之前插入的数据了。

再次打开客户端查看,还是存在两种表记录的情况。

主服务器上还是只有客户端与主插入的数据。

文章评论