1.
概述与前置检测
- 检查VPS类型与磁盘:ssh到每台VPS,运行 lsblk / nvme list / fdisk -l,确认是否为本地SSD/NVMe或共享云盘。
- 测量当前IO/延迟基线:sudo apt-get install -y sysstat fio && iostat -x 1 3 && sudo fio --name=seqwrite --filename=/tmp/testfile --direct=1 --rw=write --bs=128k --size=1G --numjobs=1 --iodepth=4。记录iops、latency、bw作为对比。
2.
磁盘分区与文件系统策略
- 分区规划:建议至少分出:/ (系统)、/var/lib/mysql (数据库数据)、/var/lib/mysql_redo (redo/log)、/tmp 或 tmpfs(临时)。若是多数据库实例,单独为每个实例分区。
- 文件系统选择与挂载参数:对数据库推荐 XFS 或 ext4。挂载选项:noatime,nodiratime,barrier=0(谨慎,需确认底层盘安全); 对于InnoDB设置 innodb_flush_method=O_DIRECT 避免双缓存时使用。示例 /etc/fstab 行:/dev/nvme0n1p2 /var/lib/mysql xfs defaults,noatime,nodiratime,discard 0 2。
- fstrim:对于支持TRIM的NVMe,添加定期 fstrim / -a (systemd-timer 或 cron weekly)。
3.
逻辑卷与分离WAL/Redo
- 用LVM分离log:创建独立LV用于InnoDB redo/log(ib_logfile)和binlog,减少随机写干扰。命令示例:pvcreate /dev/nvme0n1p3 && vgcreate vgdb /dev/nvme0n1p3 && lvcreate -L 10G -n lv_redo vgdb。
- 优先放置redo/log在低延迟介质(本地SSD/NVMe),把冷热表数据分布到不同盘降低寻址冲突。
4.
MySQL / MariaDB 实际配置步骤
- 编辑 my.cnf(路径 /etc/mysql/my.cnf 或 /etc/my.cnf):设置关键项示例(依据总内存调整):innodb_buffer_pool_size = 0.7 * 总内存; innodb_flush_method = O_DIRECT; innodb_flush_log_at_trx_commit = 1(或为性能降低到2 看风险); innodb_log_file_size = 512M~1G; innodb_io_capacity = 根据盘IOPS设定(SSD 1000~2000)。
- 更改后安全重启:systemctl stop mysql;移动旧的 ib_logfile* 到备份目录;systemctl start mysql。验证:SHOW GLOBAL VARIABLES LIKE 'innodb_%'; SHOW ENGINE INNODB STATUS\G。
5.
操作系统级缓存与IO调优
- sysctl 常用项(写入 /etc/sysctl.d/99-db.conf):vm.swappiness=10; vm.vfs_cache_pressure=50; vm.dirty_ratio=15; vm.dirty_background_ratio=5。加载:sysctl -p /etc/sysctl.d/99-db.conf。
- block layer:对于KVM/VirtIO 优化:echo noop > /sys/block/sdX/queue/scheduler(或 mq-deadline),确认使用 virtio-scsi 或 nvme 驱动。
- 调整ulimit和文件句柄:在 /etc/security/limits.conf 添加 mysql 用户 nofile 65536、nproc 65536。
6.
缓存策略:使用Redis/ProxySQL替代Query Cache
- 关闭MySQL查询缓存(若使用现代MySQL版本推荐关闭):query_cache_size=0; query_cache_type=0。使用ProxySQL做读写分离、缓存热点SQL;或使用Redis作为应用层缓存。
- Redis部署建议:配置 AOF 永久化策略为 appendfsync everysec;将Redis放在同机或同机房低延迟网络上;为热点key设置内存淘汰策略(volatile-lru)。
7.
测试与监控:实测验证效果
- fio 测试:fio --name=randrw --filename=/var/lib/mysql/testfile --rw=randrw --bs=4k --size=2G --numjobs=4 --iodepth=16 --direct=1 --runtime=60。对比优化前后IOPS和latency。
- 监控工具:安装 Prometheus + node_exporter + mysqld_exporter 或使用 Percona Monitoring,监控 innodb_buffer_pool_hit_rate、OS load、iostat、iotop。定期检查 slow query log 并优化索引。
8.
备份与安全考虑
- 在线备份:使用 Percona XtraBackup 做热备份,命令示例 xtrabackup --backup --target-dir=/data/backup。备份期间避免在数据盘上做大IO任务。
- snapshot策略:若使用LVM或云盘快照,先 flush tables with read lock(或使用xtrabackup的prepare),然后创建快照。恢复演练需定期执行。
9.
常见问题:我如何在不重启的情况下临时调整?
- 问:如何在线调整缓冲池或IO参数?
- 答:很多参数可动态修改:例如调整InnoDB缓冲池可通过 SET GLOBAL innodb_buffer_pool_size=...(MySQL 8.0 动态增减更安全),或使用 innodb_io_capacity 直接 SET GLOBAL innodb_io_capacity=2000;sysctl 项可用 sudo sysctl -w vm.swappiness=10 即时生效。但某些修改(如 innodb_log_file_size)需停止MySQL并重建日志文件后重启。
10.
常见问题:站群VPS在台湾延迟/共享IO如何处理?
- 问:如果VPS是共享IO(云盘),还能做哪些优化?
- 答:在共享盘上优先把redo/log移到更快的独立盘或本地SSD;使用本地内存缓存(Redis/Memcached)减少磁盘读写;控制并发写入(限流、批量提交)并调低 innodb_flush_log_at_trx_commit 到 2(权衡数据持久性);如可能,升级到有保证IOPS的实例类型。
11.
常见问题:如何验证改动是否生效?
- 问:做完优化后如何判断效果?
- 答:对比优化前后的基线测试结果(fio、sysstat、mysqlbench、应用层TPS/延迟);关注innodb_rows_read/innodb_rows_inserted、buffer_pool_hit_rate、avg latency(iostat -x),以及应用响应时间。若IO延迟显著下降且数据库缓慢查询减少,说明优化生效。
来源:台湾站群vps优化磁盘与缓存策略提升数据库读写性能