MySQL--主从复制和读写分离

MySQL主从复制和读写分离相关知识

1.什么是读写分离

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

2.为什么要读写分离?

1.数据库在写入数据的时候比较耗时(10000条数据 大概要4分钟)

2.数据库在读写的时候速度很快(10000条 大概5 秒左右)

读写分离之后,数据的写入和读取是分开的,哪怕写入的数据量比较大,但是不影响查询的效率

3.什么场景下需要读写分离?

数据库不是一定需要读写分离。只是在某些程序在使用数据库过程中,更新少,但是查询较多,这种情况可以考虑读写分离。

生产库一般都会做读写分离。

测试库一般不管。

在工作中,数据库的读写不会在同一个库中完成,这样既不安全,也不能满足高可用,也不能实现高并发。工作中都会做读写分离。

4.主从复制的优点

  • 数据分布:通过复制将数据分布到不同地理位置

  • 负载均衡:读写分离以及将读负载到多台从库

  • 备份:可作为实时备份

  • 高可用性:利用主主复制实现高可用

5. mysql支持的复制类型

(1) STATEMENT:基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制(5.7版本之前),执行效率高。高并发的情况可能会出现执行顺序的误差,事务的死锁。

(2)ROW:基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一 遍。精确,但效率低,保存的文件会更大。(5.7版本之后默认采用ROW模式)

(3)MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。更智能,所以大部分情况下使用MIXED。
 

三者区别

1.STATEMENT(基于sql):高并发会导致数据丢失,顺序有误

2.ROW(基于行):精准匹配,但恢复数据时,效率低

3.MIXED:一般情况用sql,高并发自动切换row

6.mysql主从复制的过程

主从复制基于主mysql服务器和从mysql服务器的三个线程两个日志展开进行的:

两个日志:二进制日志(bin log) 、中继日志(Relay log)

三个线程:I/O线程、dump线程、SQL线程

7.主从复制的工作过程:

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

2、 slave节点会在一定时间内对主库的二进制文件进行探测。探测是否发生变化。如果有变化从库会开启一个IO的线程。请求主库的二进制事件。

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

8.主从复制的问题:

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

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

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

MySQL主从复制的模式

1.异步复制:

MySQL的默认复制就算异步复制。只要执行完之后,客户端提交事务,主MySQL会立即把结果返回给服务器,主MySQL并不关心从MySQL是否已经接受,并且处理。

异步:不用等待返回结果(udp )

主一旦崩溃,主MySQL的事务可能没有传到从MySQL,这个时候强行把从提升为主,可能到新的主MySQL数据不完整(很少见)

2.全同步复制,

主库执行完成一个事务,所有的从库都执行了该事务之后才会返回客户端。因为需要等待所有从库全部执行完成,性能必然下降。(对数据一致性,和数据完整要求很好的场景)

3.半同步复制:

介于异步复制和全同步复制之间。主库执行完一个客户端提交的事务之后,至少等待一个从库接受并处理完成之后才会返回给客户端。半同步在一定程度上提高了数据的安全性。也会有一定的延迟。

这个延迟一般是一个tcp/ip的往返时间(从发送到接受的时间,单位是毫秒)。半同步复制最好在电视的网络中使用。

时间<1ms:round-trip-time RTT

如何实现主从复制

mysql 1  主  20.0.0.100
MySQL 2  从  20.0.0.110
MySQL 3  从  20.0.0.10
test1    读写分离的服务器 20.0.0.140
test2    客户端关闭防火墙
systemctl stop firewalld
setenforce 0MySQL1
yum -y install ntp
vim /etc/ntp.conf末
server 127.127.233.0
fudge 127.127.233.0 stratum 8
//数字越小。时间精确度越高。设置fudge 8,时间层级是8,最高为(15),设在中间即可,从本地获取时间源同步,不从网络获取systemctl restart ntpd
mysql2,3
systemctl restart ntpdmysql2,3
/usr/sbin/ntodate 192.168.233.21crontab -e -u root
*/30 * * * *  /usr/sbin/ntpdate 192.168.233.21date 查看时间MySQL1
vim /etc/my.cnfserver-id = 1
log-bin=master-bin
//打开二进制日志
binlog_format=MIXED
//处理方式
log_slave-updates=true
//允许从服务器复制数据时,可以从主的二进制日志写到自己的二进制日止当中
wqsystemctl restart mysqldmysql -uroot -p123456
grant replication slave on *.* to 'mysqlslave'@'20.0.0.%' identified by '123456';flush privilieges;show master status;从库MySQL2
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开启中继日志的护肤,从服务器出现异常或者崩溃时systemctl restart mysqldmysql3
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 mysqldmysql2
mysql -uroot -p123456CHANGE master to master_host='20.0.0.100',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=599;
//同步start slave;
show slave status\G;mysql3
mysql -u root -p 123456CHANGE master to master_host='20.0.0.100',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=599;
//同步
start slave;打开终端
MySQL1
create database kgc;MySQL2,3查看是否有kgc的库MySQL1
create table test ();
给表插入数据

