您当前的位置:首页 > 电脑百科 > 数据库 > MYSQL

MySQL 读写分离

时间:2022-04-26 10:02:54  来源:  作者:上班爱摸鱼的IT男

一、读写分离概述

读写分离,简单来说是把对数据库的读和写操作分开,当应用程序发起读操作时分配给读库,当应用程序发起写操作时分配给写库,从而达到减轻单台数据库服务器的压力。

实现读写分离的工具使用mycat就可以,当然还有其它的,mycat不仅可以支持MySQL,也支持oracle和SQL server。

MySQL 读写分离

读写分离逻辑图

读写分离是基于MySQL 的主从复制的,所以在实现读写分离前,我们先回顾下mysql主从复制。mysql主从复制首先它是基于二进制日志实现的,这个二进制binlong包含了DDL和DML语句。实现原理是这样的: 当主库执行了DDL和DML语句,会将数据的变更记录到binlog日志文件里,从库中的IO线程负责去读取主库的binlog,然后记录到自己的中继日志relay log中,从库的SQL线程读取中继日志relay log 重新执行到从库中。

MySQL 读写分离

 

一主一从环境环境准备,如图示:

MySQL 读写分离

 

二、配置一主一从读写分离

通过mycat来控制后台数据库的读写分离和负载均衡,由schema.xml文件中的datahost标签里的balance属性来控制。

MySQL 读写分离

 

balance属性值含义:

0: 表示不开启读写分离机制,所有读操作都发送到当前可用的writeHost 上。

1: 表示全都的readHost与备用的writeHost都参与select语句的负载均衡(针对双主环境)

2: 所有的读写操作都随机在writeHost、readHost上分发。

3: 所有的读请求随机分发到writeHost对应的readHost上执行,writeHost不负责读压力。

配置过程修改schema.xml 添加逻辑库及读写分离dataHost标签,

MySQL 读写分离

schme.xml

然后修改server.xml 运行用户访问读写分离逻辑库DB_TBSHARE_RW.

MySQL 读写分离

server.xml

ok,配置好后重启mycat进行测试。

[root@db-master /usr/local/mycat/conf]# ../bin/mycat start

[root@db-master /usr/local/mycat/conf]# cat ../logs/wrApper.log
STATUS | wrapper | 2022/04/24 20:57:01 | --> Wrapper Started as Daemon
STATUS | wrapper | 2022/04/24 20:57:02 | Launching a JVM...
INFO | jvm 1 | 2022/04/24 20:57:03 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO | jvm 1 | 2022/04/24 20:57:03 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
INFO | jvm 1 | 2022/04/24 20:57:03 |
INFO | jvm 1 | 2022/04/24 20:57:10 | MyCAT Server startup successfully. see logs in logs/mycat.log

[root@db-master /usr/local/mycat/conf]# mysql -uroot -h192.168.128.100 -p123456 -P8066
。。。
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> show databases;
+---------------+
| DATABASE      |
+---------------+
| DB_TBSHARE    |
| DB_TBSHARE_RW |
| SHOPING       |
+---------------+
3 rows in set (0.02 sec)

mysql> use DB_TBSHARE_RW;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+----------------------+
| Tables_in_db_tbshare |
+----------------------+
| tb_user              |
+----------------------+
1 row in set (0.02 sec)

mysql> 

插入4条数据,然后select,此时我们分辨不出查询是主库的还是从库的,懵逼了

mysql> insert into tb_user values(1,'凤雏','男');
Query OK, 1 row affected (0.02 sec)
mysql> insert into tb_user values(2,'落凤坡','男');
Query OK, 1 row affected (0.02 sec)
mysql> insert into tb_user values(3,'小乔','女');
Query OK, 1 row affected (0.02 sec)
mysql> insert into tb_user values(4,'风二娘','女');
Query OK, 1 row affected (0.10 sec)

mysql> select * from tb_user;
+----+-----------+------+
| id | username | sex |
+----+-----------+------+
| 1 | 凤雏 | 男 |
| 2 | 落凤坡 | 男 |
| 3 | 小乔 | 女 |
| 4 | 风二娘 | 女 |
+----+-----------+------+
4 rows in set (0.01 sec)

办法来了,我们悄悄的把从库的小乔改成大桥试试, 因为从库的更新不可能同步到主库对吧,条友们,然后才select验证,如下图示,读写分离正常。

MySQL 读写分离

 

由于这一主一从存在单点故障,当主库挂了,通过mycat查询是没问题的,但是执行DML和DDL会提示连接断开,导致大家熬夜加班。

