mysql主从复制和读写分离

主从复制

主从复制:主mysql上的数据,新增和修改的库,表,表里的数据,都会同步到从mysql上。

mysal的主从复制的模式:

1、异步复制:mysql的默认复制就是异步复制。
只要执行完之后,客户端提交事务,主mysql会立即把结果返回给从服务器,主mysql不管从mysql是否已经接受并且处理。
主一旦崩溃,主mysql的事务可能没有传到从mysql,这个时候强行把从提升为主,可能使新的主mysql,数据不完整。
2、全同步复制:主库执行完成一个事务,所有的从库都执行了该事务之后才会返回客户端。因为需要等待所有从库全部执行完成,性能必然下降。(对数据一致性,和数据完整要求很好的场景。)
3、半同步复制:介于异步复制和全同步复制之间。主库执行完一个客户端提交的事务之后,至少等待一个从库接受并处理完成之后才会返回给客户端。半同步在一定程度上提高了数据的安全性。也会有一定的延迟。这个延迟一般是一个tcp/ip的往返时间。(从发送到接收的时间,单位是毫秒),半同步复制最好在电视的网络中使用。时间<1ms:round-trip time RTT。

主从复制实验:

mysql1主 20.0.0.41
mysql2 从 20.0.0.42
mysql3 从 20.0.0.43
test1读写分离的服务器 20.0.0.10
test2客户端 20.0.0.20

主 vim /etc/my.cnf

server-id = 1

log-bin=master-bin

binlog_format=MIXED

log-slave-updates=true

[root@localhost ~]#systemctl restart mysqld

[root@localhost ~]#mysql -uroot -p

grant replication slave on *.* to 'myslave'@'20.0.0.%' identified by '123456';建立一个myslave用户,并且允许192.168.73.%这个网段的地址来登录,密码是123456,一会儿要在slave上使用这个账号

flush privileges;

show master status;#查看主服务器的bin-log日志文件名称和position点

从 vim /etc/my.cnf

server-id = 2

relay-log=relay-log-bin

relay-log-index=slave-relay-bin.index

[root@localhost ~]#systemctl restart mysqld

进入数据库

change master to master_host='20.0.0.41',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=603;根据本机位置

start slave;

show slave status \G;

中间报错

IO_Running: NO 

原因:克隆未修改uuid

解决:cat /var/lib/mysql/auto.cnf 发现uuid一样

vim /var/lib/mysql/auto.cnf 修改uuid

主从服务器之间的时间也要同步:
fudge 127.127.233.0 stratum 8
数字越小,时间精确度越高,设置fudge8时间层级是8最高到15。从本地获取时间源同步,不走网络。
log-slave-updates=true
#允许从服务器复制数据时,可以从主的二进制日志写到自己的二进制日志当中。relay_log_recovery=1
默认是0,1开启中继日志的恢复。从服务器出现异常或者崩溃时,从服务器会从主服务器的二进制的争取读取和应用中继日志。同步。
CHANG maste to master_host='192.168.233.21',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log pos=604;

Slave_IO_Running:Yes:负责和主库的IO通信
Slave_SQL Running:Yes负责自己的slave mysql进程

slave io running no

1、网络问题
2、my.cnf配置文件写错了(主要原因)
3CHANG maste to master_host='192.168.233.21',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log pos=604;要么是文件名错了,要么位置偏移量不对。

主从复制是单向的,只能从主复制到从服务器。

主从复制延迟问题:

1、网络延迟
2、主从硬件设备(CPU主频、内存IO、硬件IO)。
3、同步复制而不是异步复制。
解决方案:

1、硬件方面,主库一般来说不需要动的太多,从库的硬件配置要更好。提升随机写的性能。硬盘可以考虑换成固态的升级cpu的核数,扩展一下内存。尽量使用物理机(不要用云服务器。)4核8G,硬盘。

2、网络层面,主从服务器都配置在一个局域网内,尽量避免跨网段和跨机房。

