文章目录
-
- 一、性能优化概述
-
- [1.1 优化目标](#1.1 优化目标)
- [1.2 优化原则](#1.2 优化原则)
- [1.3 优化策略](#1.3 优化策略)
- 二、性能分析诊断流程
-
- [2.1 性能问题识别](#2.1 性能问题识别)
-
- [2.1.1 性能指标监控](#2.1.1 性能指标监控)
- [2.1.2 性能瓶颈识别](#2.1.2 性能瓶颈识别)
- [2.2 性能分析工具](#2.2 性能分析工具)
-
- [2.2.1 系统监控](#2.2.1 系统监控)
- [2.2.2 数据库监控视图](#2.2.2 数据库监控视图)
- 三、SQL优化策略
-
- [3.1 单分片查询优化](#3.1 单分片查询优化)
-
- [3.1.1 分片键使用原则](#3.1.1 分片键使用原则)
- [3.1.2 避免全分片扫描](#3.1.2 避免全分片扫描)
- [3.2 跨分片查询优化](#3.2 跨分片查询优化)
-
- [3.2.1 减少跨分片查询](#3.2.1 减少跨分片查询)
- [3.2.2 跨分片聚合优化](#3.2.2 跨分片聚合优化)
- [3.3 索引优化](#3.3 索引优化)
-
- [3.3.1 索引设计原则](#3.3.1 索引设计原则)
- [3.3.2 索引使用分析](#3.3.2 索引使用分析)
- [3.4 执行计划分析](#3.4 执行计划分析)
-
- [3.4.1 查看执行计划](#3.4.1 查看执行计划)
- [3.4.2 执行计划优化要点](#3.4.2 执行计划优化要点)
- [3.5 常见SQL优化案例](#3.5 常见SQL优化案例)
- 四、架构优化策略
-
- [4.1 分片策略优化](#4.1 分片策略优化)
-
- [4.1.1 分片键选择原则](#4.1.1 分片键选择原则)
- [4.1.2 分片数量规划](#4.1.2 分片数量规划)
- [4.1.3 分片类型选择](#4.1.3 分片类型选择)
- [4.2 读写分离优化](#4.2 读写分离优化)
-
- [4.2.1 读写分离配置](#4.2.1 读写分离配置)
- [4.2.2 读写分离注意事项](#4.2.2 读写分离注意事项)
- [4.3 表结构优化](#4.3 表结构优化)
-
- [4.3.1 表设计原则](#4.3.1 表设计原则)
- [4.3.2 分区表设计(如果TDSQL支持)](#4.3.2 分区表设计(如果TDSQL支持))
- [4.4 索引优化](#4.4 索引优化)
-
- [4.4.1 索引设计原则](#4.4.1 索引设计原则)
- [4.4.2 索引维护](#4.4.2 索引维护)
- 五、参数调优策略
-
- [5.1 Set节点参数调优](#5.1 Set节点参数调优)
-
- [5.1.1 内存参数](#5.1.1 内存参数)
- [5.1.2 IO参数](#5.1.2 IO参数)
- [5.2 Proxy节点参数调优](#5.2 Proxy节点参数调优)
-
- [5.2.1 连接参数](#5.2.1 连接参数)
- [5.2.2 路由参数](#5.2.2 路由参数)
- [5.3 分布式事务参数](#5.3 分布式事务参数)
- 六、硬件优化策略
-
- [6.1 CPU优化](#6.1 CPU优化)
- [6.2 内存优化](#6.2 内存优化)
- [6.3 存储优化](#6.3 存储优化)
- [6.4 网络优化](#6.4 网络优化)
- 七、监控与告警
-
- [7.1 关键指标监控](#7.1 关键指标监控)
- [7.2 告警阈值设置](#7.2 告警阈值设置)
- 八、优化实施流程
-
- [8.1 优化前准备](#8.1 优化前准备)
- [8.2 优化实施](#8.2 优化实施)
- [8.3 持续优化](#8.3 持续优化)
- 九、常见性能问题及解决方案
-
- [9.1 跨分片查询过多](#9.1 跨分片查询过多)
- [9.2 分片负载不均衡](#9.2 分片负载不均衡)
- [9.3 分布式事务性能差](#9.3 分布式事务性能差)
- [9.4 主从延迟](#9.4 主从延迟)
- 十、优化检查清单
-
- [10.1 SQL优化检查](#10.1 SQL优化检查)
- [10.2 架构优化检查](#10.2 架构优化检查)
- [10.3 参数优化检查](#10.3 参数优化检查)
- [10.4 监控检查](#10.4 监控检查)
- 重要提醒
一、性能优化概述
1.1 优化目标
TDSQL性能优化的核心目标:
- 提升吞吐量:提高QPS(每秒查询数)和TPS(每秒事务数)
- 降低响应时间:减少SQL执行时间和事务响应时间,特别是跨分片查询
- 提高资源利用率:优化CPU、内存、IO等资源使用
- 保障系统稳定性:避免性能瓶颈导致的系统故障
- 优化分布式性能:减少跨分片查询,优化分布式事务性能
1.2 优化原则
- 系统性原则:从整体架构到具体参数,系统化优化
- 数据驱动原则:基于监控数据和性能指标进行优化
- 渐进式原则:逐步优化,每次调整后验证效果
- 业务优先原则:优化不能影响业务功能和数据一致性
- 可回滚原则:重要变更需制定回滚方案
- 分片优先原则:优先保证单分片操作,减少跨分片查询
1.3 优化策略
性能优化策略
├── 性能分析
│ ├── 性能指标收集
│ ├── 瓶颈识别(Proxy/Set/Scheduler)
│ ├── 分片性能分析
│ └── 根因分析
├── 优化策略制定
│ ├── 架构优化(分片策略、读写分离)
│ ├── SQL优化(单分片查询、跨分片优化)
│ ├── 参数调优(Proxy、Set节点)
│ └── 硬件优化
├── 优化实施
│ ├── 测试环境验证
│ ├── 生产环境实施
│ └── 效果监控
└── 持续优化
├── 性能基线建立
├── 定期评估
└── 优化迭代
二、性能分析诊断流程
2.1 性能问题识别
2.1.1 性能指标监控
关键性能指标(KPI)
sql
-- 1. 系统整体性能(Set节点)
SELECT
'QPS' AS METRIC,
COUNT(*) / (TIMESTAMPDIFF(SECOND, MIN(start_time), MAX(start_time))) AS VALUE
FROM mysql.slow_log
WHERE start_time > DATE_SUB(NOW(), INTERVAL 5 MINUTE);
-- 2. Proxy层性能
SHOW PROXY STATUS;
-- 查看Proxy连接数、路由命中率、跨分片查询比例
-- 3. 响应时间分布
SELECT
CASE
WHEN query_time < 0.1 THEN '<100ms'
WHEN query_time < 0.5 THEN '100-500ms'
WHEN query_time < 1 THEN '500ms-1s'
WHEN query_time < 5 THEN '1s-5s'
ELSE '>5s'
END AS TIME_RANGE,
COUNT(*) AS COUNT,
ROUND(COUNT(*) * 100.0/SUM(COUNT(*)) OVER(), 2) AS PERCENTAGE
FROM mysql.slow_log
WHERE start_time > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
GROUP BY CASE
WHEN query_time < 0.1 THEN '<100ms'
WHEN query_time < 0.5 THEN '100-500ms'
WHEN query_time < 1 THEN '500ms-1s'
WHEN query_time < 5 THEN '1s-5s'
ELSE '>5s'
END;
-- 4. 缓冲池命中率(Set节点)
SELECT
(1 - (Innodb_buffer_pool_reads / NULLIF(Innodb_buffer_pool_read_requests, 0))) * 100 AS HIT_RATE
FROM
(SELECT VARIABLE_VALUE AS Innodb_buffer_pool_reads
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') AS reads,
(SELECT VARIABLE_VALUE AS Innodb_buffer_pool_read_requests
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests') AS requests;
-- 5. 锁等待情况
SELECT
COUNT(*) AS LOCK_WAITS,
AVG(TIMER_WAIT/1000000000000) AS AVG_WAIT_TIME_SEC,
MAX(TIMER_WAIT/1000000000000) AS MAX_WAIT_TIME_SEC
FROM performance_schema.events_waits_current
WHERE OBJECT_TYPE = 'TABLE' AND TIMER_WAIT > 0;
-- 6. 分片查询统计
SHOW SHARD STATISTICS;
-- 查看各分片的查询量、数据量、负载情况
2.1.2 性能瓶颈识别
瓶颈类型识别
- Proxy层瓶颈
- 连接数达到上限
- 路由计算耗时
- 跨分片查询过多
- 负载不均衡
- Set节点瓶颈
- CPU使用率高
- 内存不足
- IO等待时间长
- 锁等待频繁
- 网络瓶颈
- Proxy到Set网络延迟
- 跨分片网络通信
- 带宽不足
- 分布式事务瓶颈
- 2PC提交耗时
- 分布式锁竞争
- 跨分片事务过多
诊断SQL
sql
-- 1. 查看Proxy连接状态
SHOW PROXY CONNECTIONS;
-- 分析:连接数、空闲连接、等待连接
-- 2. 查看慢查询(包含分片信息)
SELECT
sql_text,
shard_id,
query_time,
lock_time,
rows_examined,
rows_sent
FROM mysql.slow_log
WHERE start_time > DATE_SUB(NOW(), INTERVAL 1 HOUR)
ORDER BY query_time DESC
LIMIT 20;
-- 3. 查看跨分片查询
SELECT
sql_text,
COUNT(*) AS CROSS_SHARD_COUNT,
AVG(query_time) AS AVG_TIME
FROM mysql.slow_log
WHERE sql_text LIKE '%JOIN%' OR sql_text LIKE '%UNION%'
GROUP BY sql_text
HAVING COUNT(*) > 10
ORDER BY AVG_TIME DESC;
-- 4. 查看各分片负载
SHOW SHARD LOAD;
-- 分析:各分片的QPS、连接数、CPU使用率
-- 5. 查看分布式事务状态
SHOW DISTRIBUTED TRANSACTION STATUS;
-- 分析:活跃事务数、超时事务数、平均耗时
2.2 性能分析工具
2.2.1 系统监控
bash
# 1. CPU监控
top -H -p $(pgrep -f mysqld)
# 分析:CPU使用率、线程状态
# 2. 内存监控
free -h
# 分析:内存使用、Swap使用
# 3. IO监控
iostat -x 1
# 分析:IOPS、IO等待时间、磁盘使用率
# 4. 网络监控
iftop -i eth0
# 分析:网络流量、连接数
# 5. Proxy监控
# 通过TDSQL管理平台查看Proxy指标
2.2.2 数据库监控视图
sql
-- 1. 查看当前连接
SHOW PROCESSLIST;
-- 分析:连接状态、执行时间、等待事件
-- 2. 查看InnoDB状态
SHOW ENGINE INNODB STATUS\G
-- 分析:锁等待、死锁、缓冲池状态
-- 3. 查看主从复制状态
SHOW SLAVE STATUS\G
-- 分析:复制延迟、IO线程、SQL线程状态
-- 4. 查看表统计信息
SHOW TABLE STATUS LIKE 'table_name';
-- 分析:表大小、行数、索引使用
-- 5. 查看索引使用情况
SELECT
TABLE_SCHEMA,
TABLE_NAME,
INDEX_NAME,
CARDINALITY
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY CARDINALITY DESC;
三、SQL优化策略
3.1 单分片查询优化
3.1.1 分片键使用原则
sql
-- 1. 查询必须包含分片键
-- 推荐:单分片查询
SELECT * FROM user_table WHERE user_id = 100;
-- 不推荐:全分片扫描
SELECT * FROM user_table WHERE name = 'test';
-- 2. 分片键在WHERE条件中
-- 推荐
SELECT * FROM order_table WHERE order_id = 100 AND status = 1;
-- 不推荐(如果order_id是分片键,status不是)
SELECT * FROM order_table WHERE status = 1;
-- 3. IN查询包含分片键
-- 推荐:可以路由到特定分片
SELECT * FROM user_table WHERE user_id IN (100, 200, 300);
-- 注意:如果IN值跨多个分片,会查询多个分片
3.1.2 避免全分片扫描
sql
-- 问题:全分片扫描,性能差
SELECT * FROM user_table WHERE create_time > '2024-01-01';
-- 优化方案1:添加分片键条件
SELECT * FROM user_table WHERE user_id BETWEEN 1000 AND 2000 AND create_time > '2024-01-01';
-- 优化方案2:使用分片键范围查询
SELECT * FROM user_table WHERE user_id IN (
SELECT user_id FROM user_table
WHERE create_time > '2024-01-01'
LIMIT 1000);
3.2 跨分片查询优化
3.2.1 减少跨分片查询
sql
-- 问题:跨分片JOIN,性能差
SELECT u.*, o.* FROM user_table u JOIN order_table o ON u.user_id = o.user_id;
-- 优化方案1:应用层JOIN
-- 先查询user_table,再根据user_id查询order_table
SELECT * FROM user_table WHERE user_id = 100;
SELECT * FROM order_table WHERE user_id = 100;
-- 优化方案2:冗余数据(如果业务允许)
-- 在order_table中冗余user信息,避免JOIN
-- 优化方案3:使用相同分片键
-- 确保user_table和order_table使用相同的分片键
3.2.2 跨分片聚合优化
sql
-- 问题:跨分片COUNT,需要汇总所有分片
SELECT COUNT(*) FROM user_table WHERE status = 1;
-- 优化方案1:使用分片键范围
SELECT SUM(cnt) FROM (
SELECT COUNT(*) AS cnt FROM user_table
WHERE user_id BETWEEN 1 AND 1000000 AND status = 1
UNION ALL
SELECT COUNT(*) FROM user_table
WHERE user_id BETWEEN 1000001 AND 2000000 AND status = 1
-- ... 其他分片
) AS shard_counts;
-- 优化方案2:应用层聚合
-- 在各分片分别查询,应用层汇总
-- 优化方案3:使用汇总表
-- 定期更新汇总表,查询汇总表
3.3 索引优化
3.3.1 索引设计原则
sql
-- 1. 分片键必须建立索引(通常作为主键)
CREATE TABLE user_table (
user_id INT PRIMARY KEY, -- 分片键
name VARCHAR(100),
email VARCHAR(100),
INDEX idx_name(name)
);
-- 2. 查询条件列创建索引
CREATE INDEX idx_status ON order_table(status);
CREATE INDEX idx_create_time ON order_table(create_time);
-- 3. 复合索引包含分片键
-- 推荐:分片键在前
CREATE INDEX idx_user_status ON order_table(user_id, status);
-- 4. 避免过多索引
-- 每个表索引数量建议不超过5个
3.3.2 索引使用分析
sql
-- 查看索引使用情况
SELECT
TABLE_SCHEMA,
TABLE_NAME,
INDEX_NAME,
SEQ_IN_INDEX,
COLUMN_NAME,
CARDINALITY
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX;
-- 查找未使用的索引
SELECT
s.TABLE_SCHEMA,
s.TABLE_NAME,
s.INDEX_NAME
FROM information_schema.STATISTICS s
LEFT JOIN (
SELECT DISTINCT
OBJECT_SCHEMA,
OBJECT_NAME,
INDEX_NAME
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE INDEX_NAME IS NOT NULL
) u
ON s.TABLE_SCHEMA = u.OBJECT_SCHEMA
AND s.TABLE_NAME = u.OBJECT_NAME
AND s.INDEX_NAME = u.INDEX_NAME
WHERE u.INDEX_NAME IS NULL AND s.TABLE_SCHEMA = 'your_database';
3.4 执行计划分析
3.4.1 查看执行计划
sql
-- 方式1:EXPLAIN
EXPLAIN SELECT * FROM user_table WHERE user_id = 100;
-- 方式2:EXPLAIN FORMAT=JSON(详细信息)
EXPLAIN FORMAT=JSON SELECT * FROM user_table WHERE user_id = 100;
-- 方式3:EXPLAIN ANALYZE(实际执行统计,MySQL 8.0+)
EXPLAIN ANALYZE SELECT * FROM user_table WHERE user_id = 100;
3.4.2 执行计划优化要点
- 全表扫描(ALL)
- 问题:大表全表扫描性能差
- 解决:创建索引或优化WHERE条件,确保使用分片键
- 索引扫描(index/range)
- 正常:索引扫描通常性能好
- 注意:索引选择性要足够高
- 嵌套循环(Nested Loop)
- 适用:小表JOIN
- 注意:内表要有索引,避免跨分片JOIN
- 哈希JOIN(Hash Join,MySQL 8.0+)
- 适用:大表JOIN
- 注意:需要足够内存,跨分片JOIN性能差
- 排序(Using filesort)
- 问题:排序操作消耗资源
- 解决:使用索引避免排序,或使用分片键范围查询
3.5 常见SQL优化案例
案例1:避免SELECT *
sql
-- 不推荐
SELECT * FROM user_table WHERE user_id = 100;
-- 推荐
SELECT user_id, name, email FROM user_table WHERE user_id = 100;
案例2:优化IN子查询
sql
-- 不推荐(跨分片子查询)
SELECT * FROM order_table WHERE user_id IN (SELECT user_id FROM user_table WHERE status = 1);
-- 推荐(应用层先查询user_id,再查询order)
-- 步骤1:查询user_id列表
SELECT user_id FROM user_table WHERE status = 1;
-- 步骤2:根据user_id查询order(单分片查询)
SELECT * FROM order_table WHERE user_id IN (100, 200, 300);
案例3:优化LIKE查询
sql
-- 不推荐(前导%,全分片扫描)
SELECT * FROM user_table WHERE name LIKE '%test%';
-- 推荐1(后置%,可使用索引)
SELECT * FROM user_table WHERE name LIKE 'test%';
-- 推荐2(使用全文索引)
CREATE FULLTEXT INDEX idx_ft_name ON user_table(name);
SELECT * FROM user_table WHERE MATCH(name) AGAINST('test' IN NATURAL LANGUAGE MODE);
-- 推荐3(如果必须前导%,使用分片键范围)
SELECT * FROM user_table WHERE user_id BETWEEN 1000 AND 2000 AND name LIKE '%test%';
案例4:批量操作优化
sql
-- 不推荐(逐条插入)
INSERT INTO user_table VALUES (1, 'name1');
INSERT INTO user_table VALUES (2, 'name2');
-- ...
-- 推荐(批量插入,同一分片)
INSERT INTO user_table VALUES(1, 'name1'),(2, 'name2'),(3, 'name3');
-- 注意:确保所有记录在同一分片,或使用批量API
-- 推荐(使用LOAD DATA)
LOAD DATA LOCAL INFILE '/path/to/data.csv' INTO TABLE user_table
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
案例5:分页查询优化
sql
-- 不推荐(OFFSET大时性能差)
SELECT * FROM user_table ORDER BY create_time DESC LIMIT 1000 OFFSET 10000;
-- 推荐(使用游标分页)
SELECT * FROM user_table WHERE create_time < '2024-01-01' ORDER BY create_time DESC LIMIT 1000;
-- 或使用分片键范围
SELECT * FROM user_table WHERE user_id BETWEEN 10000 AND 20000 ORDER BY create_time DESC LIMIT 1000;
四、架构优化策略
4.1 分片策略优化
4.1.1 分片键选择原则
- 高基数列:选择唯一性高的列作为分片键
- 推荐:用户ID、订单ID、设备ID
- 不推荐:性别、状态(基数低)
- 查询模式匹配:分片键应该匹配主要查询模式
- 如果主要查询是按用户ID,则使用user_id作为分片键
- 数据分布均匀:确保数据在各分片均匀分布
- 避免热点分片
- 监控各分片数据量和负载
- 业务关联性:关联表使用相同分片键
- user_table和order_table都使用user_id作为分片键
- 避免跨分片JOIN
4.1.2 分片数量规划
-- 分片数量计算公式
-- 分片数 = 总数据量 / 单分片容量(建议<500GB)
-- 建议设置为2的幂次方:4, 8, 16, 32, 64
-- 示例:总数据量2TB,单分片容量500GB
-- 分片数 = 2000GB / 500GB = 4个分片
-- 监控分片数据量
SHOW SHARD STATISTICS;
-- 如果单分片数据量接近上限,需要增加分片或清理数据
4.1.3 分片类型选择
- HASH分片
- 适用:数据分布均匀,点查询为主
- 优点:数据分布均匀,查询性能好
- 缺点:范围查询需要扫描所有分片
- RANGE分片
- 适用:范围查询多,数据有时间或ID范围特征
- 优点:范围查询性能好
- 缺点:可能产生热点分片
- LIST分片
- 适用:按业务分区,如按地区、类型
- 优点:业务隔离,查询性能好
- 缺点:需要提前规划分区规则
4.2 读写分离优化
4.2.1 读写分离配置
-- Proxy层配置
-- proxy_read_route = 1 # 从库优先
-- 应用层配置(JDBC)
-- jdbc:mysql://proxy_host:port/database?useReadOnly=true
-- 读操作自动路由到从库
4.2.2 读写分离注意事项
- 主从延迟处理
- 强一致性读操作使用主库
- 允许延迟的读操作使用从库
- 监控主从延迟:
SHOW SLAVE STATUS
- 事务内读操作
- 事务内的读操作默认使用主库
- 避免主从延迟导致的数据不一致
- 从库负载均衡
- 配置多个从库,负载均衡
- 根据从库性能设置权重
4.3 表结构优化
4.3.1 表设计原则
- 规范化设计:避免数据冗余
- 合理分区:大表使用分区表(如果支持)
- 数据类型选择:选择合适的数据类型和长度
- 字段顺序:常用字段放在前面
- 分片键设计:分片键作为主键或唯一索引
4.3.2 分区表设计(如果TDSQL支持)
sql
-- 范围分区
CREATE TABLE t_order (
order_id INT,
user_id INT,
order_date DATE,
amount DECIMAL(10,2),
PRIMARY KEY (order_id, user_id) -- 包含分片键
) PARTITION BY RANGE (YEAR(order_date)) (
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025),
PARTITION p2025 VALUES LESS THAN (2026)
);
4.4 索引优化
4.4.1 索引设计原则
sql
-- 1. 分片键索引(必须)
CREATE TABLE user_table (
user_id INT PRIMARY KEY, -- 分片键作为主键
name VARCHAR(100),
email VARCHAR(100)
);
-- 2. 查询条件索引
CREATE INDEX idx_email ON user_table(email);
CREATE INDEX idx_create_time ON user_table(create_time);
-- 3. 复合索引
-- 推荐:分片键在前
CREATE INDEX idx_user_status ON order_table(user_id, status);
-- 4. 覆盖索引
-- 如果查询只需要索引列,可以避免回表
CREATE INDEX idx_user_name_email ON user_table(user_id, name, email);
-- 查询:SELECT user_id, name, email FROM user_table WHERE user_id = 100;
4.4.2 索引维护
sql
-- 1. 定期更新统计信息
ANALYZE TABLE user_table;
-- 2. 重建索引(如果碎片严重)
ALTER TABLE user_table DROP INDEX idx_name;
ALTER TABLE user_table ADD INDEX idx_name(name);
-- 3. 监控索引使用
-- 使用performance_schema或慢查询日志分析索引使用情况
五、参数调优策略
5.1 Set节点参数调优
5.1.1 内存参数
ini
# InnoDB缓冲池(最重要)
innodb_buffer_pool_size = 40G # 物理内存的70-80%
innodb_buffer_pool_instances = 8 # 缓冲池实例数
# 连接相关
max_connections = 2000
thread_cache_size = 32
# 排序和JOIN
sort_buffer_size = 2M
join_buffer_size = 512K
5.1.2 IO参数
ini
# IO能力
innodb_io_capacity = 4000 # SSD建议2000-4000
innodb_read_io_threads = 8
innodb_write_io_threads = 8
# 日志刷盘
innodb_flush_log_at_trx_commit = 2 # 一般业务
innodb_log_file_size = 2G
5.2 Proxy节点参数调优
5.2.1 连接参数
ini
# Proxy连接数
proxy_max_connections = 5000 # 大于后端Set节点连接数总和
# 超时设置
proxy_connection_timeout = 10
proxy_idle_timeout = 3600
5.2.2 路由参数
ini
# 路由模式
proxy_route_mode = 0 # 单分片模式(推荐)
# 负载均衡
proxy_load_balance = 1 # 最小连接
# 读路由
proxy_read_route = 1 # 从库优先
5.3 分布式事务参数
ini
# 分布式事务超时
tdsql_2pc_timeout = 300 # 根据业务调整
# GTID模式
tdsql_gtid_mode = ON
六、硬件优化策略
6.1 CPU优化
- CPU选择:选择高主频CPU(OLTP场景)或多核CPU(OLAP场景)
- CPU绑定:将数据库进程绑定到特定CPU核心
- 中断均衡:使用irqbalance均衡中断
6.2 内存优化
- 内存容量:建议至少64GB,根据数据量调整
- NUMA优化:关闭NUMA或配置NUMA策略
- Swap配置:关闭Swap或设置vm.swappiness=1
6.3 存储优化
- SSD选择:使用高性能SSD(NVMe SSD)
- RAID配置:RAID 10(性能优先)或RAID 5(容量优先)
- 文件系统:使用XFS或ext4,关闭atime
- IO调度器:使用deadline或noop调度器
6.4 网络优化
- 网络带宽:确保足够带宽,建议10Gbps
- 网络延迟:Proxy到Set节点延迟<1ms
- TCP参数:优化TCP缓冲区大小
七、监控与告警
7.1 关键指标监控
- 性能指标
- QPS/TPS
- 响应时间(P50/P95/P99)
- 慢查询数量
- 资源指标
- CPU使用率
- 内存使用率
- IO使用率
- 网络带宽
- 分布式指标
- 跨分片查询比例
- 分布式事务数量
- 分片负载均衡度
7.2 告警阈值设置
告警规则:
-指标:CPU使用率
阈值:>80%(警告),>90%(严重)
-指标:内存使用率
阈值:>85%(警告),>95%(严重)
-指标:响应时间P95
阈值:>500ms(警告),>1s(严重)
-指标:慢查询数量
阈值:>100/分钟(警告),>500/分钟(严重)
-指标:跨分片查询比例
阈值:>20%(警告),>50% (严重)
八、优化实施流程
8.1 优化前准备
- 性能基线建立
- 记录当前性能指标
- 建立性能监控体系
- 问题分析
- 收集性能数据
- 识别性能瓶颈
- 分析根因
- 优化方案制定
- 制定优化策略
- 评估优化效果
- 制定回滚方案
8.2 优化实施
- 测试环境验证
- 在测试环境实施优化
- 验证优化效果
- 确认无负面影响
- 生产环境实施
- 选择业务低峰期
- 逐步实施优化
- 实时监控效果
- 效果验证
- 对比优化前后指标
- 确认优化目标达成
- 记录优化经验
8.3 持续优化
- 定期评估
- 每周/每月性能评估
- 识别新的性能问题
- 制定优化计划
- 优化迭代
- 持续优化SQL
- 调整参数配置
- 优化架构设计
九、常见性能问题及解决方案
9.1 跨分片查询过多
- 问题现象:响应时间长,Proxy CPU使用率高
- 解决方案:
- 优化SQL,确保使用分片键
- 调整分片策略,减少跨分片查询
- 应用层拆分查询,避免跨分片JOIN
9.2 分片负载不均衡
- 问题现象:部分分片CPU/IO使用率高,其他分片空闲
- 解决方案:
- 检查分片键分布,确保数据均匀
- 调整分片策略或重新分片
- 迁移热点数据到其他分片
9.3 分布式事务性能差
- 问题现象:分布式事务响应时间长,超时频繁
- 解决方案:
- 减少分布式事务,优先使用单分片事务
- 优化事务逻辑,减少事务时间
- 调整2PC超时时间
9.4 主从延迟
- 问题现象:从库查询数据不一致
- 解决方案:
- 优化主库写入性能
- 增加从库数量,分担读压力
- 使用半同步复制
- 强一致性读使用主库
十、优化检查清单
10.1 SQL优化检查
- 查询包含分片键
- 避免跨分片JOIN
- 避免全分片扫描
- 使用合适的索引
- 避免SELECT *
- 批量操作优化
10.2 架构优化检查
- 分片键选择合理
- 分片数量合适
- 数据分布均匀
- 读写分离配置正确
- 索引设计合理
10.3 参数优化检查
- Set节点参数优化
- Proxy节点参数优化
- 内存参数合理
- IO参数优化
- 连接参数合理
10.4 监控检查
- 性能指标监控完善
- 告警规则配置
- 慢查询日志开启
- 分片性能监控
- 分布式事务监控
重要提醒
- 版本差异:TDSQL不同版本参数和功能可能不同,请以对应版本官方文档为准
- 环境依赖:优化方案需要根据实际硬件和业务特点调整
- 业务适配:优化不能影响业务功能和数据一致性
- 渐进优化:逐步优化,每次调整后验证效果
- 回滚准备:重要变更需制定回滚方案
- 持续监控:优化后持续监控,确保效果稳定