Mysql 读写分离

article/2025/9/25 7:02:48

一、介绍

1.什么是读写分离

读写分离的基本原理是将数据库读和写操作分散到不同的节点上Mysql 的读写分离需要建立在主从复制基础之上,Master 数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而 Slave 数据库处理SELECT查询操作,Master 数据库的写操作导致的变更通过主从复制架构同步到集群中的 Slave 数据库中。

2.应用场景

因为数据库的 "写" 操作耗时远远大于 "读" 操作,读写分离可以增大数据库访问的并发量,从而缓解数据库的压力。

数据库不一定要读写分离。如果程序使用数据库较多时,在更新少,查询多的情况下会考虑使用,减少数据库压力,提高性能。而且,数据库也有其它优化方案,分布式数据库、负载均衡、搜索引擎、增加缓存服务器等,都是解决方法。

3.复制延迟

读写分离建立在主从复制的基础之上,当有写操作到达 Master 时,Mater 与 Slave 之间的数据同步,延迟可能达到 1 秒,如果有大量数据同步,延迟 1 分钟也是有可能的。复制延迟会带来一个问题:如果业务服务器将数据写入到数据库 Master 后,立刻(1 秒内)进行读取,此时读操作访问的是 Slave,由于数据还未同步过来,业务上就可能出现问题。例如,用户刚注册完后立刻登录,服务器提示他 "你还没有注册",而用户明明刚才已经注册成功了。

解决主从复制延迟有几种常见的方法:

1)写操作后的读操作指定发给 Master

例如,注册账号完成后,登录时读取账号的读操作也发给 Master。

2)读取 Slave 失败后再读一次 Master

这就是通常所说的 "二次读取",二次读取和业务无绑定,只需要对底层数据库访问的 API 进行封装即可,实现代价较小,不足之处在于如果有很多二次读取,将大大增加 Master 的读操作压力。例如,黑客暴力破解账号,会导致大量的二次读取操作,Master 可能顶不住读操作的压力从而崩溃。

3)关键业务读写操作全部指向 Master,非关键业务采用读写分离

例如,对于一个用户管理系统来说,注册 + 登录的业务读写操作全部访问 Master,用户的介绍、爱好、等级等业务,可以采用读写分离,因为即使用户改了自己的自我介绍,在查询时却看到了自我介绍还是旧的,业务影响与不能登录相比就小很多,还可以忍受。

4.实现方式

程序代码封装中间件封装

程序代码封装指在代码中抽象一个数据访问层,实现读写操作分离和数据库服务器连接的管理。

中间件封装指的是独立一套系统出来,实现读写操作分离和数据库服务器连接的管理。中间件对业务服务器提供 SQL 兼容的协议,业务服务器无须自己进行读写分离。对于业务服务器来说,访问中间件和访问数据库没有区别,事实上在业务服务器看来,中间件就是一个数据库服务器。其基本架构是:

下面使用 mysql-proxy 来实现 mysql 的读写分离;


二、部署

1.基本环境

    master 服务器:Centos-7.6.1810、MariaDB-5.5.60、192.168.3.29slave 服务器:Centos-7.6.1810、MariaDB-5.5.60、192.168.3.30mysql-proxy 服务器:Centos-7.6.1810、lua-5.3.5、mysql—proxy-0.8.5、192.168.3.28

基于上篇已配置完成的主从复制架构,在此基础上,配置 mysql-proxy 区分读和写的调度即可;

2.安装 Lua

Lua 是一个小巧的脚本语言。Lua 由标准 C 编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。一个完整的 Lua 解释器不过 200k,在目前所有脚本引擎中,Lua 的速度是最快的。这一切都决定了 Lua 是作为嵌入式脚本的最佳选择。

下载地址:http://www.lua.org/download.html

1)获取 Lua 部署包

[root@mysql-proxy ~]# curl -R -O http://www.lua.org/ftp/lua-5.3.5.tar.gz% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed
100  296k  100  296k    0     0   182k      0  0:00:01  0:00:01 --:--:--  182k
[root@mysql-proxy ~]# ls
lua-5.3.5.tar.gz

