SLA指标设计:延迟、吞吐量、新鲜度与完整性

好,咱们直接进入正题。SLA指标设计这块,我见过太多团队一上来就拍脑袋定指标,结果上线后天天被用户追着骂。说白了,指标定不好,后面所有保障都是空中楼阁。

今天重点聊四个核心指标:延迟、吞吐量、数据新鲜度、数据完整性。这四个指标,基本覆盖了实时数据产品90%的SLA场景。

核心原则:指标不是越多越好,关键是可测量、可预警、可追溯。你定一个无法监控的指标,等于没定。

实时数据产品SLA四维指标 SLA 指标体系 延迟指标 吞吐量指标 数据新鲜度 数据完整性 四个指标相互关联,延迟升高往往导致新鲜度下降,吞吐量过载可能影响完整性

延迟指标:P99与P999的真相

延迟指标,我习惯把它叫做「用户体验的体温计」。很多人一上来就盯着平均延迟,这其实是个坑。平均延迟会掩盖很多问题。

举个例子:你系统平均延迟50ms,但P99延迟可能已经飙到2秒了。这意味着1%的用户在忍受2秒以上的等待。对于实时场景,这1%可能就是核心用户。

指标 含义 适用场景 常见阈值
P50(中位数) 50%请求在此时间内完成 日常健康度监控 < 100ms
P95 95%请求在此时间内完成 一般业务SLA < 500ms
P99 99%请求在此时间内完成 核心交易、实时风控 < 1s
P999 99.9%请求在此时间内完成 金融、医疗等高敏场景 < 3s

我的经验:P99和P999不要同时定死。我建议先定P99,等系统稳定后再加P999。否则运维同学会疯掉——为了那0.1%的请求,成本可能翻3倍。

延迟指标的采集方式也很关键。我见过有人用应用日志算延迟,结果日志本身就有延迟。正确的做法是在网关层打埋点,用独立链路追踪。

// 延迟指标采集示例(伪代码)
public class LatencyCollector {
    // 建议在API网关层统一采集
    public void recordLatency(String apiName, long startTime) {
        long cost = System.currentTimeMillis() - startTime;
        // 按百分位存储,不要直接算平均值
        latencyBucket.add(apiName, cost);
        
        // 超过P99阈值立即告警
        if (cost > p99Threshold) {
            alertService.send("延迟告警: " + apiName + " 耗时 " + cost + "ms");
        }
    }
}

吞吐量指标:别被峰值骗了

吞吐量指标,说白了就是系统能扛多少并发。但这里有个常见的误区——很多人只看峰值吞吐量。

我记得有一次帮一个电商团队排查问题。他们号称系统能支持10万QPS,结果大促时5万QPS就把系统打垮了。为什么?因为他们的10万QPS是在理想网络环境下测的,实际生产环境有网络抖动、GC停顿、慢查询等各种干扰。

我建议吞吐量指标分三层来定:

  • 基准吞吐量:系统持续稳定运行的流量,通常取P50
  • 弹性吞吐量:系统能短暂扛住的峰值,通常持续不超过5分钟
  • 熔断阈值:超过这个值直接降级,保护后端

避坑指南:我曾经见过一个团队,吞吐量SLA定的是「平均10万QPS」。结果业务方投诉说系统经常超时。一查才发现,平均10万QPS的背后,是白天5万、晚上15万。晚上的15万已经把系统压垮了。所以,吞吐量指标一定要按时间窗口分段定义。

数据新鲜度指标:实时到底有多实时?

「实时」这个词被用烂了。很多产品号称实时,实际上延迟了5分钟。数据新鲜度指标,就是用来量化这个「实时」的。

我习惯把新鲜度分为三个等级:

  1. 秒级新鲜度:数据产生到可查询,延迟在3秒以内。适用于实时风控、实时推荐。
  2. 准实时新鲜度:延迟在30秒到5分钟。适用于报表、监控大屏。
  3. 近实时新鲜度:延迟在5分钟到30分钟。适用于离线分析、T+0报表。

新鲜度的测量方式,我推荐用「数据时间戳 vs 系统处理时间戳」的差值。举个例子:

// 数据新鲜度计算
public long calculateFreshness(DataRecord record) {
    // record.getEventTime() 是数据产生时间
    // System.currentTimeMillis() 是当前处理时间
    long freshness = System.currentTimeMillis() - record.getEventTime();
    
    // 如果新鲜度超过SLA阈值,记录慢链路
    if (freshness > freshnessThreshold) {
        slowPathLogger.warn("数据延迟过大: eventTime={}, freshness={}ms", 
            record.getEventTime(), freshness);
    }
    return freshness;
}

关键点:数据新鲜度指标必须依赖业务时间戳,而不是系统接收时间戳。否则你无法区分「数据真的来晚了」还是「数据本身产生就晚」。

数据完整性指标:丢了数据等于没做

数据完整性,是我认为最容易被忽视的指标。很多团队把延迟和吞吐量做得很好,结果数据丢了都不知道。

完整性指标的核心是「端到端对账」。我建议至少做三层校验:

校验层级 校验方式 校验频率 告警阈值
消息队列层 生产端与消费端消息数对比 每分钟 丢失率 > 0.01%
数据库层 写入行数与预期行数对比 每小时 丢失率 > 0.001%
业务层 业务主键去重校验 每天 重复率 > 0.1%

我曾经遇到过一个案例:某实时数仓每天凌晨都会丢一批数据,但监控一直没发现。为什么?因为他们只监控了消息队列的消费延迟,没做端到端对账。后来加了完整性校验,才发现是凌晨的Kafka rebalance导致部分分区消费失败。

我的建议:完整性指标一定要做「双轨校验」。一条轨是实时流计算,另一条轨是离线批处理。两条轨的结果做交叉比对,任何偏差都要告警。虽然成本高一点,但数据安全无小事。

四个指标的联动关系

最后说一个容易被忽略的点:这四个指标不是孤立的。它们之间会互相影响。

  • 延迟升高 → 数据堆积 → 新鲜度下降
  • 吞吐量过载 → 系统限流 → 部分数据丢失 → 完整性受损
  • 完整性校验太频繁 → 增加系统负担 → 延迟升高

所以,设计SLA指标时,一定要考虑指标间的权衡。我个人的做法是:先保完整性和新鲜度,再优化延迟和吞吐量。数据都丢了,快有什么用?

总结一句话:延迟看P99,吞吐量看弹性,新鲜度看时间戳,完整性看对账。四个指标联动设计,才能构建真正可靠的实时数据产品SLA。