跳到正文

背压

Backpressure

高级通用

背压(Backpressure)是下游处理不过来时,把处理能力的限制传回上游,让上游减慢、暂停或停止继续发送数据的机制。它解决的是生产速度长期超过处理速度时,队列越积越多、内存被耗尽的问题,例如文件导入时让读取速度跟上数据库写入速度。

你可能会说:「导入文件时,数据库写得慢就先别继续读,别让待写的数据一直堆在内存里。」

读之前建议先了解(这是一个高级概念)

动手看看

文件读取端缓冲队列2 / 10数据库写入端正常写入
1

读取端从文件读出记录送进队列,写入端同步取走写进数据库。两边速度相当,队列几乎是空的。

要点

  1. 1

    先找出谁生产谁消费

    你可以把数据流看成相连的几段:文件读取产生记录,校验处理记录,数据库接收写入。只要前一段持续比后一段快,没处理的记录就会积压。背压要让前一段知道:后面暂时接不动了。

  2. 2

    让上游跟着处理能力走

    下游可以通过接收窗口、队列容量或等待信号表达自己还能接多少。上游收到限制后放慢或暂停,等下游腾出空间再继续。具体信号因框架而异,关键是上游确实会响应,而不只是把数据搬到另一个队列里。

  3. 3

    确认压力最终停在哪里

    做文件导入时,暂停读取通常能让数据暂留在文件中;但如果上游是不能暂停的外部请求,就得决定何时拒收、丢弃或写入可承受的持久化队列。你要问清楚积压会停在哪里,以及满了以后怎么办。

容易混淆的地方

背压管的是一条处理链上「下游接不动时,上游如何减速」;速率限制通常按预设规则控制请求进入,不一定反映下游此刻的处理能力。消息队列能暂存任务,但仅仅加个队列不是背压:如果生产速度长期更快,队列仍会堆满,还需要限制生产或明确满载策略。

什么时候用

适合用

  • 做大文件导入时,读取和解析比数据库写入快,需要让读取随写入进度暂停和恢复。
  • 做 AI 流式输出的中转服务时,客户端接收慢,需要限制服务端继续缓存响应片段。
  • 后台消费者处理消息的速度波动大,需要根据未完成任务量控制继续拉取的数量。

不适合用

  • 只是想限制每个用户每分钟能调用多少次 API,用速率限制更直接;这不是下游处理速度传回上游的问题。
  • 后台任务量很小且偶尔才触发,现有处理方式没有积压风险时,先保持简单的任务处理流程即可。
  • 请求失败是因为依赖服务已经不可用,而不是处理速度跟不上时,优先考虑超时、熔断或故障恢复。

练一练

你在做 CSV 导入:文件读取很快,数据库写入较慢,待写记录持续占用更多内存。哪种改动最符合背压的思路?

让 AI 帮你做

请为 CSV 导入流程加入背压:限制同时待写入数据库的记录数,达到上限时暂停文件读取,写入完成后恢复。说明缓冲区满时的行为,并补测试验证慢速写入下待处理记录数不会持续增长。

接下来学什么