资讯动态

存储性能从IO特性画像到FIO压测优化实战

发布时间:2026/10/9 23:05:27 来源:尧图企业网站定制
干存储这行久了最常听到的一句话就是“这存储到底行不行”你问业务侧他说“慢”你问存储侧他说“盘是新的指标看着也正常”。两边都委屈问题却没人能说清。我早年处理过一张工单某业务系统间歇性卡顿数据库组说是存储扛不住存储组说磁盘健康没问题两边差点把工单吵成论战帖。最后的结论很有意思——硬件还真没坏是业务那会儿产生了一堆4KB的小随机写刚好把存储侧队列深度和调度策略的软肋给撞上了。从那以后我养成一个习惯先看Storage Performance背后那套IO characteristics再谈性能、谈选型、谈优化。说白了IO characteristics就是“业务到底怎么在用存储”的画像。这篇就把这些年摸过的IO画像、踩过的坑、压测和优化的一套方法写下来。不管你是DBA、系统运维、存储工程师还是写业务代码时被IO搞到头秃的应用开发只要遇到“慢”“卡”“延迟高”这类字眼这套思路都能给你指个方向。1. 从IO特性入手才能看懂性能数字存储性能从来不是一个孤立的数字。同一块盘跑4K小随机读和跑1MB顺序读成绩可能差出一个数量级。所以别急着看参数表先搞清楚你要解决的负载“长什么样”。1.1 五个核心维度我给存储做IO画像时固定看五个维度读写比例、IO大小、随机还是顺序、并发度、延迟敏感度。读写比例。读多写少的系统缓存和预读能救回来大半写多的系统缓存再大最后也得落盘这是两种完全不同的优化路径。IO大小。同样1GB数据拆成4KB小块发出去和拆成1MB大块发出去存储内部的处理单元和压力模型完全不同。用错维度去评估结论基本是错的。随机还是顺序。机械盘时代这是生死线闪存时代依然是重要的性能拐点不能只看“快”就觉得无所谓。并发度也就是队列深度。同一时刻磁盘面前堆了多少个IO请求在等决定了存储系统能不能用足硬件能力。延迟敏感度。有些应用要毫秒级响应多等几个毫秒用户就有感知有些应用只要吞吐量够高延迟宽得很这两类需求在方案选择上经常背道而驰。打个比方存储系统就是个快递仓库。读写比例决定仓库是以出库为主还是入库为主IO大小决定运的是小包裹还是集装箱随机还是顺序决定快递员是全城乱窜还是沿着一条线一路送并发度是仓库同时能接多少快递员的活儿延迟敏感度就是客户要求“五分钟出库”还是“今天到就行”。所有存储方案的纠结本质都是在这几个维度里找平衡。1.2 典型业务的IO画像差异不同业务系统的画像差异非常悬殊我做过几次典型环境的整理在线交易类数据库比如OLTP系统核心操作是日志顺序写和数据页随机刷基本都是4KB、8KB、16KB的小IO随机占比高并发大延迟极其敏感。这种负载看的是稳定低延迟和高IOPS对它谈“顺序带宽大”是鸡同鸭讲。大数据分析和离线批处理恰好反过来分区扫描为主动辄64KB到1MB的顺序读最怕带宽不够对IOPS反倒没那么敏感。视频监控、流媒体存储则是大块顺序写为主写多读少容量大、写入稳定猛延迟要求排最后。虚拟化平台最复杂一堆虚拟机混布IO大小从4KB到1MB全都有随机和顺序混在一起还要叠加快照、克隆这些额外开销这种环境选型如果只参考单一指标必然出问题。1.3 一张跑分表掩盖了什么新人最容易踩的坑就是迷信厂商给的“百万IOPS”“百微秒延迟”。这些数字都是特定IO特性下测出来的你真拿自己的业务上去跑如果负载类型对不上数字直接打折到没法看。我见过一台顺序读很猛的中端存储被拿去做8KB小随机写IOPS掉了快一个数量级延迟翻了好几倍。设备没坏是业务负载和存储的强项不匹配。所以说评估任何存储第一件事永远是确认“运行时的IO特点”而不是先问参数。2. 怎么把业务的IO特征摸清楚摸IO特性第一步不是拿工具去压盘而是先看生产负载到底什么样。我强烈建议任何一次存储性能优化之前先做一次完整的现状盘点。2.1 生产观测工具有哪些生产环境观测我常用的组合是这么几层系统层看整体用iostat、sar、pidstat能看出每块盘的每秒请求数、吞吐量、队列、响应时间。要更细粒度地看块层请求走向用blktrace或者用BCC工具集里偏openebpf的那一套能抓到每个进程发出来的IO请求长什么样。数据库侧结合慢日志和AWR这类报告去理解SQL层面对存储产生的IO模式。iostat是最容易上手的关键字段就那几个r/s、w/s表示每秒读写请求数rkB/s、wkB/s每秒吞吐avgqu-sz平均队列长度await平均响应时间util设备利用率。注意一点util到100%不一定代表盘不行有可能是IO调度把请求切得太碎盘一直在忙却出不了多少吞吐这种情况要结合r/s和w/s一起判断。2.2 采集时长和粒度踩过坑采集这里我栽过跟头。早年抓了10分钟数据正好赶上业务低谷画出来一片祥和把存储性能问题完全掩盖了。后来强行改成至少覆盖一个完整业务周期跑一周高峰期、低谷期、批量任务窗口都不敢落下。实在没时间也得抓满一个明显的高峰加一个低谷对比着看。采样粒度同样重要。iostat默认2秒一跳瞬时尖峰根本显不出来。我会压到1秒甚至500毫秒同时配合pidstat确认IO到底是哪个进程产生的。这一步很关键——我排查过不少“存储慢”的工单最后定位到某个应用进程在疯狂轮询写日志存储完全躺枪。2.3 IO大小分布是判断类型的关键看IO大小分布最靠谱的是blktrace。抓一段时间数据做汇总能看出请求集中在4KB、8KB还是256KB、1MB。这一步特别关键因为同样IOPS下4KB和1MB产生的带宽压力能差出256倍。不按大小说话性能瓶颈判断一定是歪的。我的判断方法比较直接4KB到16KB的小IO占比超过一半基本可以定性为小块随机负载优化时盯着IOPS和延迟64KB以上大IO占比高属于顺序或大块负载重点盯带宽。两种混在一起的情况就得分开统计峰值时段再决定要不要做分层或拆分。为了让大家直接落地我贴一组常用的观测命令# 1秒粒度看磁盘整体状态 iostat -x 1 # 定位是哪个进程在产生IO pidstat -d 1 # 更细粒度抓块层请求生产慎用有性能开销 blktrace -d /dev/sda -o trace blkparse -i trace -o trace.txt生产环境跑blktrace要克制块层跟踪本身有额外IO开销我一般只在性能排查窗口里开10到20分钟不长期挂。3. FIO压测把存储潜力真正测出来有了生产IO画像下一步就是压测验证存储到底能扛多大的压力。这个环节最关键的不是命令本身而是怎么把真实的IO特征翻译成测试参数。3.1 压测工具选型压测工具我主要用fio核心原因是参数直观、覆盖面够全。它支持的ioengine覆盖了libaio、io_uring、sync这些主流IO模型测不同并发模式很方便。别的基准工具我也试过但fio生态最好、踩坑答案最多新手上手也不至于太孤立。3.2 参数怎么定才不跑偏fio配参数的核心是把你从生产里摸到的IO画像变成一组数字。我一般这么取值块大小bs按生产IO大小分布来4K、8K、32K、64K、1MB都跑一遍别只压一个尺寸。读写模式rwrandread、randwrite、read、write、rw都测混合读写的比例用rwmixread来控制。队列深度iodepth按生产并发度来常见从16、32到64逐级加。并发进程numjobs模拟多应用同时发IO的场景不是越大越好。runtime建议单轮至少60秒以上短时间跑不出稳定态。看一个4K随机写的例子fio --nametest4krandwrite \ --rwrandwrite --bs4k --size8G \ --iodepth32 --numjobs4 --runtime120 \ --ioenginelibaio --direct1 \ --group_reportingdirect1表示绕过页缓存直接写盘测的是裸存储能力如果想测文件系统整体性能就把direct去掉但数字会掺杂文件系统缓存的影响。size设8G是为了连续写120秒时不至于把盘写满提前结束。这套参数测出来的就是“这台阵列在这种压力下的极限”而不是“缓存能扛多少”。3.3 别信单次数字要看延迟分布每次压测我都会跑好几轮取稳定值而不是一次峰值。IOPS这数字受冷热缓存、后台进程、文件系统状态干扰非常大单次高不代表稳定。压测结束后一定盯住fio输出的延迟分位数据clat和lat那几行P50、P99、P99.99都要看。做数据库的人最在意的其实是P99因为业务最怕“大部分时间挺好偶尔卡到飞起”平均延迟漂亮而99分位打飘的盘上线就是灾难。3.4 一套通用基准场景我把常用基准整理成一张表可以直接照着跑场景fio参数组合重点指标数据库小随机读bs8k, rwrandread, iodepth32IOPS、P99延迟数据库小随机写bs4k/8k, rwrandwrite, iodepth32IOPS、P99延迟顺序大块读bs1m, rwread, iodepth8带宽MB/s顺序大块写bs1m, rwwrite, iodepth8带宽MB/s混合读写bs16k, rwrw, rwmixread70IOPS、延迟、带宽这张表不是万能药但至少能覆盖绝大多数场景的初判需求。4. 从IO特性到优化落地压测数据出来不是收藏完事而是优化动作的开始。不同IO画像优化方向完全不同。4.1 写多场景的优化次序如果画像显示是写多的小随机负载第一件事是看缓存策略。很多存储阵列有写缓存和回写机制刷盘策略直接影响突发小写的表现。开启回写前一定要确认电池或UPS保护就位否则断电丢数据的风险不能承受。文件系统层面有些场景下关闭文件时间戳更新能减少大量元数据写IO。应用侧再往上看如果是数据库可以考虑合并日志文件、增大日志缓冲中间件改成批量提交也能显著减少小写次数。这些都属于不动硬件的优化成本最低优先级也最高。4.2 IO大小不对齐性能拦腰折遇到过太多IO大小分布散乱导致性能崩的案例。最常见的是文件系统分区起始位置没对齐或者虚拟化底层没做对齐结果一个4KB写请求实际落盘要触发读改写IOPS直接对半砍。排查可以用blktrace看请求分布如果出现大量原本应该是4KB的请求却碎成多个更小段下发多半是对齐问题。解决办法很简单分区时用特定对齐参数重新划分虚拟化存储池这类场景在后端开启顺序写优化。另外有些存储阵列开启压缩和去重反而能改善小块随机写的聚合度把多个4KB合成大块落盘。但压缩有CPU开销得实测收益再决定开不开。4.3 队列深度与延迟的平衡队列深度决定了存储端的并发度。盲目调大iodepth盘上堆的请求太多反而引起内部排队延迟。我认识一个做数据库的同事有次把应用连接池线程数直接翻倍IO并发上去了存储延迟也上去了整体吞吐反而下降。队列深度从来不是越大越好得结合盘片能力和业务可容忍延迟找拐点。找拐点的方法不复杂压测时分别跑iodepth8、16、32、64画出IOPS和延迟随深度变化的曲线。IOPS增长趋缓、延迟开始猛涨的那个点就是这台设备承载该负载的合理并发上限。找到之后把应用并发或存储端队列配置调到这个位置附近往往能让性能“再上一个台阶”。5. 常见问题与排查技巧实录整理几个高频问题都是我实际遇到并验证过解法的碰到同类情况可以少走弯路。5.1 IOPS很高应用依然慢压测IOPS高得吓人应用侧还是慢这种情况十有八九是出在延迟而不是吞吐。我发现很多场景下应用从发请求到存储响应中间隔了好几层虚拟化层、网络存储协议、存储内部缓存。物理盘IOPS足够但整条链路某层在排队导致P99飙升。排查时要一层层剥洋葱先看应用提交IO到操作系统的时间再看块层等待时间再到存储端看单盘响应延迟统计。哪一层跳变明显问题就在哪一层。5.2 只测了随机读忽略了写放大这属于新手常犯。带快照和纠删码的后端存储随机写会带来写放大一个4KB写请求可能实际产生两三倍的内部写入。只测随机读性能不测随机写等系统上线才发现写入扛不住就晚了。评估新存储时随机写测试要做足而且时长要适度拉长让垃圾回收之类的后台机制进入稳态数字才真实。短时间内跑出来的写性能很多是缓存红利不靠谱。5.3 看了带宽忽略了IOPS上限经典误区。有人说阵列带宽能到2GB/s为什么数据库还是慢一看IOPS上限几千。因为数据库全是8KB小写入带宽只用了不到10%IOPS却已经顶到头。带宽是相对顺序大块负载而言的指标小块请求数量看的是每秒请求数两者不能混着用。以后别人再跟你吹“存储很快”你反问一句“快在什么负载下”大概率能过滤掉一半以上的吹牛成分。5.4 测试参数复制粘贴害死人从网上拷一份fio参数就开跑是性能测试翻车的高发原因。别人的业务和你的业务IO特性不一样参数当然不同。我见过有人拿1MB顺序读的参数去测数据库存储跑出来一堆漂亮但完全没用的数字还当真了。参数一定要对着生产画像来bs、rw、iodepth、numjobs都得对得上业务流程。否则测的是设备的极限不是你的业务预算。5.5 后台任务干扰压测结果压测前没查后台有没有在跑备份、日志清理、快照合并属于低级错误但天天在犯。有一次线上压测波动巨大查了半天才发现是某个数据同步任务在凌晨自动启动。正确做法是压测前先确认没有定时任务有就停掉或者把压测窗口挪到任务之外。最后分享一个个人习惯任何一次性能评估我都把“业务IO画像”作为前置资料先回答清楚这个工作负载长什么样再谈存储该配置成什么样。IO characteristics和Storage Performance就像病因和症状不先看清病因光盯着症状换药大概率越治越乱。这两年最大的体会是性能问题靠一次压测跑分永远解决不了得靠长期、系统的观测积累出对业务的感知才能有的放矢地优化。这套方法不敢说能解决所有存储问题但至少能让你不用再拿着两份报告和同事踢皮球。下次再遇到“存储很慢”的投诉先问一句你的IO长什么样

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