MySQL Router是MySQL官方提供的一个轻量级中间件,它在应用程序与MySQL服务器之间提供透明的路由服务。
MySQL Router主要功能
- 负载均衡:MySQL Router能够分析前端应用的请求,并将其转发给后端DB服务器处理,从而实现数据库的负载均衡。这有助于在多个数据库服务器之间分配负载,提高系统的整体性能和响应速度。
- 高可用性和故障转移:MySQL Router支持高可用性和故障转移功能。当集群中的某个MySQL服务器发生故障时,Router会自动将应用程序的连接转移到其他可用的数据库服务器上,确保业务连续性。
- 读写分离:MySQL Router支持读写分离功能,可以根据配置将读请求和写请求分发到不同的数据库服务器上。这有助于提高系统的读性能和写性能,并减少单个服务器的负载。
- 透明性:对前端应用层来说,MySQL Router是透明的。应用层不需要知道Router的存在,也不需要修改代码来适应Router。应用层只需将MySQL Router当作一个正常的MySQL实例来使用即可。
下载MySQL Router
wget https://downloads.mysql.com/archives/get/p/41/file/mysql-router-community-8.0.37-1.el8.x86_64.rpm
复制
安装MySQL Router
[root@GreatSQL01 bin]# rpm -ivh mysql-router-community-8.0.37-1.el8.x86_64.rpm warning: mysql-router-community-8.0.37-1.el8.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID a8d3785c: NOKEY Verifying... ################################# [100%] Preparing... ################################# [100%] Updating / installing... 1:mysql-router-community-8.0.37-1.e################################# [100%]
复制
初始化MySQL Router
MySQL Router第一次启动时要先初始化
参数解释参数 :
--bootstrap
表示开始初始化参数
GreatSQL@192.168.116.41:3306
是MGR服务专用账号
--user=mysqlrouter
是运行mysqlrouter进程的系统用户名
[root@GreatSQL01 bin]# mysqlrouter --bootstrap GreatSQL@192.168.116.41:3306 --user=mysqlrouter
Please enter MySQL password for GreatSQL:
# Bootstrapping system MySQL Router 8.0.37 (MySQL Community - GPL) instance...
- Creating account(s) (only those that are needed, if any)
- Verifying account (using it to run SQL queries that would be run by Router)
- Storing account in keyring
- Adjusting permissions of generated files
- Creating configuration /etc/mysqlrouter/mysqlrouter.conf
Existing configuration backed up to '/etc/mysqlrouter/mysqlrouter.conf.bak'
# MySQL Router configured for the InnoDB Cluster 'MGR1'
After this MySQL Router has been started with the generated configuration
$ /etc/init.d/mysqlrouter restart
or
$ systemctl start mysqlrouter
or
$ mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf
InnoDB Cluster 'MGR1' can be reached by connecting to:
## MySQL Classic protocol
- Read/Write Connections: localhost:6446
- Read/Only Connections: localhost:6447
## MySQL X protocol
- Read/Write Connections: localhost:6448
- Read/Only Connections: localhost:6449
复制
如果想自定义名字和目录,还可以在初始化时自行指定 --name
和 --directory
选项,这样可以实现在同一个服务器上部署多个Router实例。
启动MySQL Router
[root@GreatSQL01 ~]# systemctl start mysqlrouter
[root@GreatSQL01 ~]# ps -ef | grep mysqlrouter
mysqlro+ 40655 1 1 08:29 ? 00:00:00 /usr/bin/mysqlrouter
root 40684 40627 0 08:29 pts/0 00:00:00 grep --color=auto mysqlrouter
[root@GreatSQL01 ~]# netstat -lntp | grep mysqlrouter
tcp 0 0 0.0.0.0:6449 0.0.0.0:* LISTEN 40655/mysqlrouter
tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN 40655/mysqlrouter
tcp 0 0 0.0.0.0:6446 0.0.0.0:* LISTEN 40655/mysqlrouter
tcp 0 0 0.0.0.0:6447 0.0.0.0:* LISTEN 40655/mysqlrouter
tcp 0 0 0.0.0.0:6448 0.0.0.0:* LISTEN 40655/mysqlrouter
[root@GreatSQL01 ~]#
复制
可以看到 mysqlrouter 服务正常启动了。
解读MySQL Router配置文件
mysqlrouter 初始化时自动生成的配置文件是 /etc/mysqlrouter/mysqlrouter.conf
,主要是关于R/W、RO不同端口的配置,例如:
[root@GreatSQL01 ~]# cat /etc/mysqlrouter/mysqlrouter.conf
# File automatically generated during MySQL Router bootstrap
[DEFAULT]
name=system #定义了这个配置文件的名称为“system”。
user=mysqlrouter #指定运行MySQL Router的用户为“mysqlrouter”。
keyring_path=/var/lib/mysqlrouter/keyring #定义了密钥环的存储路径。
master_key_path=/etc/mysqlrouter/mysqlrouter.key #指定了主密钥文件的路径。
connect_timeout=5 #设置了连接超时时间为5秒。
read_timeout=30 #设置了读取超时时间为30秒。
dynamic_state=/var/lib/mysqlrouter/state.json #定义了动态状态信息的存储路径。
client_ssl_cert=/var/lib/mysqlrouter/router-cert.pem #指定了客户端SSL证书的路径。
client_ssl_key=/var/lib/mysqlrouter/router-key.pem #指定了客户端SSL密钥的路径。
client_ssl_mode=PREFERRED #设置了客户端SSL模式为“PREFERRED”,表示优先使用SSL连接。
server_ssl_mode=AS_CLIENT #设置了服务器SSL模式为“AS_CLIENT”,表示服务器的SSL设置与客户端一致。
server_ssl_verify=DISABLED #禁用了服务器SSL验证。
unknown_config_option=error #当遇到未知的配置选项时,将其视为错误。
[logger]
level=INFO #设置了日志级别为“INFO”。
[metadata_cache:bootstrap]
cluster_type=gr #指定集群类型为Group Replication。
router_id=1 #为Router指定了一个唯一标识符。
user=mysql_router1_pzoskfc3eb5l #用于连接MySQL服务器的用户。
metadata_cluster=MGR1 #指定了元数据集群的名称。
ttl=0.5 #设置了元数据缓存的生存时间(TTL)为0.5秒。
auth_cache_ttl=-1 #设置了认证缓存的TTL
auth_cache_refresh_interval=2 #设置了认证缓存的刷新间隔。
use_gr_notifications=0 #禁用了对Group Replication通知的使用。
[routing:bootstrap_rw] #配置MySQL传统连接读写
bind_address=0.0.0.0 #绑定了所有可用的网络接口。
bind_port=6446 #指定了Router监听的端口。
destinations=metadata-cache://MGR1/?role=PRIMARY #定义了目标MySQL服务器的位置,使用了metadata-cache协议。
routing_strategy=first-available #设置了路由策略,如“first-available”和“round-robin-with-fallback”。
protocol=classic #指定了使用的协议,如“classic”和“x”。
[routing:bootstrap_ro] #配置MySQL传统连接只读
bind_address=0.0.0.0 #绑定了所有可用的网络接口。
bind_port=6447 #指定了Router监听的端口。
destinations=metadata-cache://MGR1/?role=SECONDARY #定义了目标MySQL服务器的位置,使用了metadata-cache协议。
routing_strategy=round-robin-with-fallback #设置了路由策略,如“first-available”和“round-robin-with-fallback”。
protocol=classic #指定了使用的协议,如“classic”和“x”。
[routing:bootstrap_x_rw] #配置MySQL X协议读写
bind_address=0.0.0.0 #绑定了所有可用的网络接口。
bind_port=6448 #指定了Router监听的端口。
destinations=metadata-cache://MGR1/?role=PRIMARY #定义了目标MySQL服务器的位置,使用了metadata-cache协议。
routing_strategy=first-available #设置了路由策略,如“first-available”和“round-robin-with-fallback”。
protocol=x #指定了使用的协议,如“classic”和“x”。
[routing:bootstrap_x_ro] #配置MySQL X协议只读
bind_address=0.0.0.0 #绑定了所有可用的网络接口。
bind_port=6449 #指定了Router监听的端口。
destinations=metadata-cache://MGR1/?role=SECONDARY #定义了目标MySQL服务器的位置,使用了metadata-cache协议。
routing_strategy=round-robin-with-fallback #设置了路由策略,如“first-available”和“round-robin-with-fallback”。
protocol=x #指定了使用的协议,如“classic”和“x”。
[http_server] #定义了HTTP服务器的配置
port=8443 #设置了HTTP服务器监听的端口。
ssl=1 #启用了SSL。
ssl_cert=/var/lib/mysqlrouter/router-cert.pem #指定了SSL证书的路径
ssl_key=/var/lib/mysqlrouter/router-key.pem #指定了SSL密钥的路径
[http_auth_realm:default_auth_realm] #http认证配置
backend=default_auth_backend
method=basic
name=default_realm
[rest_router]
require_realm=default_auth_realm
[rest_api]
[http_auth_backend:default_auth_backend]
backend=metadata_cache
[rest_routing]
require_realm=default_auth_realm
[rest_metadata_cache]
require_realm=default_auth_realm
[root@GreatSQL01 ~]#
复制
可以根据需要自行修改绑定的IP地址和端口,也可以在初始化时指定 --conf-base-port
选项自定义初始端口号。
确认读写分离效果
通过登录MySQL Router的6446端口看是否能登录MGR集群的primary节点
[root@GreatSQL01 ~]# mysql -h192.168.116.41 -u GreatSQL -p -P6446
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 61089
Server version: 8.0.32-26 GreatSQL, Release 26, Revision a68b3034c3d
Copyright (c) 2021-2024 GreatDB Software Co., Ltd
Copyright (c) 2009-2024 Percona LLC and/or its affiliates
Copyright (c) 2000, 2024, 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.
(Sat Oct 12 16:29:16 2024)[GreatSQL@GreatSQL][(none)]>SELECT MEMBER_ID,MEMBER_ROLE FROM performance_schema.replication_group_members;
+--------------------------------------+-------------+
| MEMBER_ID | MEMBER_ROLE |
+--------------------------------------+-------------+
| 20121e3a-7e37-11ef-9e5a-000c296335ba | PRIMARY |
| 5fa2fefd-7e37-11ef-9e13-000c2927509d | SECONDARY |
| 6f8dd4a8-7e37-11ef-bf56-000c29807526 | SECONDARY |
+--------------------------------------+-------------+
3 rows in set (0.00 sec)
(Sat Oct 12 16:29:36 2024)[GreatSQL@GreatSQL][(none)]>SELECT @@server_uuid;
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| 20121e3a-7e37-11ef-9e5a-000c296335ba |
+--------------------------------------+
1 row in set (0.00 sec)
(Sat Oct 12 16:29:48 2024)[GreatSQL@GreatSQL][(none)]>
复制
通过登录MySQL Router的6447端口看是否能登录MGR集群的SECONDARY节点
[root@GreatSQL01 ~]# mysql -h192.168.116.41 -u GreatSQL -p -P6447
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 252
Server version: 8.0.32-26 GreatSQL, Release 26, Revision a68b3034c3d
Copyright (c) 2021-2024 GreatDB Software Co., Ltd
Copyright (c) 2009-2024 Percona LLC and/or its affiliates
Copyright (c) 2000, 2024, 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.
(Sat Oct 12 16:37:21 2024)[GreatSQL@GreatSQL][(none)]>SELECT MEMBER_ID,MEMBER_ROLE FROM performance_schema.replication_group_members;
+--------------------------------------+-------------+
| MEMBER_ID | MEMBER_ROLE |
+--------------------------------------+-------------+
| 20121e3a-7e37-11ef-9e5a-000c296335ba | PRIMARY |
| 5fa2fefd-7e37-11ef-9e13-000c2927509d | SECONDARY |
| 6f8dd4a8-7e37-11ef-bf56-000c29807526 | SECONDARY |
+--------------------------------------+-------------+
3 rows in set (0.08 sec)
(Sat Oct 12 16:37:44 2024)[GreatSQL@GreatSQL][(none)]>SELECT @@server_uuid;
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| 5fa2fefd-7e37-11ef-9e13-000c2927509d |
+--------------------------------------+
1 row in set (0.01 sec)
(Sat Oct 12 16:37:55 2024)[GreatSQL@GreatSQL][(none)]>
复制
确认只读负载均衡效果
MySQL Router连接读写节点(Primary节点)默认的策略是 first-available,即只连接第一个可用的节点。Router连接只读节点(Secondary节点)默认的策略是 round-robin-with-fallback,会在各个只读节点间轮询。
保持6447端口原有的连接不退出,继续新建到6447端口的连接,查看 server_uuid,这时应该会发现读取到的是其他只读节点的值,因为 mysqlrouter 的读负载均衡机制是在几个只读节点间自动轮询。在默认的 round-robin-with-fallback 策略下,只有当所有只读节点都不可用时,只读请求才会打到PRIMARY节点上。
确认故障自动转移功能
接下来模拟PRIMARY节点宕机或切换时,mysqlrouter 也能实现自动故障转移。
先通过MySQL Router登录primary节点
[root@GreatSQL01 ~]# mysql -h192.168.116.41 -u GreatSQL -p -P6446
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 62874
Server version: 8.0.32-26 GreatSQL, Release 26, Revision a68b3034c3d
Copyright (c) 2021-2024 GreatDB Software Co., Ltd
Copyright (c) 2009-2024 Percona LLC and/or its affiliates
Copyright (c) 2000, 2024, 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.
(Sat Oct 12 16:43:20 2024)[GreatSQL@GreatSQL][(none)]>SELECT MEMBER_ID,MEMBER_ROLE FROM performance_schema.replication_group_members;
+--------------------------------------+-------------+
| MEMBER_ID | MEMBER_ROLE |
+--------------------------------------+-------------+
| 20121e3a-7e37-11ef-9e5a-000c296335ba | PRIMARY |
| 5fa2fefd-7e37-11ef-9e13-000c2927509d | SECONDARY |
| 6f8dd4a8-7e37-11ef-bf56-000c29807526 | SECONDARY |
+--------------------------------------+-------------+
3 rows in set (0.01 sec)
(Sat Oct 12 16:44:01 2024)[GreatSQL@GreatSQL][(none)]>SELECT @@server_uuid;
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| 20121e3a-7e37-11ef-9e5a-000c296335ba |
+--------------------------------------+
1 row in set (0.00 sec)
复制
重启primary节点GreatSQL
systemctl restart greatsql
复制
查看重启primary节点GreatSQL过程中,刚刚连接信息的变化
(Sat Oct 12 16:44:07 2024)[GreatSQL@GreatSQL][(none)]>SELECT MEMBER_ID,MEMBER_ROLE FROM performance_schema.replication_group_members;
ERROR 2013 (HY000): Lost connection to MySQL server during query
No connection. Trying to reconnect...
Connection id: 287
Current database: *** NONE ***
+--------------------------------------+-------------+
| MEMBER_ID | MEMBER_ROLE |
+--------------------------------------+-------------+
| 5fa2fefd-7e37-11ef-9e13-000c2927509d | PRIMARY |
| 6f8dd4a8-7e37-11ef-bf56-000c29807526 | SECONDARY |
+--------------------------------------+-------------+
2 rows in set (0.30 sec)
(Sat Oct 12 16:45:00 2024)[GreatSQL@GreatSQL][(none)]>SELECT MEMBER_ID,MEMBER_ROLE FROM performance_schema.replication_group_members;
+--------------------------------------+-------------+
| MEMBER_ID | MEMBER_ROLE |
+--------------------------------------+-------------+
| 5fa2fefd-7e37-11ef-9e13-000c2927509d | PRIMARY |
| 6f8dd4a8-7e37-11ef-bf56-000c29807526 | SECONDARY |
+--------------------------------------+-------------+
2 rows in set (0.00 sec)
(Sat Oct 12 16:45:12 2024)[GreatSQL@GreatSQL][(none)]>SELECT MEMBER_ID,MEMBER_ROLE FROM performance_schema.replication_group_members;
+--------------------------------------+-------------+
| MEMBER_ID | MEMBER_ROLE |
+--------------------------------------+-------------+
| 20121e3a-7e37-11ef-9e5a-000c296335ba | SECONDARY |
| 5fa2fefd-7e37-11ef-9e13-000c2927509d | PRIMARY |
| 6f8dd4a8-7e37-11ef-bf56-000c29807526 | SECONDARY |
+--------------------------------------+-------------+
3 rows in set (0.00 sec)
(Sat Oct 12 16:45:18 2024)[GreatSQL@GreatSQL][(none)]>SELECT @@server_uuid;
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| 5fa2fefd-7e37-11ef-9e13-000c2927509d |
+--------------------------------------+
1 row in set (0.00 sec)
(Sat Oct 12 16:52:31 2024)[GreatSQL@GreatSQL][(none)]>
复制
这就实现了自动故障转移。
至此,利用MySQL Router配合GreatSQL构建一套支持读写分离、读负载均衡以及故障自动转移的MGR集群就部署完毕了。
参考文章链接:https://greatsql.cn/docs/8.0.32-26/8-mgr/5-mgr-readwrite-split.html