基于Maxscale中间件实现Mysql读写分离实战
wptr33 2024-11-24 22:27 19 浏览
环境介绍:
?CentOS 7.5
?Mysql 5.7.29
?Mysql主服务器:192.168.2.128
?Mysql从服务器:192.168.2.129
?Mysql代理服务器:192.168.2.130
?客户端服务器:192.168.2.132
读写分离概述:
1、什么是读写分离?
?读写分离的基本原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。一般来说都是通过 主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy)来提升数据库的并发负载能力这样的方案来进行部署与实施的。
2、为什么要读写分离?
?因为数据库的“写”操作是比较耗时的,但是数据库的“读”操作耗时非常短,所以读写分离,解决的是数据库的写入影响了查询的效率(即读操作比写操作多的场景)。
3、什么时候读写分离?
?数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用,利用数据库主从同步,可以减少数据库压力,提高性能。
4、主从复制与读写分离:
?在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。
5.读写分离的好处:
?1)分摊服务器压力, 减轻主服务器的工作压力,提高机器的系统处理效率。
?2)增加冗余,提高服务可用性,当一台数据库服务器宕机后可以调整另外一台从库以最快速度恢复服务。
?读写分离适用于读远比写多的场景,如果有一台服务器,当select很多时,update和delete会被这些select访问中的数据堵塞,等待select结束,并发性能并不高,而主从只负责各自的写和读,极大程度的缓解X锁和S锁争用。
共享锁[S锁] -->读锁
排他锁[X锁] -->写锁
读锁是共享的,或者说是相互不阻塞的。
写锁是排他的,一个写锁会阻塞其他的写锁和读锁。
6.实现Mysql读写分离常见的2种方式:
1)基于程序代码内部实现
?在代码中根据select 、insert进行路由分类,这类方法也是目前生产环境下应用最广泛的。优点是性能较好,因为程序在代码中实现,不需要增加额外的硬件开支,缺点是需要开发人员来实现,运维人员无从下手。
2) 基于中间件(代理层)实现
?代理一般介于应用服务器和数据库服务器之间,代理数据库服务器接收到应用服务器的请求后根据判断后转发到后端数据库。如:Mycat、Mysql-proxy、Maxscale...
构建思路:
?1.配置Mysql主从同步
?这里就不讲述Mysql主从同步的配置了,上面一篇文章里面讲得很详细,大家可以去看一下。
?2.部署Maxscale服务
?Maxscale下载:https://downloads.mariadb.com/MaxScale/
1.下载并安装Maxscale服务
[root@test3 ~]# wget https://downloads.mariadb.com/MaxScale/2.1.2/rhel/7/x86_64/maxscale-2.1.2-1.rhel.7.x86_64.rpm
[root@test3 ~]# ll maxscale-2.1.2-1.rhel.7.x86_64.rpm
-rw-r--r-- 1 root root 17333732 3月 31 2017 maxscale-2.1.2-1.rhel.7.x86_64.rpm
[root@test3 ~]# yum -y install maxscale-2.1.2-1.rhel.7.x86_64.rpm
...
已安装:
maxscale.x86_64 0:2.1.2-1
作为依赖被安装:
gnutls.x86_64 0:3.3.29-9.el7_6 nettle.x86_64 0:2.7.1-8.el7 trousers.x86_64 0:0.3.14-2.el7
完毕!
[root@test3 ~]# max (连续按Tab两次) //maxscale服务的管理命令
maxadmin maxavrocheck maxbinlogcheck maxkeys maxpasswd
[root@test3 ~]# ll /etc/maxscale.cnf //配置文件
-rw-r--r-- 1 root root 1560 6月 9 16:40 /etc/maxscale.cnf
-----下面是备份maxscale服务的配置文件-----
[root@test3 ~]# mkdir maxscale
[root@test3 ~]# cp /etc/maxscale.cnf /root/maxscale/
[root@test3 ~]# ll /root/maxscale/
总用量 4
-rw-r--r-- 1 root root 1560 6月 9 16:44 maxscale.cnf
2.修改Maxscale配置文件
[root@test3 ~]# vim /etc/maxscale.cnf
[maxscale]
threads=auto //线程数,auto表示自动根据cpu的性能创建多少个线程
...
[server1] //定义数据库服务器的主机名
type=server
address=192.168.2.128 //master(主库)主机的ip地址
port=3306
protocol=MySQLBackend
...
[server2] //定义数据库服务器的主机名
type=server
address=192.168.2.129 //slave(从库)主机ip地址
port=3306
protocol=MySQLBackend
...
[MySQL Monitor] //定义要监视的服务器及监控的用户
type=monitor
module=mysqlmon
servers=server1,server2 /主、从数据库的主机名
user=maxscalemon //监控用户名
password=123qqq...A //监控用户密码
monitor_interval=10000 //监控的时间间隔,单位为毫秒
...
#[Read-Only-Service] //读负载均衡模块,由于读写分离模块也能实现读负载均衡,因此注释掉该模块
#type=service
#router=readconnroute
#servers=server1
#user=myuser
#password=mypwd
#router_options=slave
...
[Read-Write-Service] //定义读写分离服务及路由用户
type=service
router=readwritesplit
servers=server1,server2 //主、从数据库的主机名
user=maxscalerouter //路由用户名
password=123qqq...A //路由用户密码
max_slave_connections=100% //多少比例的从服务器被使用,默认就是所有从服务器都提供读服务
...
[MaxAdmin Service] //定义管理服务
type=service
router=cli
#[Read-Only-Listener] //注释该模块
#type=listener
#service=Read-Only-Service
#protocol=MariaDBClient
#port=4008
[Read-Write-Listener] //定义读写分离服务的端口号
type=listener
service=Read-Write-Service
protocol=MySQLClient
port=4006
[MaxAdmin Listener] //定义管理服务的端口号
type=listener
service=MaxAdmin Service
protocol=maxscaled
socket=default
port=4016
3.在主数据库上创建授权用户
[root@localhost ~]# mysql -uroot -p123qqq...A
...
mysql> grant replication slave,replication client on *.* to maxscalemon@"%" identified by "123qqq...A";
//创建监控用户授权
mysql> grant select on mysql.* to maxscalerouter@"%" identified by "123qqq...A";
//创建路由用户授权
mysql> select user,host from mysql.user where user like "maxscale%";
+----------------+------+
| user | host |
+----------------+------+
| maxscalemon | % |
| maxscalerouter | % |
+----------------+------+
4.在从数据库上查看主库上授权的用户是否同步
[root@test2 ~]# mysql -uroot -p123qqq...A
...
mysql> select user,host from mysql.user where user like "maxscale%";
+----------------+------+
| user | host |
+----------------+------+
| maxscalemon | % |
| maxscalerouter | % |
+----------------+------+
5.在代理服务器上启动Maxscale服务
[root@test3 ~]# maxscale -f /etc/maxscale.cnf //启动maxscale服务
[root@test3 ~]# ss -antulp | grep maxscale
tcp LISTEN 0 128 :::4006 :::* users:(("maxscale",pid=2732,fd=11))
//查询读写分离端口号4006是否启用
tcp LISTEN 0 128 :::4016 :::* users:(("maxscale",pid=2732,fd=12))
//查询管理服务端口号4016是否启用
测试配置:
1.在代理服务器本机访问Maxscale管理服务
?-maxadmin -uadmin -pmariadb -P管理服务端口号
[root@test3 ~]# maxadmin -uadmin -pmariadb -P4016
MaxScale> list servers //显示监控信息(集群状态)
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server | Address | Port | Connections | Status
-------------------+-----------------+-------+-------------+--------------------
server1 | 192.168.2.128 | 3306 | 0 | Master, Running
server2 | 192.168.2.129 | 3306 | 0 | Slave, Running
-------------------+-----------------+-------+-------------+--------------------
//详细信息server1为主服务器,server2为从服务器,running为开启状态,ip以及主机端口
2.在主服务器上新增数据及授权连接用户
[root@localhost ~]# mysql -uroot -p123qqq...A
mysql> create database gamedb; //创建gamedb库
mysql> create table gamedb.a(id int); //在gamedb库创建名为a的表
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| gamedb |
| mysql |
| performance_schema |
| sys |
| test |
| zabbix |
+--------------------+
mysql> use gamedb;
mysql> show tables;
+------------------+
| Tables_in_gamedb |
+------------------+
| a |
+------------------+
mysql> grant select,insert on gamedb.* to tom66@"%" identified by "123qqq...A";
//授权连接用户tom66,权限为select、insert
mysql> select user,host from mysql.user where user like "tom66";
+-------+------+
| user | host |
+-------+------+
| tom66 | % |
+-------+------+
3.客户端132连接代理服务器130访问数据
?-mysql -h服务器地址 -P读写分离服务端口号 -u用户名 -p密码
[root@VOS3000 ~]# mysql -P4006 -h192.168.2.130 -utom66 -p123qqq...A
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| gamedb |
+--------------------+
mysql> use gamedb;
mysql> show tables;
+------------------+
| Tables_in_gamedb |
+------------------+
| a |
+------------------+
验证代理服务器读写分离功能:
?-在从数据库服务器上添加新数据,主数据库服务器上并不会同步这些数据,客户端访问代理服务器访问数据时能看到从服务新添加的数据,说明读数据时是读取的从数据库服务器上的数据。(验证读写分离中的从“读”)
?-在代理服务器上添加新数据,到主数据库服务器上查看新数据写入情况,说明写数据时是在主服务上写。(验证读写分离中的主“写”)
1.在从数据库服务器上添加新数据
?在从服务器上新增数据,并不会同步到主数据库服务器上。
[root@test2 ~]# mysql -uroot -p123qqq...A
...
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| gamedb |
| mysql |
| performance_schema |
| sys |
| test |
| zabbix |
+--------------------+
mysql> use gamedb;
mysql> show tables;
+------------------+
| Tables_in_gamedb |
+------------------+
| a |
+------------------+
mysql> insert into gamedb.a values(55);
mysql> select * from gamedb.a;
+------+
| id |
+------+
| 55 |
+------+
2.在主数据库服务器上查看数据
[root@localhost ~]# mysql -uroot -p123qqq...A
...
mysql> select * from gamedb.a;
Empty set (0.00 sec) //没有数据
?可以看到主数据库服务器上并没有新增数据。
3.客户端访问代理服务器查看数据
[root@VOS3000 ~]# mysql -P4006 -h192.168.2.130 -utom66 -p123qqq...A
...
mysql> select * from gamedb.a;
+------+
| id |
+------+
| 55 |
+------+
?可以看到客户端通过代理服务器访问到了之前在从数据库服务器上新增的数据,所以说明代理服务器读数据是读取的从服务器上的数据。
4.客户端连接代理服务器新增数据
[root@VOS3000 ~]# mysql -P4006 -h192.168.2.130 -utom66 -p123qqq...A
...
mysql> select * from gamedb.a; //读取到从服务器上之前新增的数据
+------+
| id |
+------+
| 55 |
+------+
mysql> insert into gamedb.a values(88);
mysql> insert into gamedb.a values(100);
mysql> select * from gamedb.a; //查看新增的数据
+------+
| id |
+------+
| 55 |
| 88 |
| 100 |
+------+
5.主数据库服务器查看客户端通过代理服务新增的数据
[root@localhost ~]# mysql -uroot -p123qqq...A
...
mysql> select * from gamedb.a;
+------+
| id |
+------+
| 88 |
| 100 |
+------+
?可以看到刚才通过客户端连接代理服务器新增的两条数据全部都写入到了主数据库服务器中并同步到从服务器上。
6.从数据库服务器上查看数据同步情况
[root@test2 ~]# mysql -uroot -p123qqq...A
...
mysql> select * from gamedb.a;
+------+
| id |
+------+
| 55 |
| 88 |
| 100 |
+------+
总结:
?上面的实验说明代理服务器实现了读写分离功能。
?? -写数据时,代理服务器会在主数据库服务器上写。(在主数据库服务器上写入的数据会同步到从数据库服务器上)
?? -读数据时,代理服务器会在从数据库服务器上读。
如果你觉得这篇文章还不错,就请动动你的发财手为本文点赞-评论-转发吧,因为这将是我持续输出更多优质文章的最强动力,谢谢!
相关推荐
- Python自动化脚本应用与示例(python办公自动化脚本)
-
Python是编写自动化脚本的绝佳选择,因其语法简洁、库丰富且跨平台兼容性强。以下是Python自动化脚本的常见应用场景及示例,帮助你快速上手:一、常见自动化场景文件与目录操作...
- Python文件操作常用库高级应用教程
-
本文是在前面《Python文件操作常用库使用教程》的基础上,进一步学习Python文件操作库的高级应用。一、高级文件系统监控1.1watchdog库-实时文件系统监控安装与基本使用:...
- Python办公自动化系列篇之六:文件系统与操作系统任务
-
作为高效办公自动化领域的主流编程语言,Python凭借其优雅的语法结构、完善的技术生态及成熟的第三方工具库集合,已成为企业数字化转型过程中提升运营效率的理想选择。该语言在结构化数据处理、自动化文档生成...
- 14《Python 办公自动化教程》os 模块操作文件与文件夹
-
在日常工作中,我们经常会和文件、文件夹打交道,比如将服务器上指定目录下文件进行归档,或将爬虫爬取的数据根据时间创建对应的文件夹/文件,如果这些还依靠手动来进行操作,无疑是费时费力的,这时候Pyt...
- python中os模块详解(python os.path模块)
-
os模块是Python标准库中的一个模块,它提供了与操作系统交互的方法。使用os模块可以方便地执行许多常见的系统任务,如文件和目录操作、进程管理、环境变量管理等。下面是os模块中一些常用的函数和方法:...
- 21-Python-文件操作(python文件的操作步骤)
-
在Python中,文件操作是非常重要的一部分,它允许我们读取、写入和修改文件。下面将详细讲解Python文件操作的各个方面,并给出相应的示例。1-打开文件...
- 轻松玩转Python文件操作:移动、删除
-
哈喽,大家好,我是木头左!Python文件操作基础在处理计算机文件时,经常需要执行如移动和删除等基本操作。Python提供了一些内置的库来帮助完成这些任务,其中最常用的就是os模块和shutil模块。...
- Python 初学者练习:删除文件和文件夹
-
在本教程中,你将学习如何在Python中删除文件和文件夹。使用os.remove()函数删除文件...
- 引人遐想,用 Python 获取你想要的“某个人”摄像头照片
-
仅用来学习,希望给你们有提供到学习上的作用。1.安装库需要安装python3.5以上版本,在官网下载即可。然后安装库opencv-python,安装方式为打开终端输入命令行。...
- Python如何使用临时文件和目录(python目录下文件)
-
在某些项目中,有时候会有大量的临时数据,比如各种日志,这时候我们要做数据分析,并把最后的结果储存起来,这些大量的临时数据如果常驻内存,将消耗大量内存资源,我们可以使用临时文件,存储这些临时数据。使用标...
- Linux 下海量文件删除方法效率对比,最慢的竟然是 rm
-
Linux下海量文件删除方法效率对比,本次参赛选手一共6位,分别是:rm、find、findwithdelete、rsync、Python、Perl.首先建立50万个文件$testfor...
- Python 开发工程师必会的 5 个系统命令操作库
-
当我们需要编写自动化脚本、部署工具、监控程序时,熟练操作系统命令几乎是必备技能。今天就来聊聊我在实际项目中高频使用的5个系统命令操作库,这些可都是能让你效率翻倍的"瑞士军刀"。一...
- Python常用文件操作库使用详解(python文件操作选项)
-
Python生态系统提供了丰富的文件操作库,可以处理各种复杂的文件操作需求。本教程将介绍Python中最常用的文件操作库及其实际应用。一、标准库核心模块1.1os模块-操作系统接口主要功能...
- 11. 文件与IO操作(文件io和网络io)
-
本章深入探讨Go语言文件处理与IO操作的核心技术,结合高性能实践与安全规范,提供企业级解决方案。11.1文件读写11.1.1基础操作...
- Python os模块的20个应用实例(python中 import os模块用法)
-
在Python中,...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
因果推断Matching方式实现代码 因果推断模型
-
git pull命令使用实例 git pull--rebase
-
面试官:git pull是哪两个指令的组合?
-
git 执行pull错误如何撤销 git pull fail
-
git pull 和git fetch 命令分别有什么作用?二者有什么区别?
-
git fetch 和git pull 的异同 git中fetch和pull的区别
-
git pull 之后本地代码被覆盖 解决方案
-
还可以这样玩?Git基本原理及各种骚操作,涨知识了
-
git命令之pull git.pull
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)