4. 性能调优目标:延迟、吞吐量、错误率、资源利用率与 SLO/SLI
性能调优不是盲目地“调快系统”,而是围绕一组明确的、可量化的目标进行迭代。在 SRE 实践中,这些目标通常被归纳为四个核心指标维度,并通过 SLO(Service Level Objective,服务等级目标)与 SLI(Service Level Indicator,服务等级指标)进行契约化管理。
4.1 性能调优的四大常见目标
任何在线系统的性能都可以从以下四个维度进行度量与优化。它们相互关联,但优化时往往需要根据业务优先级进行权衡。
| 维度 | 定义 | 典型指标 | 调优方向 |
|---|---|---|---|
| 延迟 (Latency) | 请求从发出到收到完整响应所花费的时间 | P50、P95、P99 延迟 | 减少排队、优化算法、降低网络往返 |
| 吞吐量 (Throughput) | 系统在单位时间内成功处理的请求数量 | RPS、TPS、QPS | 增加并发、消除瓶颈、提升资源效率 |
| 错误率 (Error Rate) | 失败请求占总请求数的比例 | HTTP 5xx 率、超时率、异常率 | 修复代码缺陷、处理超时、增强容错 |
| 资源利用率 (Resource Utilization) | 系统资源(CPU、内存、磁盘、网络)被消耗的程度 | CPU 使用率、内存占用、磁盘 IOPS | 消除浪费、合理分配、弹性伸缩 |
调优权衡提示: 降低延迟通常需要增加资源(如缓存),从而降低资源利用率;提升吞吐量可能增加排队延迟。调优的核心是在四个维度间找到符合 SLO 的平衡点。
4.2 从指标到契约:SLI 与 SLO
仅有原始指标还不够,SRE 通过 SLI 和 SLO 将性能目标转化为可度量、可告警、可问责的契约。
- SLI(服务等级指标):对服务质量某个方面的量化度量。它是原始指标经过“好/坏”判定后的比率。例如:“所有请求中,延迟低于 200ms 的请求占比”。
- SLO(服务等级目标):为 SLI 设定的目标值或范围。它是团队承诺的服务水平边界。例如:“99.9% 的请求延迟应低于 200ms”。
下面这张图展示了从原始指标到 SLO 告警的完整链路:
4.3 SLI 的常见定义方式
定义 SLI 时,需要明确“什么是好的请求”。以下是一些典型服务的 SLI 定义示例:
| 服务类型 | SLI 维度 | SLI 定义(好请求标准) |
|---|---|---|
| HTTP API | 延迟 | 所有请求中,服务端处理时间 ≤ 300ms 的请求占比 |
| HTTP API | 错误率 | 所有请求中,返回 HTTP 状态码非 5xx 的请求占比 |
| 数据库查询 | 延迟 | 所有查询中,P99 查询延迟 ≤ 1s 的请求占比 |
| 消息队列 | 吞吐量 | 所有消息中,从生产到消费延迟 ≤ 5s 的消息占比 |
| CDN 缓存 | 资源利用率 | 所有请求中,缓存命中率 ≥ 90% 的请求占比 |
SLI 定义最佳实践:
- 基于用户视角: SLI 应反映用户实际体验,而非内部组件健康度。
- 使用比率: 将原始指标转化为“好请求 / 总请求”的比率,便于设定 SLO。
- 区分维度: 延迟、错误率、吞吐量应分别定义独立的 SLI,避免混合。
4.4 SLO 的设定与燃烧速率
SLO 不是“100%”,因为追求 100% 的可靠性成本极高且不现实。合理的 SLO 通常设定在 99.9% 到 99.99% 之间。SLO 的核心价值在于为告警提供“燃烧速率”依据。
燃烧速率 (Burn Rate) 是指 SLO 被消耗的速度。例如,一个 99.9% SLO 的服务,在 30 天内最多允许 0.1% 的请求失败。如果实际错误率达到 1%,则燃烧速率为 10x(即 SLO 消耗速度是预期的 10 倍)。
下面这张图展示了不同燃烧速率下的告警窗口策略:
常见误区: 不要将 SLO 直接设置为告警阈值。例如,SLO 为 99.9% 时,不应在错误率达到 0.1% 时才告警,因为此时 SLO 已经被违反。正确的做法是设置一个更严格的“告警阈值”(如 0.05% 错误率),或使用燃烧速率在 SLO 被消耗到一定程度时提前告警。
4.5 性能调优目标与 SLO 的关联
性能调优的最终目标不是让某个指标“好看”,而是确保系统在 变更窗口 内持续满足 SLO。这意味着:
- 延迟调优:确保 P99 延迟始终低于 SLO 中定义的阈值。
- 吞吐量调优:确保在峰值负载下,系统仍能维持 SLO 要求的吞吐量,且不导致延迟或错误率超标。
- 错误率调优:将错误率控制在 SLO 允许的燃烧预算内。
- 资源利用率调优:在满足前三个 SLO 的前提下,最大化资源效率,降低成本。