news 2026/9/18 11:00:38

MySQL Router 8安装配置教程:实现读写分离与高可用路由

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MySQL Router 8安装配置教程:实现读写分离与高可用路由

做MySQL架构的同学应该都有过这种经历:业务侧需要高可用,主从切换了,应用却还连在旧主库上;或者想让读写分离,又不想在每个应用里写一堆数据源切换逻辑。与其在代码层反复造轮子,不如在前端挂一个统一的“入口”。MySQL Router 8就是干这个事的——它是MySQL官方出品的轻量级路由中间件,可以理解成数据库前面的“智能门卫”,负责转发连接、负载均衡,还能感知集群拓扑变化,读写分离和故障转移都能在中间件层面直接解决。

这篇笔记我直接基于在 Linux 环境里从零安装 MySQL Router 8 的完整过程来写,重点讲清楚每一步的来龙去脉,以及在生产环境实操中容易踩的坑。适合刚接触 MySQL 高可用架构的 DBA,也适合在应用层被数据库切换搞得头疼的开发同学。

1. 为什么需要单独装一个MySQL Router

1.1 架构演进的必然选择

在没有 Router 之前,应用连数据库的模式很直接:JDBC 连接串里写主库 IP,备份库或者从库只能靠应用层自己管理。一旦发生主从切换,DBA 得改 DNS,或者应用发布一次配置才能连到新主库;读写分离稍微一复杂,就得引入中间件团队自研,还得维护一堆哪吒闹海版本。这其实不是技术能力的问题,而是架构灵活性太差——数据库拓扑变了,应用也跟着变,两者耦合很深。

MySQL Router 8 要解决的就是这个耦合问题。它把应用和真实 MySQL 实例隔开,Router 维护了一张路由表,应用只感知一个虚拟地址(比如127.0.0.1:6446)。后面挂了几台 MySQL、谁是主谁是备、谁故障了需要摘掉,都由 Router 自己根据元数据动态处理。这个思路和 Nginx 做反向代理有点类似——数据库变了,应用无感知,架构弹性一下就上来了。

1.2 Router 8的核心价值不只是转发

很多同学以为 Router 就是个简单的 TCP 端口转发工具,装了发现它还会连接 MySQL 实例查询状态。其实 Router 8 的核心机制是“元数据感知”:它通过持久化连接到 MySQL 的元数据库,实时感知 InnoDB Cluster 或主从复制拓扑的变化。官方文档里管这条路叫 metadata cache,也就是说 Router 不是瞎转发的,它知道哪台机器健康、哪台机器权重高。

读写分离场景下,这个能力特别值钱。Router 8 支持把读流量分散到多个从库,从库负载不一样还能配置不同权重,应用端完全无感。主库故障时,只要集群完成了自动提升,Router 通过元数据感知到新主库地址,就会自动把写流量切过去,应用只需要在连接失败那一下做一次重连。这个特性在官方架构图里写得很清楚,实际跑通了,你才能体会“数据库拓扑对应用透明”这句话的分量。

2. 安装前要把这几件事想清楚

2.1 版本选择和下载渠道

MySQL Router 8 的版本号跟着 MySQL 8.0 走,比如 8.0.33、8.0.37。版本选择没那么多玄学,我个人的建议是:能用新不用旧,但别追最新,选当前 8.0 系列里成熟的小版本即可。因为它要配合 MySQL Shell、MySQL Server 8.0 做 InnoDB Cluster,版本差异太大会出现元数据协议不兼容的问题,所以如果服务器上已经建好了 Cluster,Router 版本尽量和 MySQL Server 大版本保持一致,都是 8.0.x 就没问题。

下载渠道有两条:官方 Yum/Apt 源和二进制通用包。如果服务器能访问官方源,用包管理器装最省事,依赖自动解决;如果内网环境没外网,就去官方下载页面先把二进制 tar 包拖到内网。我这次实操用的就是通用二进制包,解压即用,方便控制安装目录,也能看清楚 Router 内部有哪些组件。

2.2 先确认拓扑方式,再决定引导命令

Router 8 的配置方式有两种:一种是--bootstrap自动引导,直接对接 InnoDB Cluster,把整个 Router 配置文件自动生成;另一种是纯手工写配置文件,适合非 Cluster 的普通主从复制架构。这一步非常关键,因为很多人安装 Router 时会直接执行引导命令,结果发现自己的 MySQL 压根没有启用 MySQL Shell 的 AdminAPI,metadata 还没初始化,引导必然失败。

