Skip to content

MySQL ProxySQL 基于读写分离

什么是ProxySQL

ProxySQL是一个高性能、高可用的MySQL代理,支持读写分离、负载均衡、连接池管理和查询路由等功能。

读写分离原理

读写分离是指将数据库的读操作和写操作分离到不同的数据库实例上,以提高系统的整体性能和可用性。ProxySQL通过以下方式实现读写分离:

  1. 识别SQL语句类型(读/写)
  2. 将写操作路由到主库
  3. 将读操作路由到从库
  4. 支持多种读负载均衡算法
  5. 支持从库健康检查

部署架构

ProxySQL 基于读写分离的典型部署架构:

应用程序 → ProxySQL → 主库(写操作)
                    → 从库1(读操作)
                    → 从库2(读操作)
                    → 从库3(读操作)

安装 ProxySQL

1. 二进制安装

bash
# 下载 ProxySQL
wget https://github.com/sysown/proxysql/releases/download/v2.5.4/proxysql_2.5.4-debian11_amd64.deb

# 安装 ProxySQL
dpkg -i proxysql_2.5.4-debian11_amd64.deb

# 启动 ProxySQL
systemctl start proxysql

# 启用 ProxySQL 开机自启
systemctl enable proxysql

2. 源码编译安装

bash
# 克隆源码
git clone https://github.com/sysown/proxysql.git
cd proxysql

# 编译安装
make -j$(nproc)
make install

# 启动 ProxySQL
./src/proxysql

配置 ProxySQL

1. 连接 ProxySQL 管理接口

bash
# 连接 ProxySQL 管理接口
mysql -u admin -padmin -h 127.0.0.1 -P 6032 --prompt='ProxySQLAdmin> '

2. 添加 MySQL 服务器

sql
-- 添加主库
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight, max_connections) VALUES (10, 'master_host', 3306, 100, 100);

-- 添加从库
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight, max_connections) VALUES (20, 'slave1_host', 3306, 100, 100);
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight, max_connections) VALUES (20, 'slave2_host', 3306, 100, 100);
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight, max_connections) VALUES (20, 'slave3_host', 3306, 100, 100);

-- 加载配置到运行时
LOAD MYSQL SERVERS TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL SERVERS TO DISK;

3. 配置读写分离规则

sql
-- 添加读写分离规则
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply) VALUES (1, 1, '^SELECT.*FOR UPDATE$', 10, 1);
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply) VALUES (2, 1, '^SELECT', 20, 1);

-- 加载配置到运行时
LOAD MYSQL QUERY RULES TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL QUERY RULES TO DISK;

4. 配置用户认证

sql
-- 添加MySQL用户
INSERT INTO mysql_users (username, password, active, default_hostgroup) VALUES ('app_user', 'password', 1, 10);

-- 加载配置到运行时
LOAD MYSQL USERS TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL USERS TO DISK;

5. 配置监控用户

sql
-- 添加监控用户
INSERT INTO mysql_monitor_users (username, password) VALUES ('monitor_user', 'monitor_password');

-- 加载配置到运行时
LOAD MYSQL MONITOR USERS TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL MONITOR USERS TO DISK;

6. 配置主从复制监控

sql
-- 配置主从复制监控
UPDATE global_variables SET variable_value='monitor_user' WHERE variable_name='mysql-monitor_username';
UPDATE global_variables SET variable_value='monitor_password' WHERE variable_name='mysql-monitor_password';
UPDATE global_variables SET variable_value='2000' WHERE variable_name='mysql-monitor_connect_interval';
UPDATE global_variables SET variable_value='2000' WHERE variable_name='mysql-monitor_ping_interval';
UPDATE global_variables SET variable_value='2000' WHERE variable_name='mysql-monitor_read_only_interval';

-- 加载配置到运行时
LOAD MYSQL VARIABLES TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL VARIABLES TO DISK;

验证读写分离

1. 连接 ProxySQL 前端接口

bash
# 连接 ProxySQL 前端接口
mysql -u app_user -ppassword -h 127.0.0.1 -P 6033 --prompt='ProxySQLFront> '

2. 验证写操作

sql
-- 执行写操作
INSERT INTO test_table (column1, column2) VALUES ('value1', 'value2');

-- 查看主库是否有该数据
SELECT * FROM test_table WHERE column1 = 'value1';

3. 验证读操作

sql
-- 执行读操作
SELECT * FROM test_table;

-- 查看从库是否有该数据
SELECT * FROM test_table;

4. 查看 ProxySQL 统计信息

sql
-- 查看查询规则匹配统计
SELECT * FROM stats_mysql_query_rules;

-- 查看服务器状态
SELECT * FROM stats_mysql_servers;

-- 查看连接统计
SELECT * FROM stats_mysql_connection_pool;

高级配置

1. 配置连接池

sql
-- 配置连接池参数
UPDATE global_variables SET variable_value='1000' WHERE variable_name='mysql-max_connections';
UPDATE global_variables SET variable_value='100' WHERE variable_name='mysql-default_max_connections_per_group';
UPDATE global_variables SET variable_value='60000' WHERE variable_name='mysql-default_max_transaction_time';

-- 加载配置到运行时
LOAD MYSQL VARIABLES TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL VARIABLES TO DISK;

2. 配置负载均衡算法

sql
-- 配置负载均衡算法(轮询)
UPDATE mysql_servers SET load_balance_mode='ROUNDROBIN' WHERE hostgroup_id=20;

-- 配置负载均衡算法(权重)
UPDATE mysql_servers SET load_balance_mode='WEIGHTED' WHERE hostgroup_id=20;

