前言
主从复制: 解决了Mysql的单点故障问题以及提高MySQL的整体服务性能.
读写分离: 解决的是数据库的读性能问题,分担主库的压力,提高系统的可用性和稳定性。
分库分表: 数据库分表可以解决单表海量数据的查询性能问题,分库可以解决单台数据库的并发访问压力问题。
主从复制在前篇文章中已经讲过,此篇主要讲解读写分离.
读写分离实现有哪几种方案?
- Atlas 奇虎360的一个开源中间代理,是在mysql官方mysql-proxy 0.8.2的基础上进行了优化,增加一些新的功能特性。 项目地址: https://github.com/Qihoo360/Atlas ,该项目当前已经有4.4k的点赞量。
-
Cobar 阿里提供的一个中间件,已经停止更新。项目地址:https://github.com/alibaba/cobar
- Mycat 前身就是cobar,活跃度比较高,完全使用java语言开发。 项目地址:https://github.com/MyCATApache/Mycat-Server ,该项目当前已经有8.3k的点赞量,但现在发现Myscat的下载地址 http://dl.mycat.org.cn/2.0/ 已经访问不了,感觉应该是不维护了。
- Mysql Proxy 一个轻量的中间代理,是官方提供的mysql中间件产品可以实现负载平衡,读写分离,failover等,依靠内部一个lua脚本实现读写语句的判断。项目地址: https://github.com/mysql/mysql-proxy ,该项目已经六七年没有维护了,官方也不建议应用于生成环境。
- MySQL Router 是MySQL官方提供的一个轻量级中间件, 最早是作为 MySQL-Proxy的替代方案出现的,官方推荐使用MySQLRouter. 项目地址: https://github.com/mysql/mysql-router
-
......
案例:Atlas配置读写分离
介绍
安装
# 下载rpm
wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm# 卸载rpm包
rpm -e Atlas# 安装rpm包
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
[root@vm log]# cd /usr/local/mysql-proxy
[root@vm mysql-proxy]# ll
总用量 0
drwxr-xr-x 2 root root 75 10月 16 17:44 bin
drwxr-xr-x 2 root root 22 10月 16 18:10 conf
drwxr-xr-x 3 root root 331 10月 16 17:44 lib
drwxr-xr-x 2 root root 38 10月 16 18:17 log
- bin 目录下放的都是可执行文件
-
encrypt是用来生成MySQL密码加密的,在配置的时候会用到
- mysql-proxy 是 MySQL 自己的读写分离代理
- mysql-proxyd 是 360 弄出来的,后面有个 “d” ,服务的启动、重启、停止。都是用他来执行的
-
- conf 目录下放的是配置文件
- test.cnf 只有一个文件,用来配置代理的,可以使用vim来编辑
- lib 目录下放的是一些包,以及Atlas的依赖
- log 目录下放的是日志,如报错等错误信息的记录
配置
进入bin目录,使用encrypt
来对数据库的密码进行加密,我的MySQL数据的用户名是root,密码是root,我需要对密码进行加密
[root@vm mysql-proxy]# /usr/local/mysql-proxy/bin/encrypt root
DAJnl8cVzy8=
配置Atlas,使用vim进行编辑
[root@vm mysql-proxy]# vim /usr/local/mysql-proxy/conf/test.cnf
进入后,可以在Atlas进行配置,360写的中文注释都很详细,根据注释来配置信息,其中比较重要,需要说明的配置如下:
这是用来登录到Atlas的管理员的账号与密码,与之对应的是“#Atlas监听的管理接口IP和端口”,也就是说需要设置管理员登录的端口,才能进入管理员界面,默认端口是2345,也可以指定IP登录,指定IP后,其他的IP无法访问管理员的命令界面。方便测试,我这里没有指定IP和端口登录。
# 管理接口的用户名
admin-username = hero
# 管理接口的密码
admin-password = hero
这是用来配置主数据的地址与从数据库的地址,这里配置的主数据库是130,从数据库是131
#Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses = 192.168.68.132:3306#Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
proxy-read-only-backend-addresses = 192.168.68.133:3306@1
这个是用来配置MySQL的账户与密码的,我的MySQL的用户是root,密码是root,刚刚使用Atlas提供的工具生成了对应的加密密码
#用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,下行的user1和user2为示例,将其替换为你的MySQL的用户名和加密密码!
pwds = root:DAJnl8cVzy8=
这是设置工作接口与管理接口的,如果ip设置的”0.0.0.0”就是说任意IP都可以访问这个接口,当然也可以指定IP和端口,方便测试我这边没有指定,工作接口的用户名密码与MySQL的账户对应的,管理员的用户密码与上面配置的管理员的用户密码对应
#Atlas监听的工作接口IP和端口
proxy-address = 0.0.0.0:1234#Atlas监听的管理接口IP和端口
admin-address = 0.0.0.0:2345
启动
[root@vm mysql-proxy]# /usr/local/mysql-proxy/bin/mysql-proxyd test start
使用如下命令,进入Atlas的管理模式 mysql -h127.0.0.1 -P2345 -uhero -phero
,能进去说明Atlas正常运行,因为它会把自己当成一个MySQL数据库,所以在不需要数据库环境的情况下,也可以进入到MySQL数据库模式。
[root@vm gorgor]# mysql -h127.0.0.1 -P2345 -uhero -phero
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.0.99-agent-adminCopyright (c) 2000, 2023, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
可以访问“help”表,来看MySQL管理员模式都能做些什么。可以使用SQL语句来访问
mysql> select * from help;
+----------------------------+---------------------------------------------------------+
| command | description |
+----------------------------+---------------------------------------------------------+
| SELECT * FROM help | shows this help |
| SELECT * FROM backends | lists the backends and their state |
| SET OFFLINE $backend_id | offline backend server, $backend_id is backend_ndx's id |
| SET ONLINE $backend_id | online backend server, ... |
| ADD MASTER $backend | example: "add master 127.0.0.1:3306", ... |
| ADD SLAVE $backend | example: "add slave 127.0.0.1:3306", ... |
| REMOVE BACKEND $backend_id | example: "remove backend 1", ... |
| SELECT * FROM clients | lists the clients |
| ADD CLIENT $client | example: "add client 192.168.1.2", ... |
| REMOVE CLIENT $client | example: "remove client 192.168.1.2", ... |
| SELECT * FROM pwds | lists the pwds |
| ADD PWD $pwd | example: "add pwd user:raw_password", ... |
| ADD ENPWD $pwd | example: "add enpwd user:encrypted_password", ... |
| REMOVE PWD $pwd | example: "remove pwd user", ... |
| SAVE CONFIG | save the backends to config file |
| SELECT VERSION | display the version of Atlas |
+----------------------------+---------------------------------------------------------+
16 rows in set (0.00 sec)mysql>
测试
主库user表数据
从库user表数据
在Atlas 执行查询user的数据发现,只能查出从库的数据,测试成功。
root@vm gorgor]# mysql -uroot -proot -P1234 --protocol=tcp -e"use gorgor; select * from user;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+--------+-----+---------------------+-------------+
| id | name | age | create_time | update_time |
+----+--------+-----+---------------------+-------------+
| 1 | gorgor | 30 | 2024-10-15 15:56:25 | NULL |
| 2 | fairy | 28 | 2024-10-15 17:47:56 | NULL |
+----+--------+-----+---------------------+-------------+
案例:MySQL Router配置读写分离【要求】
介绍
一个简单的MySQL Router部署图如下。
安装
wget http://ftp.iij.ad.jp/pub/db/mysql/Downloads/MySQL-Router/mysql-router-8.0.20-el7-x86_64.tar.gz
tar zxf mysql-router-8.0.20-el7-x86_64.tar.gz
配置
在mysql-router-8.0.20-el7-x86_64的conf文件下,创建mysqlrouter.conf并写入如下内容:
[logger]
level = INFO[routing:secondary]
bind_address = localhost
bind_port = 7001
destinations = 192.168.68.133:3306,192.168.68.134:3306
routing_strategy = round-robin[routing:primary]
bind_address = localhost
bind_port = 7002
destinations = 192.168.68.132:3306
routing_strategy = first-available
-
这里设置了两个路由策略:
-
通过本地7001端口,配置读取服务,循环连接到192.168.68.133:3306、192.168.68.134:3306三个实例,由round-robin路由策略所定义;
-
通过本地7002端口,配置写入服务,并设置首个可用策略。
-
首个可用策略:使用目标列表中的第一个可用服务器,即当192.168.68.132:3306可用时,所有7002端口的连接都转发到它,否则转发到后面的服务器,以此类推。Router不会检查数据包,也不会根据分配的策略或模式限制连接
-
-
-
因此应用程序可以据此确定将读写请求发送到不同的服务器。
-
本例中可将读请求发送到本地7001端口,将读负载均衡到两台服务器。同时将写请求发送到7002,这样只写一个服务器,从而实现的读写分离
启动
./mysqlrouter -c mysqlrouter.conf &
测试
mysql -uroot -proot -P7001 --protocol=tcp -e"select @@hostname"
由上可见,发送到本地7001端口的请求,被循环转发到两个服务器,而发送到本地7002端口的请求,全部被转发到192.168.68.132:3306。
routing_strategy是MySQL Router的核心选项,从8.0.4版本开始引入,当前有效值为first-available、next-available、round-robin、round-robin-with-fallback。
顾名思义,该选项实际控制路由策略,即客户端请求最终连接到哪个MySQL服务器实例。相对于以前版本mode的选项,routing_strategy选项更为灵活,并且不能同时设置routing_strategy和mode,静态路由的设置只能选择其中之一。对于InnoDB Cluster而言,该设置时可选的,缺省使用round-robin策略。
-
round-robin:每个新连接都以循环方式连接到下一个可用的服务器,以实现负载平衡。
-
round-robin-with-fallback:用于InnoDB Cluster。每个新的连接都以循环方式连接到下一个可用的secondary服务器。如果secondary服务器不可用,则以循环方式使用primary服务器。
-
first-available:新连接从目标列表路由到第一个可用服务器。如果失败,则使用下一个可用的服务器,如此循环,直到所有服务器都不可用为止。
-
next-available:与first-available类似,新连接从目标列表路由到第一个可用服务器。与first-available不同的是,如果一个服务器被标记为不可访问,那么它将被丢弃,并且永远不会再次用作目标。重启Router后,所有被丢弃服务器将再次可选。