三、主主复制,双主双从架构实现读写分离

主节点master1用于处理所有的写请求,它的从节点slave1和另外一台主节点master2及slave2从节点负责所有的读请求。当master1主机节点宕机后,master2主节点负责写请求,它俩互为备机,如图示:

MySQL 读写分离

 

实现过程

1、搭建双主

修改M1的 my.cnf 添加主要参数

server_id=33061

binlog-do-db=db01

binlog-do-db=db02

binlog-do-db=db03

log-slave-updates=1 #强制刷新从库二进制日志,如果有更新的话

M2的my.cnf文件添加

server_id=33062

binlog-do-db=db01

binlog-do-db=db02

binlog-do-db=db03

log-slave-updates=1

然后在两个主库中创建复制账号

grant replication slave on *.* to repl@'192.168.128.%' identified by '123456';

flush privileges;

show master status;

MySQL 读写分离

 

从库配置,修改server_id 即可

server_id=33071 # S1

server_id=33072 # S2

重启服务

接着配置两台从库管理主库,S1关联M1

change master to master_host='192.168.128.100',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=154;

start slave && show slave status;

S2管理M2

change master to master_host='192.168.128.101',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=154;

start slave; && show slave status; # 如果有故障就reset slave all

主库M1和M2相互复制

M1: change master to master_host='192.168.128.101',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=154;

start slave && show slave status;

M2: change master to master_host='192.168.128.100',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=154;

start slave && show slave status;

测试,分别在两台M1、M2上执行DDL、DML语句,查看涉及到的数据库服务器的数据同步情况。

M1 上创建db01, 如图db01全部同步完成。

MySQL 读写分离

 

在M2上创建表并插入数据观察同步情况

MySQL 读写分离

 

是没有问题的

MySQL 读写分离

 

主从主主复制已实现,接下来实现双主双从读写分离。

Mycat控制后台数据库的读写分离和负载均衡是由schema.xml文件中的datahost标签里的balance属性控制的,通过writeType及switchType来完成失败自动切换。

MySQL 读写分离

 

schema.xml 配置


<schema name="DB_TBSHARE_RW2" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn7">
                <!--此处可以不用配逻辑表-->
</schema>

<dataNode name="dn7" dataHost="dbhost7" database="db01" />

<dataHost name="dbhost7" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!--M1 S1-->
<writeHost host="master1" url="192.168.128.100:3306" user="root" password="123456">
<readHost host="slave1" url="192.168.128.101:3307" user="root" password="123456" />
</writeHost>
<!--M2 S2-->
<writeHost host="master2" url="192.168.128.101:3306" user="root" password="123456">
<readHost host="slave2" url="192.168.128.101:3307" user="root" password="123456" />
</writeHost>
</dataHost>

balance="1", 表示全部的readHost与备用的writeHost参与select语句的负载均衡,换句话说,就是当双主双从模式M1->S1,M2->S2互为主备,正常情况下,M2、S1、S2都参与select语句的负载均衡。

writeType: 0 写操作都转发到第一台writehost、writehost1宕机会切换到writehost2上

1 所有的写操作都随机发送到配置的writehost上。

switchType: -1 不自动切换 ; 1 自动切换

配置好后,重启mycat。 ./bin/mycat restart

[root@db-master ~]# mysql -uroot -h192.168.128.100 -p123456 -P8066
.......
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
mysql> show databases;
+----------------+
| DATABASE |
+----------------+
| DB_TBSHARE |
| DB_TBSHARE_RW2 |
| SHOPING |
+----------------+
3 rows in set (0.02 sec)

mysql> use DB_TBSHARE_RW2;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+----------------+
| Tables_in_db01 |
+----------------+
| tb_user |
+----------------+
1 row in set (0.02 sec)
mysql>

  mysql> select * from tb_user;
+----+------+------+
| id | name | sex  |
+----+------+------+
|  1 | Jack | 1    |
|  2 | Tony | 1    |
|  3 | mack | 2    |
|  4 | Lucy | 2    |
|  5 | Mely | 2    |
+----+------+------+
5 rows in set (1.86 sec)

为了区分查询结果到底是哪台节点上的,我们先把S1 和S2 上的数据进行标识。

mysql> update tb_user set name='Jack-S1' where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from tb_user;
+----+---------+------+
| id | name | sex |
+----+---------+------+
| 1 | Jack-S1 | 1 |                     # 查询结果为Jack-S1 |说明来自S1
。。。。