简单说:

后端架构推荐配置方式前提条件
InnoDB Clustermysqlrouter --bootstrapMySQL Server 8.0 + MySQL Shell 已创建 Cluster
普通主从复制手工编写 router.conf有主库、从库地址,明确读写分离策略
单机故障转移手工配置或用--bootstrap--directory想用 Router 隐藏真实端口

如果你只是想在测试环境快速跑一把,我建议先搭一个单机实例,再用 bootstrap 引导 Router 熟悉流程,别一上来就怼生产。

2.3 提前规划端口、账号和目录

安装之前,端口规划很重要。Router 默认的读写端口是6446,只读端口是6447,但生产环境容易和别的进程冲突,建议提前用ss -lntp | grep 6446查一下。另外 Router 在引导模式下还会在本地监听8440之类的管理端口,这些都需要在防火墙规则里提前放行。

账号方面,Router 需要一个能登录 MySQL 的用户来读取元数据,生产环境别直接用 root,建议单独建一个最小权限账号。官方推荐的姿势是从 MySQL Shell 里创建 Cluster 时自动生成的mysql_router1_user,但手工配置场景下,我们可以自己创建,只授权SELECTUPDATE权限即可。目录上,二进制包安装的 Router 默认会写到/opt/mysql-router,但它的配置、日志和运行状态文件分别在/etc//var/log//var/lib/下,后续排查问题要清楚这些路径,别到时候找不到日志干着急。

3. 完整安装与配置实操记录

3.1 二进制方式安装详解

我用 MySQL Router 8.0.37 在 CentOS 7.9 上走了一遍完整流程,这里把每一步都记录下来。

先去官方下载页面拿到 Linux Generic 二进制包的下载地址,然后服务器上执行:

wget -c https://cdn.mysql.com/Downloads/MySQLRouter/mysql-router-8.0.37-linux-glibc2.17-x86_64.tar.xz tar -xvf mysql-router-8.0.37-linux-glibc2.17-x86_64.tar.xz mv mysql-router-8.0.37-linux-glibc2.17-x86_64 /opt/mysql-router

解压完成后,先看一下目录结构,我习惯用tree -L 2 /opt/mysql-router,确认有binlibshare几个关键目录。Router 的二进制主体就是/opt/mysql-router/bin/mysqlrouter,你可以执行mysqlrouter --version验证一下是否可用,能看到版本号说明依赖库没问题。

按官方建议,Router 不应该以 root 身份直接跑,最好创建一个专用系统用户:

useradd -r -s /bin/false mysqlrouter

然后把安装目录属主改一下:

chown -R mysqlrouter:mysqlrouter /opt/mysql-router mkdir -p /var/log/mysqlrouter /var/lib/mysqlrouter chown -R mysqlrouter:mysqlrouter /var/log/mysqlrouter /var/lib/mysqlrouter

这一步看着繁琐,但对生产装态很有必要。Router 进程如果被入侵,至少不是 root 权限,能少很多麻烦。

3.2 用 bootstrap 引导配置,快速对接 InnoDB Cluster

接下来是重头戏。如果你的后端已经有一套 InnoDB Cluster,那么执行引导命令即可:

/opt/mysql-router/bin/mysqlrouter --bootstrap root@192.168.1.100:3306 --user=mysqlrouter --directory=/opt/mysql-router

这条命令会连接192.168.1.100:3306上的 MySQL 实例,检测是否在这个节点上启用了 Cluster 元数据。如果一切正常,Router 会自动生成mysqlrouter.confmysqlrouter.key等文件,还会打印出各个路由端口的配置概要。--directory把配置和日志都合并到一个目录里,方便测试环境一键清理。

需要特别注意账号权限。如果你直接拿 root 用户去 bootstrap,大概率会碰到提示说账号没有 admin 权限,或者元数据不是最新版本。官方推荐的姿势是先在 MySQL Shell 里用cluster.addRouter()注册 Router 账号,或者 bootstrap 时用 Cluster 管理员账号,Router 会自动创建后续连元数据库的专用账号。测试时可以图省事用 root,但生产环境务必在 MySQL Shell 里预先创建账号:

CREATE USER 'router_user'@'%' IDENTIFIED BY 'StrongPass123'; GRANT SELECT, UPDATE ON mysql_innodb_cluster_metadata.* TO 'router_user'@'%'; GRANT SELECT ON performance_schema.* TO 'router_user'@'%';