Slave_IO_Running:Yes 负责和主库的IO通信

//位置偏移量不对,防火墙没关,配置文件不对

Slave SQL Running:Yes

//负责自己的slave MySQL进程

slave io running no 的原因

1.网络问题

2.my.cnf 配置文件写错了

3.CHANGE master to master_host='192.168.233.21',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604; 文件名写错了,位置偏移量不对

4.防火墙和安全机制的问题

**位置偏移量要和主服务器上  show master status;中内容一致

主从复制延迟的问题

1.网络延迟

2.主从硬件设备(CPU主频,内存I/O,硬件I/O)

3.同步复制而不是异步复制

解决方案:

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

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

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

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

追求安全性配置:

innodb flush_log_at_trx_commit=1

//每次啊hi去提交时都会刷新事务日志,已确保持久性,最高级别的数据安全性,但是会影响性能,默认是1

0 就是事务提交是不会立即刷新,而是每秒刷新。可以提高性能,但是发送故障会导致数据丢失

2 事务提交时,事务日志不会写入硬盘而是保存在系统缓存,不会进行刷新,一定的安全性和性能,内存要求比较高。

sunc_binlog=1

1 也是默认值,每次提交事务之后,直接把二进制刷新到硬盘,以确保日志的持久性,占用比较高的性能,但是安全

0 二进制日志写入缓存,也不会刷新日志文件。故障发送也会发发

读写分离配置

要实现读写分离,首先必须要实现主从复制。

读写分离:所有的写入操作都在主库,从库只负责读。(select)。如果有更新,是从主库复制到从库。

Mysql读写分离的原理:

1.根据脚本实现。在代码中实现路由分类。select insert进行路由分类。这种方式是最多的。

特点:性能号,在代码中就能实现,不需要额外的硬件设备

缺点:门槛高,开发实现。如果大型的复制的应用,设计改动的代码非常多。

2.基于中间层代理实现

mysql-proxy自带的开源项目。基于自带的lua脚本不是现成的,要自己写,不熟悉他的内置变量是写不出来的 atlas 360内部自己使用的代理工具。每天的读写请求承载量可以到几十亿条,支持事务,支持存储过程

Amoeba 陈思儒,之前在阿里就职。是由java开发的一个开源软件,不支持事务,也不支持存储过程。但是Amoeba也是用的最广

mycat也可以实现

安装部署mycat

