3. 数据库工作负载特征建模

数据库工作负载特征建模,本质上是把“业务在跑什么、怎么跑、跑多快”翻译成存储系统能够理解的一组量化输入。存储设计最怕的不是压力大,而是压力说不清:如果只知道“数据库有点慢”,就无法判断该加带宽、加 IOPS、降时延,还是该调整数据布局。因此,建模的目标不是做一份好看的报表,而是形成可指导 Pure Storage 阵列容量、性能、协议与保护策略设计的输入参数。

需要采集的核心指标通常包括六类:IO 大小、读写比例、队列深度、热点分布、并发连接数,以及由它们共同决定的IOPS 与带宽需求。这些指标并非孤立,而是相互耦合:IO 大小乘以 IOPS 就是带宽;队列深度与并发连接数共同影响时延表现;热点分布决定缓存与分层是否有效。下面这张图给出从采集点到设计输入的完整关系链。

数据库工作负载特征建模链路 采集 → 分析 → 参数化 → 存储设计输入 采集点 数据库 AWR / Statspack OS iostat / sar 存储端性能计数器 应用连接池监控 采样周期:1s / 5s / 1min 六类核心指标 IO 大小 8K / 16K / 64K 读写比例 读:写 = 7:3 队列深度 QD 4 ~ 64 热点分布 前 5% 数据占比 并发连接数 活跃会话数 IOPS / 带宽 峰值与均值 分析维度 峰值 / 均值 / P95 随机 vs 顺序 读缓存命中率 热点数据倾斜度 时间窗口:日 / 周 / 月 Pure Storage 存储设计输入 容量与精简比 按有效数据量规划 性能等级 IOPS / 时延目标 协议与连接 FC / iSCSI / NVMe 保护与快照 RPO / RTO 策略 验证与迭代:上线后对比实测与模型偏差,修正参数 关键换算:带宽(MB/s) = IOPS × IO大小(KB) ÷ 1024;时延 = 队列深度 ÷ (IOPS × 服务时间) 示例:8K 随机读、IOPS 120000 → 带宽约 937 MB/s

一、IO 大小:决定带宽与缓存效率的第一参数

IO 大小直接决定同样 IOPS 下需要多少带宽。数据库的 IO 大小通常呈现明显的分层特征:OLTP 以 8K 或 16K 随机小 IO 为主,数据仓库或批量作业则以 64K 到 1M 的顺序大 IO 为主。采集时不能只看平均值,必须看分布。例如某 Oracle 联机交易库,AWR 显示平均 IO 大小 12K,但进一步按等待事件拆分后发现,db file sequential read 集中在 8K,而 db file scattered read 集中在 128K。若只按 12K 规划,会低估大 IO 对带宽的瞬时冲击。

在 Pure Storage 上,IO 大小还影响数据缩减效果与缓存命中。小 IO 随机读更容易被全闪阵列的元数据缓存吸收,而大 IO 顺序写则更依赖后端带宽与写入合并。因此建模时应分别记录读 IO 与写 IO 的大小分布,而不是合并成一个数字。

二、读写比例:决定阵列读写路径与保护策略

读写比例是区分工作负载类型的关键。典型的 OLTP 读写比约为 7:3 或 8:2,日志写入集中且顺序;报表分析库可能读占 95% 以上;而批量导入场景写比例会短时飙升。读写比例不仅影响性能规划,还影响快照与复制策略:写密集库需要更关注写带宽和 NVRAM 缓冲,读密集库则更关注缓存容量与读时延。

采集读写比例时,建议同时记录“逻辑读写”与“物理读写”。数据库层的逻辑读可能被 Buffer Cache 吸收,真正落到存储的物理读才是设计依据。例如某 MySQL 实例逻辑读 50 万次/秒,但物理读仅 3 万次/秒,若按逻辑读规划存储,会严重过配。

三、队列深度与并发连接数:时延的隐藏变量

队列深度(Queue Depth)反映的是“同时有多少个 IO 在等待处理”,它和并发连接数不是同一个概念。并发连接数是应用侧同时活跃的数据库会话数,队列深度是这些会话实际发出的、尚未完成的 IO 数量。两者共同决定存储端看到的压力形态。一个常见的误区是:连接数很高但队列深度很低,说明应用在等数据库 CPU 或锁,而不是等存储;反之连接数不高但队列深度很高,说明单个会话在批量提交,存储时延会被放大。

在 Pure Storage 环境中,队列深度还影响时延曲线的拐点。全闪阵列在低队列深度下时延极低,但随着 QD 上升,时延会缓慢增长。建模时应记录峰值 QD 以及对应的 P95 时延,而不是只看平均时延。例如某库峰值 QD 为 48,P95 时延 0.8ms,均值时延 0.3ms,若按均值规划,会在业务高峰出现体验落差。

四、热点分布:决定缓存、分层与数据布局

热点分布回答的是“数据访问是否集中在少数对象上”。常见表现包括:某几张核心表占 80% 的读 IO;某张流水表的最新分区承担绝大部分写入;索引热块集中在少数叶块。热点分布直接决定 Pure Storage 的缓存效率、是否需要对特定卷做独立性能策略,以及是否需要通过分区、归档或读写分离来打散压力。

采集热点分布时,可以从数据库侧获取段级或对象级 IO 统计,再与存储侧卷级统计对齐。例如某订单库中,orders 表及其索引占该卷 72% 的读 IO,而该卷总容量 2TB,热数据实际不足 80GB。这种“小热数据、大冷容量”的结构,非常适合利用全闪阵列的缓存与精简能力,而不必为全部容量配置同等性能。

五、从指标到设计输入:一个可复用的建模示例

下面给出一个简化的建模记录表,用于把采集结果整理成存储设计输入。表中数据为教学示例,实际项目应以真实采集值为准。

指标 采集值(示例) 分析结论 存储设计输入
IO 大小 读 8K 占 85%,写 64K 占 70% OLTP 随机小读 + 顺序日志写 读 IOPS 优先,写带宽按 64K 估算
读写比例 物理读:写 = 7:3 读密集,缓存收益高 加大读缓存策略,写路径关注 NVRAM
队列深度 峰值 QD 48,P95 时延 0.8ms 高峰时延敏感 性能等级按 P95 时延 ≤1ms 设计
热点分布 前 5% 对象占 72% 读 IO 热数据集中,冷容量大 利用精简与缓存,容量按有效数据规划
并发连接数 活跃会话 300,峰值 650 连接数高但 QD 中等 协议连接数按 800 预留,避免前端瓶颈
IOPS / 带宽 峰值 120K IOPS,约 937 MB/s 带宽与 IOPS 双高 按峰值 1.2 倍冗余规划阵列性能

完成建模后,还需要做一次交叉验证:把存储侧实测的 IOPS、带宽、时延与模型预测值对比。如果偏差超过 20%,应回到采集环节检查采样窗口是否覆盖业务高峰、是否遗漏了批量作业或备份流量。建模不是一次性动作,而应在上线后持续迭代,把实测结果反哺到参数中,使下一轮设计更准确。

采集窗口建议至少覆盖一个完整业务周期(如一周),并单独标记月末结账、批量导入、备份窗口等特殊时段,避免用平均值掩盖峰值特征。
不要把数据库逻辑读直接当作存储物理读。逻辑读可能被 Buffer Cache 吸收,只有物理读才真正落到存储。混淆两者会导致容量与性能严重过配。