bootstrap 完成之后,Router 配置文件里已经自动写好了 metadata_cache 和 routing 两段配置,读写端口和只读端口也按默认规则生成了。此时可以直接后台启动测试:

/opt/mysql-router/bin/mysqlrouter --config=/opt/mysql-router/mysqlrouter.conf &

启动后看端口监听状态:

ss -lntp | grep -E '6446|6447'

如果能看到两个端口都在监听,说明核心路由功能已经上线了。

3.3 手工配置方案:不靠 Cluster 也能跑

如果说你的环境压根没建 Cluster,只是普通的 Master-Slave 主从复制,那 bootstrap 这一套就有点不匹配了。Router 8 也支持手工配置,我直接写了一份最基础的mysqlrouter.conf,这里做个示例:

[DEFAULT] logging_folder = /var/log/mysqlrouter runtime_folder = /var/lib/mysqlrouter config_folder = /opt/mysql-router [logger] level = INFO [routing:primary] bind_address = 0.0.0.0 bind_port = 6446 mode = read-write destinations = 192.168.1.100:3306,192.168.1.101:3306 routing_strategy = first-available [routing:secondary] bind_address = 0.0.0.0 bind_port = 6447 mode = read-only destinations = 192.168.1.102:3306,192.168.1.103:3306 routing_strategy = round-robin

注意看几个关键点:

  • [routing:primary][routing:secondary]是配置块的名字,可以任意命名,但建议读写分离语义用 primary/secondary 区分。
  • mode = read-write表示这条路由接受写流量,read-only只接受读流量。Router 8 的read-only模式并不是简单的禁止写操作,如果你往只读端口发写 SQL,Router 会在 MySQL 协议层直接拦截并返回错误。
  • destinations可以写多个地址,Router 会根据routing_strategy做负载均衡。first-available倾向于把流量导给第一个健康实例,适合主从切换场景;round-robin适合把读流量分散到多个只读实例。

手工配置的好处是灵活,坏处是 Router 不会自动感知后端拓扑变化,主库从192.168.1.100切换到了192.168.1.101,你得手工改配置或者依赖外部脚本调用mysqlrouter --reload重新加载。所以,能用 Cluster 的场景还是建议优先 Cluster,Router 才能发挥出动态感知的优势。

3.4 用配置文件快速验证路由是否生效

配置写好后,先用以下命令验证配置语法:

/opt/mysql-router/bin/mysqlrouter --config=/opt/mysql-router/mysqlrouter.conf --validate

如果没有任何输出,说明配置是合法的。然后前台启动看日志:

/opt/mysql-router/bin/mysqlrouter --config=/opt/mysql-router/mysqlrouter.conf

看到日志里有Starting MySQL RouterListening on相关的行,就可以用 MySQL 客户端连一下试试:

mysql -h127.0.0.1 -P6446 -uroot -p

登录后执行:

SELECT @@port;

如果返回的是后端某个实例的实际端口(比如 3306),说明连接已经被正确路由到后端 MySQL 了。多连几次,SELECT @@server_uuid;会看到不同的值,说明负载均衡生效。

4. 作为系统服务托管,避免进程守护的坑

4.1 注册 systemd 服务实例

二进制方式启动 Router 非常灵活,但生产环境不可能靠命令行后续台跑,进程守护、开机自启都是必要诉求。CentOS 7+ 基本都是 systemd,单位文件可以这样写:

[Unit] Description=MySQL Router After=network.target [Service] User=mysqlrouter Group=mysqlrouter ExecStart=/opt/mysql-router/bin/mysqlrouter --config=/opt/mysql-router/mysqlrouter.conf Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target

把这个文件保存为/etc/systemd/system/mysqlrouter.service,然后:

systemctl daemon-reload systemctl enable mysqlrouter systemctl start mysqlrouter systemctl status mysqlrouter

需要注意一点,如果使用 bootstrap 生成的文件没有mysqlrouter.key属主为 root 的情况,系统服务跑在 mysqlrouter 用户下会因为访问权限不足启动失败。安装时我已经chown过了,但手工配置时很容易漏掉/var/lib/mysqlrouter目录的属主,启动前记得检查一遍:

ls -ld /var/lib/mysqlrouter /var/log/mysqlrouter /opt/mysql-router/mysqlrouter.conf

4.2 配置热加载与平滑重启

