在2核4G内存的服务器上优化MySQL吞吐量,需要从配置、查询、架构和运维多方面入手。以下是关键优化策略:
1. MySQL配置优化
内存分配
# my.cnf 配置
[mysqld]
# 缓冲池(占总内存50-70%)
innodb_buffer_pool_size = 2G
# 日志缓冲区
innodb_log_buffer_size = 64M
innodb_log_file_size = 256M
# 排序和连接缓冲
sort_buffer_size = 2M
join_buffer_size = 2M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
# 连接相关
max_connections = 200
thread_cache_size = 50
table_open_cache = 2000
InnoDB优化
# 事务日志
innodb_flush_log_at_trx_commit = 2 # 平衡性能和持久性
sync_binlog = 1000
# I/O优化
innodb_io_capacity = 200
innodb_io_capacity_max = 400
innodb_flush_method = O_DIRECT
# 线程并发
innodb_thread_concurrency = 4
innodb_read_io_threads = 4
innodb_write_io_threads = 4
2. 查询优化
索引优化
-- 创建复合索引
CREATE INDEX idx_user_status_time ON users (status, created_at);
-- 覆盖索引减少回表
SELECT id, name FROM users WHERE status = 'active'
AND created_at > '2024-01-01';
-- 避免全表扫描
EXPLAIN SELECT * FROM large_table WHERE unindexed_column = 'value';
查询重写
-- 使用LIMIT分页
SELECT * FROM posts ORDER BY id DESC LIMIT 10 OFFSET 100;
-- 避免SELECT *
SELECT id, title, content FROM articles WHERE user_id = 123;
-- 优化JOIN顺序
SELECT u.name, p.title
FROM users u
INNER JOIN posts p ON u.id = p.user_id
WHERE u.status = 'active';
3. 架构优化
读写分离
// 应用层实现读写分离
class Database {
private $master;
private $slave;
public function write($sql) {
return $this->master->query($sql);
}
public function read($sql) {
return $this->slave->query($sql);
}
}
连接池
# 使用连接池中间件
connection_pool:
max_connections: 50
min_connections: 5
connection_timeout: 30
4. 表结构优化
数据类型选择
-- 使用合适的数据类型
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
status TINYINT UNSIGNED DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB;
分区表
-- 按时间分区
CREATE TABLE logs (
id INT AUTO_INCREMENT,
log_time DATETIME,
message TEXT,
PRIMARY KEY (id, log_time)
) PARTITION BY RANGE (YEAR(log_time)) (
PARTITION p2023 VALUES LESS THAN (2024),
PARTITION p2024 VALUES LESS THAN (2025)
);
5. 缓存策略
查询缓存(谨慎使用)
query_cache_type = 1
query_cache_size = 64M
query_cache_limit = 2M
应用层缓存
// Redis缓存示例
function getUser($userId) {
$cacheKey = "user:{$userId}";
$user = $redis->get($cacheKey);
if (!$user) {
$user = $db->query("SELECT * FROM users WHERE id = ?", [$userId]);
$redis->setex($cacheKey, 3600, json_encode($user));
}
return json_decode($user, true);
}
6. 监控和调优
性能监控
-- 查看慢查询
SET long_query_time = 1;
SET slow_query_log = ON;
-- 监控状态
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Handler_read%';
SHOW STATUS LIKE 'Key_reads';
定期维护
# 优化表
OPTIMIZE TABLE large_table;
# 更新统计信息
ANALYZE TABLE users;
# 清理二进制日志
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);
7. 系统级优化
文件系统
# 使用ext4或XFS文件系统
# mount -o noatime,nodiratime /dev/sda1 /var/lib/mysql
# 调整I/O调度
echo deadline > /sys/block/sda/queue/scheduler
内核参数
# /etc/sysctl.conf
vm.swappiness = 1
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5
8. 实际优化步骤
- 基准测试:使用
sysbench进行压力测试 - 监控分析:通过
pt-query-digest分析慢查询 - 逐步调整:每次只调整一个参数并观察效果
- 定期评估:根据业务增长重新评估配置
# 基准测试示例
sysbench oltp_read_write --mysql-host=localhost --mysql-user=root
--mysql-password=password --tables=10 --table-size=10000 prepare
sysbench oltp_read_write --mysql-host=localhost --mysql-user=root
--mysql-password=password --threads=16 --time=60 run
通过以上综合优化,可以在2核4G的硬件限制下最大化MySQL的吞吐量表现。关键是要持续监控、分析和调整,找到最适合具体工作负载的配置组合。
云计算