-- 加载配置到运行时
LOAD MYSQL SERVERS TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL SERVERS TO DISK;

3. 配置从库健康检查

sql
-- 配置从库健康检查
UPDATE global_variables SET variable_value='true' WHERE variable_name='mysql-monitor_enabled';
UPDATE global_variables SET variable_value='3000' WHERE variable_name='mysql-monitor_read_only_timeout';

-- 加载配置到运行时
LOAD MYSQL VARIABLES TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL VARIABLES TO DISK;

4. 配置查询缓存

sql
-- 启用查询缓存
UPDATE global_variables SET variable_value='1' WHERE variable_name='mysql-query_cache_size_MB';

-- 加载配置到运行时
LOAD MYSQL VARIABLES TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL VARIABLES TO DISK;

故障处理

1. ProxySQL 无法启动

可能原因

  • 配置文件错误
  • 端口被占用
  • 权限问题

解决方案

  • 检查配置文件语法
  • 检查端口占用情况
  • 检查文件权限
  • 查看错误日志

2. 读写分离不工作

可能原因

  • 查询规则配置错误
  • 服务器状态异常
  • 用户权限问题

解决方案

  • 检查查询规则配置
  • 检查服务器状态
  • 验证用户权限
  • 查看 ProxySQL 日志

3. 从库延迟过高

可能原因

  • 主库写入压力大
  • 从库硬件性能不足
  • 网络延迟
  • 大事务

解决方案

  • 监控从库延迟
  • 配置延迟阈值,自动移除延迟过高的从库
  • 优化主库写入性能
  • 提升从库硬件配置

最佳实践

1. 监控与告警

  • 监控 ProxySQL 性能指标
  • 监控后端服务器状态
  • 监控查询规则匹配情况
  • 配置告警规则

2. 高可用性

  • 部署多个 ProxySQL 实例
  • 使用 Keepalived 实现 ProxySQL 高可用
  • 配置 ProxySQL 之间的同步

3. 安全性

  • 限制 ProxySQL 管理接口访问
  • 使用强密码
  • 启用 SSL/TLS 加密
  • 配置防火墙规则

4. 性能优化

  • 调整连接池参数
  • 优化查询规则
  • 配置适当的缓存
  • 定期清理日志

常见问题(FAQ)

Q1: ProxySQL 支持哪些负载均衡算法?

A1: ProxySQL 支持以下负载均衡算法:

  • ROUNDROBIN(轮询)
  • WEIGHTED(权重)
  • LEAST_CONNECTIONS(最少连接)
  • FASTEST_RESPONSE(最快响应)

Q2: 如何查看 ProxySQL 版本?

A2: 可以使用以下命令查看 ProxySQL 版本:

sql
SELECT version();

Q3: 如何配置 ProxySQL 日志?

A3: 可以通过以下方式配置 ProxySQL 日志:

sql
-- 配置日志级别
UPDATE global_variables SET variable_value='INFO' WHERE variable_name='proxysql_log_level';

-- 配置日志文件
UPDATE global_variables SET variable_value='/var/lib/proxysql/proxysql.log' WHERE variable_name='proxysql_log_file';

-- 加载配置到运行时
LOAD ADMIN VARIABLES TO RUNTIME;

-- 保存配置到磁盘
SAVE ADMIN VARIABLES TO DISK;

Q4: 如何备份 ProxySQL 配置?

A4: 可以通过以下方式备份 ProxySQL 配置:

bash
# 备份配置文件
cp /var/lib/proxysql/proxysql.db /backup/proxysql.db_$(date +%Y%m%d)

# 使用管理接口导出配置
mysql -u admin -padmin -h 127.0.0.1 -P 6032 -e "SELECT * FROM mysql_servers" > /backup/mysql_servers.txt
mysql -u admin -padmin -h 127.0.0.1 -P 6032 -e "SELECT * FROM mysql_query_rules" > /backup/mysql_query_rules.txt
mysql -u admin -padmin -h 127.0.0.1 -P 6032 -e "SELECT * FROM mysql_users" > /backup/mysql_users.txt

Q5: 如何升级 ProxySQL?

A5: 可以通过以下步骤升级 ProxySQL:

  1. 备份现有配置
  2. 下载新版本 ProxySQL
  3. 停止现有 ProxySQL 实例
  4. 安装新版本 ProxySQL
  5. 恢复配置
  6. 启动新版本 ProxySQL

Q6: ProxySQL 支持哪些 MySQL 版本?

A6: ProxySQL 支持 MySQL 5.5 及以上版本,包括 MariaDB 和 Percona Server。

Q7: 如何配置 ProxySQL 监控?

A7: 可以使用以下工具监控 ProxySQL:

  • Prometheus + Grafana
  • Zabbix
  • ProxySQL 内置监控表
  • 第三方监控工具

Q8: 如何处理 ProxySQL 中的慢查询?

A8: 可以通过以下方式处理 ProxySQL 中的慢查询:

  1. 启用慢查询日志
  2. 分析慢查询日志
  3. 优化慢查询
  4. 调整查询规则
  5. 考虑使用缓存

与其他代理的比较

代理名称优点缺点适用场景
ProxySQL高性能、功能丰富、支持多种负载均衡算法配置复杂、学习曲线陡峭大型 MySQL 集群
MaxScale配置简单、易于使用功能相对较少中小型 MySQL 集群
MySQL Router官方支持、与 MySQL 深度集成功能有限MySQL 官方解决方案
HAProxy高性能、稳定可靠不支持 SQL 解析简单的读写分离