mysql> update tb_user set name='Jack-S2' where id=1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from tb_user;
+----+---------+------+
| id | name    | sex  |
+----+---------+------+
|  1 | Jack-S2 | 1    |                   # 查询结果为Jack-S2 |说明来自S2
。。。。。

我们切换会mycat进行查询

mysql> select * from tb_user;
+----+---------+------+
| id | name | sex |
+----+---------+------+
| 1 | Jack-S1 | 1 |                               # 从节点 S1
| 2 | Tony | 1 |
| 3 | Mack | 2 |
| 4 | Lucy | 2 |
| 5 | Mely | 2 |
+----+---------+------+
5 rows in set (0.00 sec)

mysql> select * from tb_user;
+----+---------+------+
| id | name | sex |
+----+---------+------+
| 1 | Jack-S1 | 1 |                               # 从节点 S1
| 2 | Tony | 1 |
| 3 | Mack | 2 |
| 4 | Lucy | 2 |
| 5 | Mely | 2 |
+----+---------+------+
5 rows in set (0.01 sec)

mysql> select * from tb_user;
+----+------+------+
| id | name | sex |
+----+------+------+
| 1 | Jack | 1 |
| 2 | Tony | 1 |                   # 主节点M2,因为M1负责写操作,我们配了balance="1"
| 3 | Mack | 2 |
| 4 | Lucy | 2 |
| 5 | Mely | 2 |
+----+------+------+
5 rows in set (0.03 sec)

mysql> select * from tb_user;
+----+------+------+
| id | name | sex |
+----+------+------+
| 1 | Jack | 1 |
| 2 | Tony | 1 |
| 3 | Mack | 2 |
| 4 | Lucy | 2 |
| 5 | Mely | 2 |
+----+------+------+
5 rows in set (0.00 sec)

插入一条数据 看看4个节点同步情况

mysql> insert into tb_user values(6,'Baky','2');

Query OK, 1 row affected (0.33 sec)

MySQL 读写分离

 

mysql> update tb_user set name='SZ-马' where id=2;

update 更新也是没有问题的。

Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from tb_user;
+----+--------+------+
| id | name | sex |
+----+--------+------+
| 1 | Jack | 1 |
| 2 | SZ-马 | 1 |
| 3 | Mack | 2 |
| 4 | Lucy | 2 |
| 5 | Mely | 2 |
| 6 | Baky | 2 |
+----+--------+------+
6 rows in set (0.01 sec)
mysql> select * from tb_user;
+----+---------+------+
| id | name | sex |
+----+---------+------+
| 1 | Jack-S1 | 1 |
| 2 | SZ-马 | 1 |
| 3 | Mack | 2 |
| 4 | Lucy | 2 |
| 5 | Mely | 2 |
| 6 | Baky | 2 |
+----+---------+------+
6 rows in set (0.02 sec)
mysql> select * from tb_user;
+----+---------+------+
| id | name | sex |
+----+---------+------+
| 1 | Jack-S1 | 1 |
| 2 | SZ-马 | 1 |
| 3 | Mack | 2 |
| 4 | Lucy | 2 |
| 5 | Mely | 2 |
| 6 | Baky | 2 |
+----+---------+------+
6 rows in set (0.25 sec)

模拟M1节点宕机,看看会不会切换M2及能否执行写入操作

systemctl stop mysqld

mysql> select * from tb_user;
+----+---------+------+
| id | name | sex |
+----+---------+------+
| 1 | Jack-S1 | 1 |
| 2 | SZ-马 | 1 |
| 3 | Mack | 2 |
| 4 | Lucy | 2 |
| 5 | Mely | 2 |
| 6 | Baky | 2 |
+----+---------+------+
6 rows in set (0.01 sec)

mysql> select * from tb_user;
+----+---------+------+
| id | name    | sex  |
+----+---------+------+
|  1 | Jack-S2 | 1    |
|  2 | SZ-马   | 1    |
|  3 | Mack    | 2    |
|  4 | Lucy    | 2    |
|  5 | Mely    | 2    |
|  6 | Baky    | 2    |
  
  mysql> insert into tb_user values(7,'www','1');
Query OK, 1 row affected (0.01 sec)

mysql> select * from tb_user;
+----+--------+------+
| id | name   | sex  |
+----+--------+------+
|  1 | Jack   | 1    |
|  2 | SZ-马  | 1    |
|  3 | Mack   | 2    |                # M2
|  4 | Lucy   | 2    |
|  5 | Mely   | 2    |
|  6 | Baky   | 2    |
|  7 | www    | 1    |
+----+--------+------+
7 rows in set (0.00 sec)

