qinghuan
← 回到知识探索

后端现场 / 动手实验

队列有两千条,还要等多久?

先画清进入和离开的范围,再看 Little 法则能回答什么。

展开本文目录
  1. 先规定哪些任务算在里面
  2. 用三个任务核对“人数乘时间”
  3. 持续积压时,先看进出差额
  4. 同时观察任务数量和最老任务
  5. 记住这三点
  6. 别把例子用过头
  7. 自己试一小步
  8. 查原始资料
  9. 找一份资料继续练
开始前,会这些就够了
  • 理解平均数和每秒速率
遇到不熟悉的词,先看这 4 个解释
重试
遇到可能只是暂时性的失败后,按预定规则再次尝试同一项操作;规则通常限制次数、等待间隔和总耗时,也要考虑重复执行会不会多做一次业务。
缓存雪崩
大量缓存同时失去作用后,本来被缓存接住的请求集中转到后端,可能让数据库和依赖服务接连过载;常见诱因是许多条目在相近时间到期。
吞吐量
单位时间内处理的工作数量,例如每秒完成多少请求或每分钟处理多少任务;比较前要写清统计窗口、工作类型,以及失败的尝试是否也被计入。
队列
把暂时不能立即处理的任务或消息先保存起来,等处理方取走;它把提交与执行分开,可以缓冲短时忙碌,但等待中的数量也会占用资源。
打开完整术语小抄 ↗

假设图片处理服务积压了两千个任务,同事拿“每秒进来一百个”一除,宣布二十秒就能清完。这个算式很诱人,却没有说明处理速度,也没有说明新任务会不会继续到来。队列是存量,进入速率和完成速率是两股流,三者不能混成一个数字。

先规定哪些任务算在里面

Little 法则常写成 L = λW:长期平均在系统里的任务数,等于进入该系统的有效平均速率,乘以任务在其中的平均停留时间。比如假设稳定服务每秒完成一百个请求,每个请求从接纳到完成平均停留零点二秒,那么系统内平均约有二十个请求。

这二十个包含等待和正在处理的请求,不等于必须开二十个工作线程。如果只统计排队区,W 也只能使用排队等待时间。被入口拒绝而未进入系统的请求,不能计进这里的有效到达率;把不同范围的数据相乘,单位可能正确,意思却已经错了。

用三个任务核对“人数乘时间”

下面是三个假设任务的进入、离开时间,单位为秒。程序先按每段时间有多少任务留在系统里计算平均数量,再独立计算吞吐量和平均停留时间。观察窗口从零到六秒,开始前为空,结束时全部离开,因此没有只算了一半的任务。

这个有限窗口的完整记账可以直接核对等式,不需要假定随机到达或固定处理时长。实际监控窗口常切过任务:有些在窗口前进入,有些结束后才离开。如果只拿窗口内完成的任务计算平均停留时间,未必能与窗口内的平均任务数量对应。使用长期稳定的平均值是常见办法,同时仍要检查这些数量和时间是否来自同一系统范围,并采用可比的观察时段。

小实验 · python
jobs = [(0, 2), (1, 4), (2, 6)]
points = sorted({t for job in jobs for t in job})
area = 0
for left, right in zip(points, points[1:]):
    middle = (left + right) / 2
    count = sum(start <= middle < end for start, end in jobs)
    area += count * (right - left)
window = 6
L = area / window
rate = len(jobs) / window
W = sum(end - start for start, end in jobs) / len(jobs)
print("L", L, "rate", rate, "W", W)
print("rate * W", rate * W)

怎样运行:Python 3.10+;保存为 queue_demo.py,运行 python queue_demo.py。

运行后对照结果
L 1.5 rate 0.5 W 3.0
rate * W 1.5

持续积压时,先看进出差额

假设每秒接纳一百个任务,只能完成八十个,没有取消或丢弃,积压就每秒增加二十个。此时不能把某一刻的任务数量塞进稳定平均公式,声称系统已经达到平衡。即使增加队列容量,也只是允许更多任务继续等着,并没有提高完成速率。

若新任务停止进入,且处理速度一直稳定为每秒八十个,才可以用剩余工作量估算清空时间;任务大小不同、重试、多个队列优先级或处理速度变化,都会影响结果。任务数量相同也不一定工作量相同,一张小图与一段长视频就不能等价计算。

同时观察任务数量和最老任务

平均数量可能掩盖少数任务一直被饿着的情况,所以还要看最老任务已经等多久、完成吞吐量、失败重试数量,以及新旧任务是否争用同一资源。Little 法则是核对平均量关系的工具,不会告诉你某一个请求何时完成,也不会自己找出瓶颈。

需要缩短等待时,可以减少接纳、提高实际处理能力,或减少每个任务的工作量;若改成丢弃、合并或取消,也要把这些离开方式记在统计里。先把“谁进来、谁离开、在里面多久”记明白,扩容建议才有可以检验的依据。

记住这三点

  • L、λ、W 必须使用同一个系统范围和兼容的统计口径。
  • 瞬时积压与长期平均在途数量不是同一个量。
  • 队列更大不会自动增加完成能力,还要观察任务年龄。

别把例子用过头

  • 本例的完整有限窗口避免了边界任务,线上窗口通常需要额外处理。
  • 法则不直接给出个体等待时间或尾延迟,也不替代容量模型。

自己试一小步

如果观察只到第四秒,而第三个任务尚未完成,怎样记录才不会漏算它的占用?

  1. 在纸上把三个任务画成横向时间段。
  2. 将窗口截为零到四秒,分别计算窗口内占用面积和已完成任务平均耗时。
  3. 列出两组数字不再能随意配对的原因。

做到这些,就算完成

  • 区分完整停留时间与窗口内占用时间。
  • 说明队列范围是否包括正在处理的任务。
  • 没有用一个瞬时队长证明系统长期稳定。

查原始资料

想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。

  • Class 3: Capacity Lecture (新标签页)↗MIT OpenCourseWare · 英文

    PDF 第 17 页展示 L = λW、系统平均数量、平均停留时间与流量平衡;讲义区分确定性和突发到达。

    公开英文 PDF,共 22 页;课程目录标为 2004 年,讲义页脚署年为 2002。

  • Queueing Lecture Notes (新标签页)↗MIT OpenCourseWare · 英文

    PDF 第 3–4 页分别定义系统内数量与排队数量、总停留与排队等待,并列出队列模型的稳定性前提。

    公开英文 PDF,共 7 页;课程目录为 Spring 2005,材料页脚为 Spring 2004。

找一份资料继续练

先选一项,按下面的范围继续学;不必从头读完整门课程。