
要定位读写瓶颈,首先需要分层检查:从物理/虚拟磁盘、内核 I/O 调度、到应用/数据库。常用工具包括 fio(生产负载模拟)、iostat、vmstat、ioping、blktrace 与 perf。
推荐基本流程:1)用 fio 做随机/顺序、不同并发(iodepth/numjobs)与不同块大小(4K/64K/1M)的基准,得出 IOPS/吞吐/延迟曲线;2)用 iostat -xz 观察 %util、await、svctm,以判断是 I/O 饱和还是延迟抖动;3)检查 CPU、系统负载、上下文切换(vmstat)与磁盘队列深度(/sys/block/sdX/queue/nr_requests)。
同时监测网络与内存:高并发可能是页面缓存命中率低或网络吞吐不足导致的间接瓶颈,使用 sar、netstat/ss、free/top 来排查。
如果 %util 接近 100% 且 IOPS 达到磁盘峰值,说明存储已饱和;如果 await 非常高但 %util 低,可能是 I/O 调度或锁竞争问题;如果 CPU 在系统态/软中断占用高,则考虑中断/网络负载影响。
fio 示例(随机读写混合模拟): fio --name=randrw --ioengine=libaio --rw=randrw --rwmixread=70 --bs=4k --iodepth=64 --numjobs=4 --size=2G --runtime=60
在云厂商的美国机房上测试时,尽量使用相同计费与规格的实例(磁盘类型、本地SSD或网络盘)来获得可比数据。
优先选择合适的存储介质:对高并发随机 I/O,NVMe 或本地 SSD 的延迟和 IOPS 明显优于传统云盘或 SATA SSD。若使用云盘,了解其 IOPS/带宽配额并考虑预留或升级。
文件系统方面,XFS 对并发写入与大文件性能表现良好;ext4 稳定且兼容性好;对于数据库或大量小文件,考虑直接使用裸块设备并由数据库管理文件布局或使用专用存储引擎。
常见优化包括在 /etc/fstab 中加上 noatime 或 relatime 来减少 metadata 写入;对 ext4 可启用 lazy_itable_init 或调整 commit= 值;对 XFS 可调整 inode64、logbufs 等。
禁用 atime:在 /etc/fstab 中添加 noatime;调整 readahead:blockdev --setra 1024 /dev/sdX;查看/设置 IO 调度器:cat /sys/block/sdX/queue/scheduler && echo mq-deadline > /sys/block/sdX/queue/scheduler。
在使用云提供的网络块存储(如 AWS EBS、GCP PD)时,了解其缓存/写入策略(write-through/write-back),并选择合适的 flush 策略以避免数据一致性问题。
内核层面的调整对高并发性能影响巨大。常见优化包括调整 I/O 调度器、减小 swappiness、调整页缓存刷新参数(vm.dirty_*)、调整文件句柄与网络连接数上限,以及开启异步 I/O 相关功能(aio、io_uring)。
推荐设置:将 vm.swappiness 设为较低值(如 10),减少内存被回收的倾向;根据应用调整 vm.dirty_ratio 与 vm.dirty_background_ratio,以控制内核何时把脏页刷写到磁盘;对于高并发写入,可以适当增大 vm.dirty_expire_centisecs 与 vm.dirty_background_bytes 以合并写入。
提升 ulimit -n(如 100000)并在 /etc/security/limits.conf 中配置,提高系统可同时打开的文件数。对于 TCP 连接,调优 net.core.somaxconn、net.ipv4.tcp_tw_reuse、tcp_fin_timeout 等有助于 Web 层并发处理。
sysctl -w vm.swappiness=10
sysctl -w vm.dirty_ratio=20
sysctl -w vm.dirty_background_ratio=5
sysctl -w fs.file-max=200000
对高并发场景,使用 io_uring 或 libaio 的异步 I/O 能显著降低系统调用开销;应用层应避免大量小同步写(O_SYNC/O_DSYNC),改为批量或异步提交。
应用层应优先做缓存与异步化:使用 Redis/Memcached 做读缓存,避免热点查询直击磁盘;对写操作采用缓冲/批量提交,使用消息队列(Kafka/RabbitMQ)做削峰;开启连接池和复用(数据库连接池、HTTP keepalive)。
数据库方面,根据引擎调优参数非常关键:MySQL InnoDB 可通过调整 innodb_buffer_pool_size(通常占物理内存 60-80%)、innodb_flush_method(O_DIRECT/O_DIRECT_NO_FSYNC)、innodb_log_file_size 与 innodb_flush_log_at_trx_commit (0/1/2) 来平衡性能与持久性。
避免频繁的全表扫描,尽量通过合适的索引、分区表或分库分表来降低单节点磁盘 I/O 压力;对于写密集型表,考虑使用延迟二级索引或异步去重策略。
my.cnf 中示例:innodb_buffer_pool_size=12G;innodb_flush_method=O_DIRECT;innodb_log_file_size=1G;innodb_flush_log_at_trx_commit=2(非关键强一致场景可使用)。
尽量使用批量写入、压缩数据减少磁盘带宽占用、对静态文件走 CDN、对日志使用异步写入或集中化日志系统(Fluentd/Logstash)。
容量规划需基于基准测试结果与业务增长预测:用 fio 模拟不同并发/块大小/混合读写比例,得出单盘或单实例的峰值 IOPS 与带宽,然后按冗余系数(1.5~2倍)规划实例数量与存储配额。
压测策略应覆盖最坏场景:短时高并发突发、长时间稳定高并发、混合读写比例变动。使用工具(wrk、ab、sysbench、pgbench、fio)联合压测应用、数据库与磁盘层。
磁盘层:IOPS、吞吐(MB/s)、平均延迟(avg_lat)、队列深度、%util;系统层:CPU、内存、上下文切换、中断;应用层:QPS、平均响应时间、错误率;数据库:缓冲池命中率、锁等待、慢查询。
使用 Prometheus + Grafana、Elastic Stack 或云厂商监控,将上述指标可视化并设置阈值告警(如磁盘延迟超过 20 ms 或 buffer pool 命中率低于 90%)。
定期做故障演练(磁盘 IO 饱和、单节点故障切换),并验证自动扩容/降级策略与数据一致性策略在高并发下的可靠性。