2)安装 Lua 需要的依赖包

[root@mysql-proxy ~]# yum -y install gcc* gcc-c++* autoconf* automake* zlib* libxml* ncurses-devel* libmcrypt* libtool* flex* pkgconfig* libevent* glib* readline-devel
...

3)编译安装 Lua

[root@mysql-proxy ~]# tar -zxvf lua-5.3.5.tar.gz  -C /usr/local
...
[root@mysql-proxy ~]# cd /usr/local/lua-5.3.5
[root@mysql-proxy lua-5.3.5]# make linux
...
[root@mysql-proxy lua-5.3.5]# make install
...
[root@mysql-proxy lua-5.3.5]# export LUA_CFLAGS="-I/usr/local/include" LUA_LIBS="-L/usr/local/lib -llua -ldl" LDFLAGS="-lm"

3.安装 mysql-proxy

1)获取安装包

[root@mysql-proxy ~]# wget https://cdn.mysql.com/archives/mysql-proxy/mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz
[root@mysql-proxy ~]# ls
lua-5.3.5.tar.gz  mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz

2)解压即可

[root@mysql-proxy ~]# tar -zxvf mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz -C /usr/local
...
[root@mysql-proxy ~]# cd /usr/local
[root@mysql-proxy local]# mv mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit/ mysql-proxy

4.配置读写分离

1)修改 Lua 脚本

[root@mysql-proxy mysql-proxy]# cp /usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua ./
[root@mysql-proxy mysql-proxy]# vim rw-splitting.lua
## 修改 min_idle_connections 和 max_idle_connections 值为1--- config
--
-- connection pool
if not proxy.global.config.rwsplit thenproxy.global.config.rwsplit = {min_idle_connections = 1,max_idle_connections = 1,is_debug = false}
end

2)启动mysql-proxy,并指明启动参数(Mater 地址,Slave 地址、Lua脚本路径)

[root@mysql-proxy mysql-proxy]# cd bin
[root@mysql-proxy bin]# ./mysql-proxy --proxy-read-only-backend-addresses=192.168.3.30:3306 --proxy-backend-addresses=192.168.3.29:3306 --proxy-lua-script=/usr/local/mysql-proxy/rw-splitting.lua &

3)登录 Mater 数据库,创建读写分离的数据库链接账户

[root@mysql-master ~]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 7
Server version: 5.5.60-MariaDB MariaDB ServerCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MariaDB [(none)]> grant all on *.* to 'proxy'@'192.168.3.28' identified by 'proxy';   
Query OK, 0 rows affected (0.01 sec)

5.测试

可使用任意 mysql 数据库客户端登录 proxy@192.168.3.28 账户,进行读写分离测试;

下面在 windows 上使用 Navicat Premium 测试:

1)登录

 连接名 随便起,端口 选4040( mysql-proxy 进程监听的端口);

2)初始数据如下

3) 插入一条数据并查看

上面 insert 的语句 其实是在 Master 数据库中操作的,而 select 语句 是在 Slave 数据库完成的,只是我们还看不出效果,下面在 Slave 数据库中停止 slave 服务,然后再次测试。

4)登录 Slave 数据库,停止 slave 服务

[root@mysql-slave ~]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 5.5.60-MariaDB MariaDB ServerCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.01 sec)

5)再次插入数据并查看

插入数据成功;

查看表, 刚刚插入的数据不存在,是因为 insert 的操作,是在 Master 数据库中完成的,而select 的操作是在 Slave 数据库中进行的,由于刚刚我们停止了 Slave 数据库的 slave 服务,导致插入 Master 数据库的数据无法同步到 Slave 数据库中,所以查不到数据;

6)进一步验证

登录 Master 数据库,查看刚刚插入的数据存在;

[root@mysql-master ~]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 12
Server version: 5.5.60-MariaDB MariaDB ServerCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MariaDB [(none)]> use school;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
MariaDB [school]> select * from student;
+------+--------+------+
| id   | name   | age  |
+------+--------+------+
|    1 | syztoo |   19 |
|    2 | syz    |   22 |
|    3 | too    |   33 |
+------+--------+------+
3 rows in set (0.00 sec)