(1)主机上安装java(mycat基于java)
#yum安装java
[root@localhost ~]#yum install java -y
#确认安装成功
[root@localhost ~]#java -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-b12)
OpenJDK 64-Bit Server VM (build 25.131-b12, mixed mode)(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
STATUS | wrapper  | 2021/12/09 21:04:10 | --> Wrapper Started as Daemon
STATUS | wrapper  | 2021/12/09 21:04:10 | Launching a JVM...
INFO   | jvm 1    | 2021/12/09 21:04:11 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO   | jvm 1    | 2021/12/09 21:04:11 |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
INFO   | jvm 1    | 2021/12/09 21:04:11 | 
INFO   | jvm 1    | 2021/12/09 21:04:12 | MyCAT Server startup successfully. see logs in logs/mycat.log(6)客户端连接数据库
#这里密码初始为123456   需要加端口
[root@localhost bin]#mysql -uroot -p123456 -h 192.168.59.114 -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行, 可以修改,这边不修改了

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

[root@localhost ~]#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标签:数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应。#name:逻辑数据库名,与server.xml中的schema对应;#checkSQLschema: 数据库前缀相关设置,这里为false;#sqlMaxLimit:  select时默认的limit,避免查询全表,否则可能会遇到查询量特别大的情况造成卡 死;#dataNode:表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name
</schema><dataNode name="dn1" dataHost="localhost1" database="hellodb" />#dataNode标签: 定义mycat中的数据节点,也是通常说的数据分片,也就是分库相关配置#name: 定义数据节点的名字,与table中dataNode对应#datahost: 物理数据库名,与datahost中name对应,该属性用于定义该分片属于哪个数据库实例#database: 物理数据库中数据库名,该属性用于定义该分片属性哪个具体数据库实例上的具体库<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"#dataHost标签: 物理数据库,真正存储数据的数据库#name: 物理数据库名,与dataNode中dataHost对应#maxCon属性指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的writeHost、readHost标  签都会使用这个属性的值来实例化出连接池的最大连接数#minCon属性指定每个读写实例连接池的最小连接,初始化连接池的大小#balance: 均衡负载的方式writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">#writeType: 写入方式#dbType: 数据库类型#dbDriver指定连接后端数据库使用的 Driver,目前可选的值有 native 和 JDBC。用 native 的话,因为这个值执行的是二进制的 mysql 协议,所以可以使用 mysql 和maridb。其他类型的数据库则需要使用 JDBC 驱动来支持。#switchType:  “-1” 表示不自动切换; “1” 默认值,自动切换; “2” 基于 MySQL主从同步的状态决定是否切换心跳语句为 show slave status; “3” 基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1)心跳语句为 show status like ‘wsrep%’.<heartbeat>select user()</heartbeat>#heartbeat: 心跳检测语句,注意语句结尾的分号要加<writeHost host="host1" url="192.168.59.113:3306" user="root" password="123456">#host:用于标识不同实例,一般 writeHost 我们使用*M1,readHost 我们用*S1。#url:后端实例连接地址。Native:地址:端口 JDBC:jdbc的url#user:后端存储实例需要的用户名字#password:后端存储实例需要的密码<readHost host="host2" url="192.168.59.112:3306" user="root" password="123456"/></writeHost></dataHost>
</mycat:schema>

<dataNode name="主服务器的主机名">

<database="指定主服务器的数据库名">

<writeHost host="host1" url="主服务器的IP">

<readHost host="host1" url="从服务器的IP">

主服务器上授权

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

GRANT ALL ON *.* TO 'root'@'192.168.59.%' IDENTIFIED BY '123456';

flush privileges;

此处一定要刷新权限,否则接下来配置无法成功启动!!!!

重启mycat服务,客户机连接mycat

在mycat服务器上,重启mycat服务,查看启动日志,文末出现successfully[root@localhost ~]#mycat restart  [root@localhost ~]#tail -f /apps/mycat/logs/wrapper.logINFO   | jvm 1    | 2021/12/09 21:15:40 | 
INFO   | jvm 1    | 2021/12/09 21:15:40 | MyCAT Server startup successfully. see logs in logs/mycat.log
STATUS | wrapper  | 2021/12/09 21:16:38 | TERM trapped.  Shutting down.
STATUS | wrapper  | 2021/12/09 21:16:39 | <-- Wrapper Stopped
STATUS | wrapper  | 2021/12/09 21:16:40 | --> Wrapper Started as Daemon
STATUS | wrapper  | 2021/12/09 21:16:40 | Launching a JVM...
INFO   | jvm 1    | 2021/12/09 21:16:40 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO   | jvm 1    | 2021/12/09 21:16:40 |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
INFO   | jvm 1    | 2021/12/09 21:16:40 | 
INFO   | jvm 1    | 2021/12/09 21:16:41 | MyCAT Server startup successfully. see logs in logs/mycat.l

查看3306端口,可以监听到主从服务器

ss -antp|grep 3306

此处必须得是 user:(("java".......))

才算成功。同时,如果本机有mysql,一定得关闭mysql服务,否则会因为端口被占从而服务搭建失败

在客户机上登录mycat,这时可以不加端口直接进入数据库了

如何实现完全同步

完全同步其实就是主主同步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/172050.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于IGT-DSER智能网关实现GE的PAC/PLC与罗克韦尔(AB)的PLC之间通讯

工业自动化领域的IGT-DSER智能网关模块支持GE、西门子、三菱、欧姆龙、AB等各种品牌的PLC之间通讯(相关资料下载)&#xff0c;同时也支持PLC与Modbus协议的工业机器人、智能仪表等设备通讯。网关有多个网口、串口&#xff0c;也可选择WIFI无线通讯。无需编程开发&#xff0c;只…

python 爬虫之urllib 库的相关模块的介绍以及应用

文章目录 urllib.request 模块打开 URL&#xff1a;发送 HTTP 请求&#xff1a;处理响应&#xff1a; 应用如何读取并显示网页内容提交网页参数使用HTTP 代理访问页面 urllib.request 模块 在 Python 中&#xff0c;urllib.request 模块是用于处理 URL 请求的标准库模块之一。…

11月14日星期二今日早报简报微语报早读

11月14日星期二&#xff0c;农历十月初二&#xff0c;早报微语早读。 1、江西南城县&#xff1a;限时发放购房补贴政策&#xff0c;三孩家庭每平方米最高补贴500元&#xff1b; 2、2023年中国内地电影市场累计票房突破500亿元&#xff1b; 3、市场监管总局&#xff1a;在全国…

vmware安装MacOS遇到的问题

安装过程&#xff1a;参考下面的文章 链接&#xff1a; 虚拟机VMware安装苹果系统macOS&#xff0c;超级详细教程&#xff0c;附文件下载&#xff0c;真教程&#xff01;&#xff01; 无限重启情况&#xff1a; &#xff08;二&#xff09; 配置虚拟机找到你的虚拟机安装文件…

Spring Cloud学习(七)【Docker 容器】

文章目录 初识 DockerDocker 介绍Docker与虚拟机Docker架构安装 Docker Docker 基本操作镜像相关命令容器相关命令数据卷 Dockerfile 自定义镜像镜像结构Dockerfile DockerComposeDockerCompose介绍安装DockerCompose Docker镜像仓库常见镜像仓库服务私有镜像仓库 初识 Docker …

U-Mail邮件系统安全登录解决方案

企业邮箱是企业对内对外商务往来的主要通信工具&#xff0c;并且企业邮箱里面还包含了大量企业内部隐私信息、商业机密等&#xff0c;很容易成为黑客的攻击目标。其中邮件盗号是企业邮箱遭受攻击的主要形式&#xff0c;一旦企业邮箱密码被黑客盗取&#xff0c;黑客不仅可以利用…

arcgis提取栅格有效边界

方法一&#xff1a;【3D Analyst工具】-【转换】-【由栅格转出】-【栅格范围】 打开一幅栅格数据&#xff0c;利用【栅格范围】工具提取其有效边界&#xff08;不包含NoData值&#xff09;&#xff1a; 方法二&#xff1a;先利用【栅格计算器】将有效值赋值为1&#xff0c;得到…

使用jmeter进行简单压力测试

前言 最近项目要上线,需要项目进行简单的压力测试,本次使用的是jmeter来进行的,由于本人不是专业测试,只是对本次使用过程进行简单的记录. 一.jemeter的下载与安装 我这个已经安装很久了,具体过程这个可以查询下其他博客(偷个懒). 二.使用过程 1.测试计划右击-添加(add)-线…

%与floormod方法区别

%求余数 计算步骤&#xff1a; 10 / -3 -3.333333........... %是向0方向取整&#xff0c;因此-3.3333.......取整数-3 10 % -3 10-&#xff08;-3*-3&#xff09; 1 floormod方法 计算步骤&#xff1a;floormod(10,-3) floormod是向负无穷方向取整&#xff0c;因此-3…

卸载本地开发环境,拥抱容器化开发

以前在公司的时候&#xff0c;使用同事准备的容器化环境&#xff0c;直接在 Docker 内进行开发&#xff0c;爽歪歪呀。也是在那时了解了容器化开发的知识&#xff0c;可惜了&#xff0c;现在用不到那种环境了。所以打算自己在本地也整一个个人的开发环境&#xff0c;不过因为我…

守护 C 盘,Python 相关库设置

前言 pip 安装依赖和 conda 创建环境有多方便&#xff0c;那 C 盘就塞得就有多满。以前我不管使用什么工具&#xff0c;最多就设置个安装位置&#xff0c;其他都是默认。直到最近 C 盘飙红了&#xff0c;我去盘符里的 AppData 里一看&#xff0c;pip 的缓存和 conda 以前创建的…

(.htaccess文件特性)[MRCTF2020]你传你呢 1

题目环境&#xff1a; 不难看出是一道文件上传漏洞 上传一句话木马文件burpsuite进行抓包<?php eval($_POST[shell]);?> 命名为PHP文件格式 Repeater进行重放 尝试了其它后缀进行绕过都没有成功 通过 application/x-php内容类型&#xff0c;可以看出被识别出是PHP文件&…