mysql> select * from tb_user;
+----+---------+------+
| id | name    | sex  |
+----+---------+------+
|  1 | Jack-S2 | 1    |
|  2 | SZ-马   | 1    |
|  3 | Mack    | 2    |
|  4 | Lucy    | 2    |
|  5 | Mely    | 2    |
|  6 | Baky    | 2    |
|  7 | www     | 1    |
+----+---------+------+
7 rows in set (0.00 sec)

mysql> select * from tb_user;
+----+---------+------+
| id | name    | sex  |
+----+---------+------+
|  1 | Jack-S1 | 1    |
|  2 | Tony    | 1    |
|  3 | Mack    | 2    |
|  4 | Lucy    | 2    |
|  5 | Mely    | 2    |
|  6 | Baky    | 2    |
+----+---------+------+
6 rows in set (0.00 sec

OK,读写分离讲完啦,你学废了吗。



Tags:读写分离   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Nginx 大揭秘:读写分离助力您轻松征服高并发
引言在构建高性能、高可用的 Web 应用时,如何有效地处理数据库的读写负担已成为一个十分重要的考虑因素。Nginx 作为一款强大的反向代理服务器,提供了简单而灵活的负载均衡配...【详细内容】
2023-11-14  Search: 读写分离  点击:(55)  评论:(0)  加入收藏
MySQL 数据库读写分离
MySQL 是最流行的关系型数据库管理系统MySQL 配置主备模式基于一台服务器的数据复制,故得名单机热备,主-备 Active-Standby 主-备方式,即指的是一台服务器处于某种业务的激...【详细内容】
2023-03-22  Search: 读写分离  点击:(128)  评论:(0)  加入收藏
MySQL读写分离,写完读不到问题如何解决
今天我们来详细了解一下主从同步延迟时读写分离发生写后读不到的问题,依次讲解问题出现的原因,解决策略以及 Sharding-jdbc、MyCat 和 MaxScale 等开源数据库中间件具体的实现...【详细内容】
2022-11-09  Search: 读写分离  点击:(337)  评论:(0)  加入收藏
关于Linux下MySQL主备集群负载均衡之读写分离(MaxScale)
写在前面 分享一些MySQL(MariaDB)集群主从结构数据读写分离的笔记,关于读写分离: 一如果对于读密集型应用,可以容忍从库异步复制延迟导致的脏数据,读写分离是一种不错的负载均...【详细内容】
2022-10-15  Search: 读写分离  点击:(399)  评论:(0)  加入收藏
数据库读写分离详解
一、实现高性能数据库集群一般我们业务在读多写少的场景下,遇到的第一个瓶颈就是数据库这块,大量的读请求会来到数据库,这样如果你初期部署的一个数据库就会造成IO大量增加,使得...【详细内容】
2022-07-20  Search: 读写分离  点击:(481)  评论:(0)  加入收藏
阿里大神都在用的MySQL读写分离
1、简介  当今MySQL使用相当广泛,随着用户的增多以及数据量的增大,高并发随之而来。然而我们有很多办法可以缓解数据库的压力。分布式数据库、负载均衡、读写分离、增加缓存...【详细内容】
2022-05-16  Search: 读写分离  点击:(420)  评论:(0)  加入收藏
MySQL 读写分离
一、读写分离概述读写分离,简单来说是把对数据库的读和写操作分开,当应用程序发起读操作时分配给读库,当应用程序发起写操作时分配给写库,从而达到减轻单台数据库服务器的压力。...【详细内容】
2022-04-26  Search: 读写分离  点击:(383)  评论:(0)  加入收藏
mysql搭建及主从同步+读写分离
从库生成两个线程,一个I/O线程,一个SQL线程;i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;主库会生成一个 log dump 线程,用来给从库 i/o线程传...【详细内容】
2022-04-08  Search: 读写分离  点击:(322)  评论:(0)  加入收藏
MySQL MyCAT 读写分离实战
1.MySQL读写分离概念:MYSQL读写分离的原理其实就是让Master数据库处理事务性增、删除、修改、更新操作(CREATE、INSERT、UPDATE、DELETE),而让Slave数据库处理SELECT操作,MYSQL读...【详细内容】
2021-10-11  Search: 读写分离  点击:(295)  评论:(0)  加入收藏
浅谈读写分离和几种常见的开源数据库中间件
最近学习了阿里资深技术专家李运华的架构设计关于读写分离的教程,颇有收获,总结一下。1 读写分离概述 基本架构图: 2 适用场景 读写分离不是银弹,并不是一有性能问题就上读写分...【详细内容】
2021-08-19  Search: 读写分离  点击:(1529)  评论:(0)  加入收藏
▌简易百科推荐
MySQL 核心模块揭秘
server 层会创建一个 SAVEPOINT 对象,用于存放 savepoint 信息。binlog 会把 binlog offset 写入 server 层为它分配的一块 8 字节的内存里。 InnoDB 会维护自己的 savepoint...【详细内容】
2024-04-03  爱可生开源社区    Tags:MySQL   点击:(10)  评论:(0)  加入收藏
MySQL 核心模块揭秘,你看明白了吗?
为了提升分配 undo 段的效率,事务提交过程中,InnoDB 会缓存一些 undo 段。只要同时满足两个条件,insert undo 段或 update undo 段就能被缓存。1. 关于缓存 undo 段为了提升分...【详细内容】
2024-03-27  爱可生开源社区  微信公众号  Tags:MySQL   点击:(17)  评论:(0)  加入收藏
MySQL:BUG导致DDL语句无谓的索引重建
对于5.7.23之前的版本在评估类似DDL操作的时候需要谨慎,可能评估为瞬间操作,但是实际上线的时候跑了很久,这个就容易导致超过维护窗口,甚至更大的故障。一、问题模拟使用5.7.22...【详细内容】
2024-03-26  MySQL学习  微信公众号  Tags:MySQL   点击:(14)  评论:(0)  加入收藏
从 MySQL 到 ByteHouse,抖音精准推荐存储架构重构解读
ByteHouse是一款OLAP引擎,具备查询效率高的特点,在硬件需求上相对较低,且具有良好的水平扩展性,如果数据量进一步增长,可以通过增加服务器数量来提升处理能力。本文将从兴趣圈层...【详细内容】
2024-03-22  字节跳动技术团队    Tags:ByteHouse   点击:(29)  评论:(0)  加入收藏
MySQL自增主键一定是连续的吗?
测试环境:MySQL版本:8.0数据库表:T (主键id,唯一索引c,普通字段d)如果你的业务设计依赖于自增主键的连续性,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不...【详细内容】
2024-03-10    dbaplus社群  Tags:MySQL   点击:(14)  评论:(0)  加入收藏
准线上事故之MySQL优化器索引选错
1 背景最近组里来了许多新的小伙伴,大家在一起聊聊技术,有小兄弟提到了MySQL的优化器的内部策略,想起了之前在公司出现的一个线上问题,今天借着这个机会,在这里分享下过程和结论...【详细内容】
2024-03-07  转转技术  微信公众号  Tags:MySQL   点击:(32)  评论:(0)  加入收藏
MySQL数据恢复,你会吗?
今天分享一下binlog2sql,它是一款比较常用的数据恢复工具,可以通过它从MySQL binlog解析出你要的SQL,并根据不同选项,可以得到原始SQL、回滚SQL、去除主键的INSERT SQL等。主要...【详细内容】
2024-02-22  数据库干货铺  微信公众号  Tags:MySQL   点击:(54)  评论:(0)  加入收藏
如何在MySQL中实现数据的版本管理和回滚操作?
实现数据的版本管理和回滚操作在MySQL中可以通过以下几种方式实现,包括使用事务、备份恢复、日志和版本控制工具等。下面将详细介绍这些方法。1.使用事务:MySQL支持事务操作,可...【详细内容】
2024-02-20  编程技术汇    Tags:MySQL   点击:(54)  评论:(0)  加入收藏
MySQL数据库如何生成分组排序的序号
经常进行数据分析的小伙伴经常会需要生成序号或进行数据分组排序并生成序号。在MySQL8.0中可以使用窗口函数来实现,可以参考历史文章有了这些函数,统计分析事半功倍进行了解。...【详细内容】
2024-01-30  数据库干货铺  微信公众号  Tags:MySQL   点击:(55)  评论:(0)  加入收藏
mysql索引失效的场景
MySQL中索引失效是指数据库查询时无法有效利用索引,这可能导致查询性能显著下降。以下是一些常见的MySQL索引失效的场景:1.使用非前导列进行查询: 假设有一个复合索引 (A, B)。...【详细内容】
2024-01-15  小王爱编程  今日头条  Tags:mysql索引   点击:(88)  评论:(0)  加入收藏
站内最新
站内热门
站内头条