Router 8 支持配置热加载,修改mysqlrouter.conf之后不需要停止进程,只需要给进程发送一个 SIGHUP 信号。实际操作:

kill -HUP $(cat /var/lib/mysqlrouter/mysqlrouter.pid)

但要注意,并不是所有配置项都支持热加载,像监听端口、bind_address 这种核心网络配置改了,还是需要完整重启。为了安全起见,大改配置后我一般先kill -HUP看一眼日志有没有报错,再决定是否重启。这个习惯能减少很多不必要的连接中断,因为热加载失败 Router 会回滚配置,不会把后端连接全部断掉,但重启一定会打断所有活跃连接,业务侧的感觉非常明显。

4.3 多实例部署时的端口和日志隔离

如果你的环境需要多个 Router 实例,比如一组给业务A,一组给业务B,或者读写和只读流量要完全隔离,尽量不要在一个进程里塞多个[routing]块,而是用 systemd 的实例化服务来管理。配置文件按实例分开,服务名用模板:

[Unit] Description=MySQL Router instance %i After=network.target [Service] User=mysqlrouter Group=mysqlrouter ExecStart=/opt/mysql-router/bin/mysqlrouter --config=/etc/mysqlrouter/%i.conf Restart=on-failure [Install] WantedBy=multi-user.target

然后分别存放/etc/mysqlrouter/businessA.conf/etc/mysqlrouter/businessB.conf,启动时:

systemctl start mysqlrouter@businessA systemctl start mysqlrouter@businessB

每个实例监听不同端口、写不同日志,排障时互不干扰。端口分配上我习惯在一个 excel 表里统一登记,防止以后加实例时端口冲突,别笑,生产事故不少就是在这种小细节上翻车的。

5. 常遇到的问题和排障思路

5.1 bootstrap 报错:元数据不可用

最常见的问题出现在--bootstrap的时候,错误信息一般是:

ERROR: Error connecting to MySQL server at X.X.X.X:3306: Access denied for user 'root'@'X.X.X.X' (using password: YES)

或者:

ERROR: The MySQL metadata is not available for the account used for bootstrap.

前一个本质是账号密码或权限问题,检查连接串有没有写对,账号能不能远程登录;后一个说明当前实例压根没有初始化 InnoDB Cluster 元数据,或者元数据版本太老。要解决,先用 MySQL Shell 连上实例,执行:

var cluster = dba.getCluster(); console.log(cluster.status());

如果这一步都报错,说明你还没建 Cluster,那就老老实实用手工配置路线,或者先用 MySQL Shell 创建 Cluster 再回来 bootstrap。

5.2 配置没问题,端口却一直不监听

如果--validate通过、进程也在跑,但ss -lntp看不到端口,大概率是防火墙把端口拦了,或者 Router 只绑定了 IPv6 的某个地址。前者用firewall-cmd --add-port=6446/tcp --permanent放行;后者需要检查bind_address配置,写成0.0.0.0听所有地址,写成::听所有 IPv6 地址。在纯 IPv4 环境下,bind_address 配置成::会让你客户端根本连不上,这是个非常隐蔽的坑。

5.3 连接被拒绝但日志没报明显错误

有一次我帮同事排查,Router 进程活着、端口也监听,但客户端连接总是超时。最后发现是destinations里写的主机名无法解析。Router 启动时不会立刻去解析 destinations 里的域名,只有客户端的连接进来后,它才会去连接后端,如果 DNS 解析失败,连接就一直在重试。所以在配置里我建议一律写 IP,或者确保/etc/hosts里有对应解析,别过度依赖 DNS,否则生产上会莫名多出很多疑难杂症。

5.4 读写分离后,只读端口出现“写操作被拦截”

之前有同事反馈,应用通过只读端口执行INSERT居然不报错,数据还真的写进去了。原因是他把mode写成了read-write,导致只读端口实际上也是读写端口。这个不是 Router 的 bug,而是配置语义理解不到位。手工配置时[routing:secondary]mode必须明确写成read-only,Router 才会在协议层拦截非读操作。用集群bootstrap自动生成时一般不会犯这个错,但手工配置就特别容易翻车。

5.5 日志文件刷得太快,磁盘告警

Router 默认日志级别是 INFO,如果后端 MySQL 实例频繁重启,Router 会反复重新连接,日志瞬间膨胀。生产环境我一般把级别调成 WARNING,只在需要排查问题时临时改成 INFO/DEBUG,排查完再调回来。日志轮转方面,Router 自身没有内置 logrotate 配置,建议在/etc/logrotate.d/mysqlrouter加一个:

/var/log/mysqlrouter/*.log { daily rotate 7 compress delaycompress missingok notifempty copytruncate }

这样能防止日志把磁盘吃满,避免一个中间件进程拖垮整个数据库服务器。

6. 安装配置之后的几点真实体会

整个过程走完,我最大的感受是 MySQL Router 8 的安装并不难,难的是把它放到整个架构里理解清楚。它不是一个孤立的软件,而是 InnoDB Cluster 高可用方案里的连接层,少了它,Cluster 的故障转移只能做到数据库层面,应用侧依然会连接中断。有了它,应用只认端口,数据库再怎么折腾都与应用无关。

我实际操作中还有两个小技巧值得分享。第一个是连接测试时别用root,建一个专用应用账号,这样通过 Router 的端口连接后端实例时,权限模型和生产完全一致,能提前暴露授权问题。第二个是安装完成后一定要把 Router 的数据目录、日志目录纳入备份和监控体系,它虽然不存业务数据,但它的配置文件变了,意味着整个高可用拓扑的入口变了,这种变更不给监控,出问题只能靠事后翻记录。

另外,Router 8 默认的routing_strategy在不同模式下行为差异很大,测试环境建议把round-robinfirst-availableround-robin-with-fallback都试一遍,用mysql -e "select @@port;"循环压一下,观察流量分布是否符合预期。这个验证动作最多十分钟,但它能让你对 Router 的调度策略有非常直观的感知,后面调优心里就有底了。

这篇文章里的配置路径和命令,大方向对绝大多数 Linux 发行版都适用,细节上Yum 安装和二进制安装会有些不同,但底层原理一致。如果你正在搞 InnoDB Cluster,或者刚接手一套用 Router 做读写分离的业务,把上面几个场景吃透,基本就能应对日常的安装和运维需求了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 10:59:07

训练集、验证集、测试集怎么划分?避开数据泄漏的坑

刚开始接触机器学习,或者已经用YOLO这类框架跑过几个模型的朋友,对“训练集、测试集、验证集”这三个词肯定不陌生。但说实话,很多人对它们的理解停留在“训练集用来学,测试集用来考”这个层面,真到自己划分数据、调参…

作者头像 李华
网站建设 2026/9/18 10:57:25

TM影像地质解译实战指南:从波段组合到岩性识别

简介:本资源是一份面向地质类专业本科生及考研学生的《遥感地质学》核心复习资料,聚焦遥感基本原理、地质解译方法与典型应用难点,助力系统梳理课程重点、高效备考。文件为单个PDF文档(1.52MB),内容完整覆盖…

作者头像 李华
网站建设 2026/9/18 10:56:59

Unity资源管理三大认知断层与真机崩溃根因分析

1. 项目概述:为什么Unity资源管理总在“爆内存”和“掉帧”之间反复横跳?你有没有遇到过这样的场景:刚把一个2K贴图拖进Unity工程,编辑器卡顿三秒;Build出包后发现APK体积暴涨80MB,但实际运行时内存占用又飙…

作者头像 李华
网站建设 2026/9/18 10:56:02

电商数据库设计实战:SQL Server+ER模型+数据流图

1. 这不是“画几张图交作业”,而是让系统真正跑起来的数据库骨架“网络购物管理系统数据库设计”——看到这八个字,很多刚学完《数据库原理》的同学第一反应是:不就是画个ER图、建几张表、写几个CREATE TABLE语句吗?我带过三届毕业…

作者头像 李华
网站建设 2026/9/18 10:55:17

前端颜色治理体系:HEX/RGB/十进制/英文名四格式协同实践

1. 为什么一张“颜色代码速查表”在前端开发中比你想象的更重要前端开发里,颜色从来不是“挑个好看的”那么简单。我带过三届校招新人,几乎每届都有人把#FF6B6B直接写死在 CSS 里,结果上线后设计师突然说:“这个珊瑚红饱和度偏高了…

作者头像 李华
网站建设 2026/9/18 10:53:59

数据结构与算法分析期末考试复盘:考点精讲与备考策略

1. 写在前面:这门课为什么让人又爱又恨从2022年12月考场走出来的时候,我脑子里的第一个念头不是"考得怎么样",而是"这半年总算没白熬"。说实话,西电网信院的《数据结构与算法分析》在全校计算机相关课程里都属…

作者头像 李华