基于 MaxScale 实现 MySQL 读写分离
在高并发 MySQL 场景中,读写分离是提升数据库性能的核心手段之一。MaxScale 作为 MariaDB 官方推出的开源中间件,凭借灵活的插件机制和对数据一致性的精准控制,成为实现 MySQL 读写分离的优质选择。本文将详细介绍 MaxScale 的工作原理、部署步骤及最佳实践,帮助运维人员快速搭建可靠的读写分离架构。
一、MaxScale 读写分离核心原理
MaxScale 实现 MySQL 读写分离的核心在于智能路由与数据一致性保障,其关键机制包括:
读写请求分流
通过readwritesplit
路由器插件,自动将写操作(如INSERT
、UPDATE
、DELETE
)路由至主库,读操作(如SELECT
)分发至从库,减轻主库压力。数据一致性控制
依托 MySQL 半同步复制,MaxScale 通过以下方式确保从库读取的数据有效性:- 延迟阈值控制:通过
max_slave_replication_lag
参数设定允许的最大主从延迟(如 1 秒),超过该阈值的从库将被排除在读请求路由之外; - 因果读取:配置
causal_reads=local
后,若从库延迟较高,MaxScale 会等待causal_reads_timeout
(默认 10 秒),超时后自动将请求路由至主库,避免读取过期数据。
- 延迟阈值控制:通过
故障容错
当所有从库延迟均超过阈值时,读请求将自动路由至主库,保证业务连续性(需注意主库负载压力)。
二、部署环境与拓扑规划
1. 环境说明
- 数据库架构:1 主 2 从半同步复制(MySQL 5.7+)
- MaxScale 版本:6.1.4(支持 MySQL 读写分离的稳定版本)
- 操作系统:CentOS 7
2. 节点拓扑
主机名 | IP 地址 | 角色 | 说明 |
---|---|---|---|
node4 | 10.186.63.88 | MaxScale 中间件 | 处理读写请求路由 |
node1 | 10.186.61.191 | MySQL 主库(Master) | 处理写操作,同步数据至从库 |
node2 | 10.186.61.192 | MySQL 从库(Slave) | 处理读操作 |
node3 | 10.186.63.64 | MySQL 从库(Slave) | 处理读操作 |
三、部署步骤详解
1. 后端 MySQL 环境准备
(1)配置主从半同步复制
确保主库已开启半同步复制,从库正常同步:
-- 主库验证半同步客户端数量(应为2,对应两个从库)
mysql> show global status like 'Rpl_semi_sync_master_clients';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| Rpl_semi_sync_master_clients | 2 |
+------------------------------+-------+-- 查看从库状态
mysql> show slave hosts;
+-----------+---------------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID |
+-----------+---------------+------+-----------+--------------------------------------+
| 737716692 | 10.186.61.192 | 3306 | 622227692 | d121bf0f-1922-11ed-86d9-02000aba3dc0 |
| 534997148 | 10.186.63.64 | 3306 | 622227692 | bb3d53a9-1940-11ed-a059-02000aba3f40 |
+-----------+---------------+------+-----------+--------------------------------------+
(2)创建 MaxScale 所需用户
路由用户:用于 MaxScale 连接数据库并路由请求
CREATE USER 'maxscale'@'%' IDENTIFIED BY '123'; GRANT SELECT ON mysql.* TO 'maxscale'@'%'; -- 需查询mysql库获取主从信息 GRANT SHOW DATABASES ON *.* TO 'maxscale'@'%';
监控用户:用于 MaxScale 监控主从状态
CREATE USER 'monitor'@'%' IDENTIFIED BY '123'; GRANT REPLICATION CLIENT ON *.* TO 'monitor'@'%'; -- 允许查看复制状态
2. 安装与配置 MaxScale
(1)安装依赖与 MaxScale
# 安装依赖包
yum -y install libcurl libaio openssl gnutls libatomic# 下载并解压安装包
wget https://dlm.mariadb.com/1864578/MaxScale/6.1.4/bintar/rhel/7/x86_64/maxscale-6.1.4.rhel.7.tar.gz
mkdir -p /data/maxscale
tar xf maxscale-6.1.4.rhel.7.tar.gz -C /data/maxscale --strip-components=1# 创建运行用户
groupadd maxscale
useradd -g maxscale maxscale
chown -R maxscale.maxscale /data/maxscale
(2)密码加密(安全加固)
MaxScale 需加密存储数据库用户密码,避免明文泄露:
# 生成加密密钥
/data/maxscale/bin/maxkeys /data/maxscale/var/lib/maxscale# 加密用户密码(以密码123为例)
/data/maxscale/bin/maxpasswd /data/maxscale/var/lib/maxscale/ 123
# 输出加密后的密码(示例):F270B97B3D4D37BC619EB02304A02C1456F41B05CF2D7E5F37BA48CC7646C2E4
(3)配置 MaxScale 核心文件(maxscale.cnf)
配置文件需定义服务器节点、监控模块、路由服务及监听器,路径为/data/maxscale/etc/maxscale.cnf
:
[maxscale]
threads=auto # 自动分配线程数# 后端MySQL服务器定义
[dbserv1]
type=server
address=10.186.61.191 # 主库IP
port=3306
protocol=MariaDBBackend[dbserv2]
type=server
address=10.186.61.192 # 从库1 IP
port=3306
protocol=MariaDBBackend[dbserv3]
type=server
address=10.186.63.64 # 从库2 IP
port=3306
protocol=MariaDBBackend# 主从监控模块
[Replication-Monitor]
type=monitor
module=mariadbmon # 监控主从复制状态的插件
servers=dbserv1, dbserv2, dbserv3
user=monitor # 监控用户
password=F270B97B3D4D37BC619EB02304A02C1456F41B05CF2D7E5F37BA48CC7646C2E4 # 加密后的密码
monitor_interval=2000ms # 监控间隔# 读写分离服务
[Read-Write-Service]
type=service
router=readwritesplit # 读写分离路由插件
servers=dbserv1, dbserv2, dbserv3
user=maxscale # 路由用户
password=F270B97B3D4D37BC619EB02304A02C1456F41B05CF2D7E5F37BA48CC7646C2E4 # 加密后的密码
max_slave_connections=2 # 每个从库最大连接数
master_accept_reads=false # 主库不处理读请求(除非从库不可用)
max_slave_replication_lag=1s # 允许的最大从库延迟
# causal_reads=local # 开启因果读取(按需启用)
# causal_reads_timeout=10 # 因果读取超时时间# 监听器(客户端连接入口)
[Read-Write-Listener]
type=listener
service=Read-Write-Service
protocol=MariaDBClient
port=33060 # MaxScale监听端口(区别于MySQL的3306)
3. 启动 MaxScale 服务
(1)创建系统服务文件
cat > /usr/lib/systemd/system/maxscale.service << 'EOF'
[Unit]
Description=MariaDB MaxScale Database Proxy
After=network.target[Service]
Type=forking
Restart=on-abort
User=maxscale
Group=maxscale
ExecStart=/data/maxscale/bin/maxscale --user=maxscale --basedir=/data/maxscale/ --config=/data/maxscale/etc/maxscale.cnf
TimeoutStartSec=120
LimitNOFILE=65535
RestartForceExitStatus=75[Install]
WantedBy=multi-user.target
EOF
(2)启动并验证服务
systemctl daemon-reload
systemctl start maxscale
systemctl enable maxscale # 开机自启# 检查服务状态
systemctl status maxscale
四、读写分离效果验证
1. 查看后端服务器状态
使用maxctrl
工具检查 MaxScale 识别的主从状态:
maxctrl list servers
预期输出(主库标记为Master
,从库为Slave
):
┌─────────┬───────────────┬──────┬─────────────┬─────────────────┐
│ Server │ Address │ Port │ Connections │ State │
├─────────┼───────────────┼──────┼─────────────┼─────────────────┤
│ dbserv1 │ 10.186.61.191 │ 3306 │ 1 │ Master, Running │
│ dbserv2 │ 10.186.61.192 │ 3306 │ 1 │ Slave, Running │
│ dbserv3 │ 10.186.63.64 │ 3306 │ 1 │ Slave, Running │
└─────────┴───────────────┴──────┴─────────────┴─────────────────┘
2. 验证读请求分发
通过 MaxScale 端口(33060)连接数据库,多次执行读操作,观察返回的主机名(需数据库开启hostname
系统变量):
# 连接MaxScale
mysql -umaxscale -p123 -h 10.186.63.88 -P 33060# 执行读操作(多次执行)
mysql> select @@hostname;
预期结果:读请求交替路由至 node2 和 node3(从库),证明读请求分发生效。
3. 验证写请求路由
执行写操作(如插入数据),检查主从数据同步情况:
-- 在MaxScale连接中执行写操作
mysql> insert into test.t values(1, 'test');-- 分别登录主库和从库,验证数据是否同步
-- 主库(node1)
mysql> select * from test.t; -- 应有新增记录-- 从库(node2)
mysql> select * from test.t; -- 应有新增记录(半同步复制确保同步)
五、最佳实践与注意事项
主库负载保护
当所有从库延迟超限时,读请求会全部路由至主库,可能导致主库过载。建议:- 合理设置
max_slave_replication_lag
(如业务允许可放宽至 3-5 秒); - 监控主库负载,必要时临时扩容从库。
- 合理设置
用户权限最小化
MaxScale 的maxscale
用户仅需SELECT
(mysql 库)和SHOW DATABASES
权限,monitor
用户仅需REPLICATION CLIENT
,避免过度授权。连接池优化
根据业务并发量调整max_slave_connections
和max_connections
参数,避免连接数不足或资源浪费。监控与告警
通过 MaxScale 的监控插件(如prometheus
)收集路由指标,设置主从延迟、连接数等关键指标的告警阈值。
总结
MaxScale 通过插件化设计实现了 MySQL 读写分离的灵活配置,尤其在数据一致性控制上表现出色。通过本文的部署步骤,可快速搭建 “1 主 2 从 + MaxScale” 架构,将读压力分流至从库,同时保障数据读取的有效性。实际应用中,需结合业务特性调整延迟阈值和连接参数,平衡性能与一致性,构建高可用的数据库服务。