3、架构方面:读写分离,把写入控制在主库,从库负责读,降低从库的压力

4、配置方面,mysql配置。从配置文件的角度实现性能最大化

追求安全性的配置:

innodb flush_log_at_trx_commit=1
#每次事务提交时都会刷新事务日志。已确保持久性,最高级别的数据安全性,但是会影响性能,默认就是1
0就是事务提交时不会立刻刷新,而是每秒刷新一次。可以提高性能,但是发生故障会导致数据丢失。
2事务提交时,事务日志不会写入硬盘而是保存在系统缓存,不会进行刷新。一定的安全性和性能。内存要求比较高。

sync binlog=1
1也是默认值,每次提交事务之后,直接把二进制日志刷新到磁盘,以确保日志的持久性。占用比较高的性能。但是安全性高。
0,二进制日志写入到缓存,也不会刷新日志。故障发生也会丢失数据,内存的要求也提高了
3,每3个事务执行一次刷新到磁盘。提高性能,但是一旦崩溃,数据会大量丢失。

追求性能化:

sync_binlog=0
innodb_flush_log_at _trx_commit=2
logs-slave-updates=0
从库的更新不会写入二进制日志。(不建议)
innodb_buffer_pool_size 300M 500G
innodb存储引擎的缓冲池大小,设置的s数值越高,可以提高innodb的性能。
更多的数据和索引都可以缓存在内存中。减少磁盘的访问次数。对系统内存要求比较高。

主从复制的工作过程:

1、主节点的数据记录发生变化都会记录在二进制日志。

2、slave节点会一定时间内对主库的二进制日志文件进行探测,看其是否发生变化,如果有变化,从库会开启一个l/O的线程请求的主库的二进制事件

3、主库会给每一个I/O的线程启动一个dump,用于发送二进制事件给从库,从库通过I/O线程获取更新,slave_sql负责将更新写入到从库本地。实现主从一致。

主从复制的问题:

1、只能在主库上发生变化,然后同步到从。

2、复制过程是串行化过程,在从库上复制是串行的,主库的并行更新不能在从库上并行操作。

3、主从复制的设计目的就是为在主库上写,在从库上查。读写分离,实现高可用。

读写分离:

要实现读写分离,必须要先实现主从复制。
读写分离后,所有的写入操作都在主库,从库只负责读。(select)。如果有更新,是从主库复制到从库。

使用mycat读写分离

步骤一:部署主从复制

如上 主服务器 20.0.0.41 从20.0.0.43

主从复制步骤二:安装mycat(20.0.0.42)

(1)主机上安装java(mycat基于java)
#yum安装java
[root@localhost ~]#yum install java -y
#确认安装成功
[root@localhost ~]#java -version
(2)切换至opt目录,下载mycat安装包
[root@localhost ~]#cd /opt
[root@localhost ~]#wget http://dl.mycat.org.cn/1.6.7.6/20210303094759/Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz
(3)创建/apps文件夹,并解压mycat包至/apps下
[root@localhost ~]#mkdir /apps
[root@localhost ~]#tar zxvf Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz -C /apps/
(4)设置变量环境
[root@localhost ~]#echo 'PATH=/apps/mycat/bin:$PATH' > /etc/profile.d/mycat.sh
[root@localhost ~]#source /etc/profile.d/mycat.sh
(5)启动mycat,查看日志文件,最后可以看到启动成功
[root@localhost ~]#mycat start
#注意内存小于2G 起不来
Starting Mycat-server...
[root@localhost ~]#tail -f /apps/mycat/logs/wrapper.log
#启动成功日志末尾会出现successfully
(6)客户端连接数据库
#这里密码初始为123456   需要加端口
[root@localhost bin]#mysql -uroot -p123456 -h 192.168.73.105 -P8066

步骤三:修改 mycat 配置文件

配置文件 /apps/mycat/conf/server.xml

