14.8.6 容量规划与扩缩容实践
容量规划与扩缩容实践围绕业务增长曲线、读写比例、连接峰值与后端实例能力展开。本节给出基线采集、容量估算、扩缩容流程、排错与练习示例,并包含原理草图与关键命令说明。
基线指标采集(含安装与命令说明)#
1)安装与启用采集工具(示例:proxysql 自带管理接口 + node_exporter)
# 安装 ProxySQL(示例,基于 Debian/Ubuntu)
sudo apt-get update
sudo apt-get install -y proxysql
# 启动并检查
sudo systemctl enable --now proxysql
sudo systemctl status proxysql --no-pager
# 安装 node_exporter(示例)
cd /opt
curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz
tar -xf node_exporter-1.6.1.linux-amd64.tar.gz
/opt/node_exporter-1.6.1.linux-amd64/node_exporter --version
2)采集 ProxySQL 基线指标(连接池、QPS、延迟)
# 进入 ProxySQL 管理接口(默认端口6032)
mysql -u admin -padmin -h 127.0.0.1 -P6032
# 关键指标查看
SELECT Variable_name, Variable_value FROM stats.stats_mysql_global WHERE Variable_name IN
('Client_Connections_created','Client_Connections_aborted','MySQL_Query_Cache_count_get','MySQL_Query_Cache_count_set');
SELECT hostgroup, srv_host, status, ConnUsed, ConnFree, ConnOK FROM stats.stats_mysql_connection_pool;
SELECT Hostgroup, srv_host, Queries, Latency_us, Err_count FROM stats.stats_mysql_query_digest ORDER BY Queries DESC LIMIT 10;
3)采集 MySQL 基线指标(QPS/TPS、延迟、复制)
# QPS/TPS 粗略估算(间隔1s)
mysql -e "SHOW GLOBAL STATUS LIKE 'Questions'; SHOW GLOBAL STATUS LIKE 'Com_commit'; SHOW GLOBAL STATUS LIKE 'Com_rollback';"
# 复制延迟
mysql -e "SHOW SLAVE STATUS\G" | egrep "Seconds_Behind_Master|Slave_IO_Running|Slave_SQL_Running"
说明:
- ConnUsed/ConnFree 反映连接池命中与压力。
- Latency_us 用于评估热点查询延迟。
- Questions、Com_commit 用于估算峰值吞吐能力。
容量规划方法与示例#
容量估算建议采用“峰值负载×安全系数”,并区分代理层与后端层:
- 代理层:按峰值并发连接数、规则数量、SQL解析开销估算CPU与内存。
- 后端MySQL:按写入放大、索引命中率与磁盘IOPS估算。
- 安全系数一般1.5~2.0,促销场景2.5以上。
示例估算
- 峰值并发连接 5000,平均每连接 2KB 内存,ProxySQL 规则 500 条
- 估算内存:5000*2KB=10MB(连接池)+ 规则与缓存预留 1~2GB
- 若峰值QPS 30k,单代理CPU可承载 15k QPS,则至少 2 台代理
扩容实践(读扩/写扩)#
1)读扩:新增从库并加入读组(灰度引流)#
-- 在 ProxySQL 管理接口执行
INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight, max_connections)
VALUES(10, '10.0.10.21', 3306, 10, 1000);
-- 先设为低权重灰度
UPDATE mysql_servers SET weight=1, status='ONLINE' WHERE hostname='10.0.10.21';
-- 应用到运行时
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
-- 观察连接池与延迟
SELECT hostgroup, srv_host, status, ConnUsed, ConnFree FROM stats.stats_mysql_connection_pool;
SELECT Hostgroup, srv_host, Latency_us, Err_count FROM stats.stats_mysql_query_digest ORDER BY Latency_us DESC LIMIT 5;
-- 稳定后提升权重
UPDATE mysql_servers SET weight=10 WHERE hostname='10.0.10.21';
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
2)写扩:分库分表或分片路由(示例规则)#
-- 假设按用户ID取模分片到不同写库组
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES (1001, 1, '^SELECT.*FROM orders WHERE user_id%2=0', 20, 1),
(1002, 1, '^SELECT.*FROM orders WHERE user_id%2=1', 21, 1);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
缩容实践(先出流量再下线)#
-- 降低权重逐步出流量
UPDATE mysql_servers SET weight=0 WHERE hostname='10.0.10.21';
LOAD MYSQL SERVERS TO RUNTIME;
-- 观察连接消化
SELECT hostgroup, srv_host, ConnUsed FROM stats.stats_mysql_connection_pool WHERE srv_host='10.0.10.21';
-- 连接清零后下线并移除
UPDATE mysql_servers SET status='OFFLINE_SOFT' WHERE hostname='10.0.10.21';
LOAD MYSQL SERVERS TO RUNTIME;
DELETE FROM mysql_servers WHERE hostname='10.0.10.21';
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
排错清单与命令#
1)扩容后无流量:
- 检查规则命中、权重与状态
SELECT rule_id, match_pattern, destination_hostgroup, active FROM mysql_query_rules;
SELECT hostname, status, weight FROM mysql_servers;
2)延迟飙升:
- 查看慢查询与复制延迟
mysql -e "SHOW GLOBAL STATUS LIKE 'Slow_queries';"
mysql -e "SHOW SLAVE STATUS\G" | egrep "Seconds_Behind_Master"
3)连接耗尽:
- 查看连接池使用率
SELECT hostgroup, srv_host, ConnUsed, ConnFree, ConnOK FROM stats.stats_mysql_connection_pool;
练习与验收#
1)练习:新增一台从库并灰度引流,观察 10 分钟延迟与错误率
- 验收标准:Err_count=0,Latency_us 不高于原均值 20%
2)练习:模拟缩容
- 将权重降为 0,确认 ConnUsed 归零后删除实例
- 验收标准:代理层无 Client_Connections_aborted 增长
3)练习:容量模型更新
- 采集 1 周峰值 QPS 与延迟分位,计算新安全系数
- 验收标准:形成可复用的容量估算表格与阈值文档