登录 Slave 数据库,查看刚刚插入的数据不存在:

[root@mysql-slave ~]# mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 13
Server version: 5.5.60-MariaDB MariaDB ServerCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MariaDB [(none)]> use school;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
MariaDB [school]> select * from student;
+------+--------+------+
| id   | name   | age  |
+------+--------+------+
|    1 | syztoo |   19 |
|    2 | syz    |   22 |
+------+--------+------+
2 rows in set (0.00 sec)

查看 Slave 状态未运行:

MariaDB [school]> show slave status\G
*************************** 1. row ***************************Slave_IO_State: Master_Host: 192.168.3.29Master_User: slave30Master_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000002Read_Master_Log_Pos: 3034Relay_Log_File: mariadb-relay-bin.000007Relay_Log_Pos: 1711Relay_Master_Log_File: mysql-bin.000002Slave_IO_Running: NoSlave_SQL_Running: NoReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 3034Relay_Log_Space: 3433Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 29
1 row in set (0.00 sec)

开启 slave 服务,再次查看数据已存在:

MariaDB [school]> start slave;
Query OK, 0 rows affected (0.00 sec)MariaDB [school]> select * from student;
+------+--------+------+
| id   | name   | age  |
+------+--------+------+
|    1 | syztoo |   19 |
|    2 | syz    |   22 |
|    3 | too    |   33 |
+------+--------+------+
3 rows in set (0.00 sec)

基于 Mariadb 的 读写分离部署成功!!!

 


http://chatgpt.dhexx.cn/article/iWKr1bHD.shtml

相关文章

MySQL读写分离

目录 一、读写分离 1. 工作原理 2.为什么要读写分离 3.什么时候要读写分离 4.主从复制与读写分离 5.mysql支持的复制类型 二、MySQL 读写分离方式 1.基于程序代码内部实现 2.基于中间代理层实现 三、实验:读写分离(主从复制基础上&…

Mysql读写分离的四种方案

一、读写分离介绍 1、做读写分离的原因 数据库写入效率要低于读取效率,一般系统中数据读取频率高于写入频率,单个数据库实例在写入的时候会影响读取性能,这是做读写分离的原因。 2、MySQL读写分离的基础 实现方式主要基于mysql的主从复制&…

JMETER接口测试_用户登录(MD5加密)

JMETER接口测试—— 用户登录(密码MD5加密) 1)给整个线程组,添加全局变量 TestPlan–>线程组–>右键–>ADD Config Element -->User Defined Variables。 全局变量的意思:整个线程中,该变量设定的值,所有…

Jmeter接口测试之常用断言

在接口测试中,我们需要检查请求处理结果是否正确。当请求的响应状态码为200,是否表时接口功能正常呢?显然是不正确的。 响应状态为200,只能表明服务处理了你的请求,同时进行了结果返回;但并不能代表处理的…

jmeter接口测试传参问题汇总