[root@localhost ~]#vim /apps/mycat/conf/server.xml
#去掉44行行注释,对应的在51行行末注释,删除50行行末注释,5 * 60 * 1000L; //连接空>    闲检查
#修改45行端口号为3306
45 <property name="serverPort">3306</property>
#配置Mycat的连接信息(账号密码),在110 和111行

配置文件/apps/mycat/conf/schema.xml

vim /apps/mycat/conf/schema.xml

#删除所有内容,重新写入以下

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema>
        <dataNode name="dn1" dataHost="localhost1" database="hellodb" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                
                <writeHost host="host1" url="20.0.0.41:3306" user="root" password="abc123">
                 <readHost host="host2" url="20.0.0.43:3306" user="root" password="abc123"/>
 
                </writeHost>
        </dataHost>
</mycat:schema>

步骤三:master服务器进行授权

[root@localhost ~]#mysql -u root -p
#授权
GRANT ALL ON *.* TO 'root'@'192.168.73.%' IDENTIFIED BY '123456';
 
#查看创建成功
use mysql;
select user,host from user;

步骤四:重启mycat服务,客户机连接mycat

(1)在mycat服务器上,重启mycat服务,查看启动日志,文末出现successfully
 [root@localhost ~]#mycat restart  
 [root@localhost ~]#tail -f /apps/mycat/logs/wrapper.log
 
 
#######在master上创建一个数据库######
#新库就是TESTDB的实际库
mysql -u root  -p
create database hellodb ;
 
(2)在mycat主机上查看3306端口,可以监听到主从服务器
 [root@localhost ~]# ss -antp|grep 3306
 
(3)在客户机上登录mycat,这时可以不加端口直接进入数据库了
[root@localhost ~]#mysql -uroot -p  -h 192.168.73.105
#看是否能查到表
show databases;
use TESTDB;
show tables;
 
+-------------------+
 
#查看当前的查询来自哪台服务器,可以看到查询功能来自id为2的从服务器
select @@server_id;

为什么要有读写分离:

1、数据库在写入数据时,比较耗时(写10000条数据3分)
2、数据库在读的时候,速度很快(读10000条,4.96s)
读写分离之后,数据的写入和读取是分开的,哪怕写入的数据量比较大,但是不影响查询的效率。

什么场景下需要读写分离:

数据库不是一定需要读写分离的。只有在某些程序在使用数据库过程中,更新少,但是查询较多,这种情况可以考虑读写分离。读和查的需求差不多,也可以考虑读写分离。
生产库一般都会做读写分离,测试库一般不管。
在工作中,数据库的读写不会在同一个库中完成。既不安全,也不能满足高可用,也不能实现高并发。工作中都会做读写分离。

mysql读写分离的原理:

1、根据脚本实现:
在代码中实现路由分类。select insert进行路由分类。这种方式是最多的。
优点:性能好,在代码中就可以实现,不需要额外的硬件设备
缺点:开发实现的,跟我们无关。如果大型的复杂的应用,设计改动的代码非常多。
2、基于中间代理层实现:
mysal-proxy自带的开源项目,基于自带的lua脚本。这些lua脚本不是现成的,要自己写,不熟悉他的内置变量写不出来的。
atlas 360内部做自己使用的代理工具。每天的读写请求承载量可以到几十亿条。支持事务,支持存储过程。
Amoeba 不支持事务,也不支持存储过程。但是Amoeba还是用的最多的功能比较强大的软件。

Amoeba:来实现读写分离

面试题:

1、主从复制的原理
2、读写分离实现方式:
脚本 amoeba实现,mycat实现
3、如何查看主从复制是否成功?
show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
在主库创建一个库或者表,看是否能同步到从库。
4、如果slave_IO_running no排查思路是什么?
85%配置文件。

*5、show slave status\G;能得到的信息有哪些?
1、IO和sql的线程状态信息
2、master服务的ip地址,端口,事务开始的位置
3、最近一次的错误信息和错误的位置。
4、最近一次IO的报错信息
5、最近一次sql的报错信息

6、主从复制的延迟如何解决?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值