1、 在Jmeter接口测试json传参时,number类型的参数不能为空,例如: {title: "测试标题",languageTypeId: ,content: "测试内容"}当这样数字类型传参为空时,jmeter就会报错如下: {&quo…

Jmeter接口测试之响应断言

一、断言是什么 1. 断言的作用 断言用于对采样器执行结果的检查,并在同一范围内的每个采样器之后进行处理。如果要对某个采样器进行断言,直接将断言添加到采样器的子集即可。 2. 为什么要用断言? JMeter以及Postman等接口测试工具&#xff…

用户认证授权---Jmeter接口测试

用户根据用户名,密码,验证码登录系统。要测试系统登录接口及查看用户所受权限,首先测试获取验证码接口,获取验证码,再测试登录接口,最后进行权限接口测试。 一、获取验证码 将返回信息中img通过data:image…

jmeter 接口测试快速入门

jmeter是一款小巧,轻便、开源的性能测试工具,它也可以很方便的进行接口测试。 下面我就带大家学习下jmeter接口测试。 目录 1.准备工作: 2.第一个接口测试走起! 3.再来一个稍微复杂一点的接口——获取短信验证码接口&#xf…

JMeter接口测试___参数化方法

一、JMeter添加参数的常用方法 1.Get请求 2.Post请求二、JMeter常用参数化的方式 1.用户参数(User Parameter) 2.用户自定的变量(User Defined Variables) 3.CSV数据文件设置(CSV Data Set C…

Jmeter 接口测试中的签名处理

签名机制:服务端接口为了防止非法请求,要求接口的入参需要传入一个签名字段sign,签名字段是按照一定的规则对接口的业务参数进行加密后得到的。在测试此类接口时,必须传入业务数据,和对应的签名数据,才能正…

jmeter接口测试教程以及接口测试流程详解

一、Jmeter简介 Jmeter是由Apache公司开发的一个纯Java的开源项目,即可以用于做接口测试也可以用于做性能测试。 Jmeter具备高移植性,可以实现跨平台运行。 Jmeter可以实现分布式负载。 Jmeter采用多线程,允许通过多个线程并发取样或通过独…

jmeter接口测试教程

在日常工作中,尤其是做接口测试时,我们最经常用到的两个工具,就是Jmeter和postman。今天,我们主要是讲一讲Jmeter在接口测试这一块的一些方式方法。内容比较多,大家可以收藏一下,以后慢慢学。 1&#xff0…

JMeter接口测试及接口登陆压力测试

脚本: https://mp.csdn.net/mp_download/manage/download/UpDetailed 1.JMeter接口测试 查看别的博主内容时发现了个开放的API,可以作为练习使用 https://wanandroid.com/blog/show/2 jmeter基本操作 操作步骤 1.启动jmeter 2.在"测试计划&…

Jmeter接口测试-获取token

相信大家都知道在开展接口测试或者是接口面试的过程中,我们会发现很多接口需要依赖前面的接口,需要我们动态从前面的接口返回中提取数据,也就是我们通常说的关联。关联通俗来讲就是把上一次请求的返回内容中的部分截取出来保存为参数&#xf…

8、jmeter接口测试教程(简单案例)

以登录、查询接口为案例 注意: 1、如果找不到接口,可以通过F12进行抓包, 具体步骤如下: (1)选择任意浏览器(模式选择谷歌内核即可); (2)按F12键&a…

Jmeter接口测试流程详解

1、jmeter简介 Jmeter是由Apache公司开发的java开源项目,所以想要使用它必须基于java环境才可以; Jmeter采用多线程,允许通过多个线程并发取样或通过独立的线程对不同的功能同时取样。 2、jmeter安装 首先需要安装jdk(最好是最…

全网最细节的jmeter接口测试教程以及接口测试流程详解

文章目录 一、Jmeter简介 二、Jmeter安装 三、设置Jmeter语言为中文环境 四、Jmeter主要元件 五、Jmeter元件的作用域和执行顺序 六、Jmeter进行接口测试流程 七、Jmeter进行接口测试流程步骤详解 八、Jmeter接口测试必定用到的扩展阅读 一、Jmeter简介 Jmeter是由Apa…

Jmeter接口测试——使用教程(上)

目录 前言 一、Jmeter简介 二、Jmeter-http接口脚本 Jmeter-http接口脚本添加header: Jmeter-http接口脚本添加cookie: 三、Jmeter-webservice脚本 四、Jmeter-参数化 1、Jmeter参数化的方式有三种 2、用户定义的变量 3、函数生成器 4、从文件…

如何使用jmeter进行接口测试?jmeter接口测试流程是怎样的

前言 我们学习自动化测试都会用到不同的工具,那么今天笔者呢,想给大家聊聊Jmeter接口测试流程详解,废话不多说直接进入正题。 一、jmeter简介 Jmeter是由Apache公司开发的java开源项目,所以想要使用它必须基于java环境才可以&am…

JMeter接口测试___接口关联

前言一、什么是接口关联?二、JMeter关联方法: 1.正则表达式提取器2.Json Extractor提取器3.边界值提取器总结 前言 关联的概念: 关联也称为串行参数或数据依赖。 在开展接口测试的过程中,我们会发现很…