Skip to content

模型Model

字节流缓冲与端到端背压

Stream backpressure · Bounded buffer · Partial write

按实际短写推进未发送前缀,用有界队列与高低水位传播消费压力,并区分就绪、完成与业务成功。

形式陈述 ​

背压是下游资源或消费能力不足时,限制上游继续生产或接收的机制。TCP只管理传输层缓存及窗口;应用自己的队列、解析器、工作任务和响应缓存,也都需要容量合同。把数据从内核搬进无限应用队列,只是移动压力,没有消除它。

一个发送器维护待发送字节队列Q、容量C和当前块的已接受前缀位置k。新数据只能在总占用不超过C时加入;send返回正数n时,只移除本次缓冲的前n字节,继续保留未接受后缀。EAGAIN保持队列不变并等待下次可写机会;不可恢复错误进入失败状态,向调用者交代剩余与已接受前缀。对非空写入意外得到0时,应走接口规定的无进展处理,不能在原地忙循环。

接收端可设置高水位H和低水位L,满足 0≤L<H≤C。占用达到H就暂停上游读取或任务准入;消费降到L再恢复,避免在同一个阈值附近频繁切换。每次实际读取或接受任务仍要检查剩余容量;水位通知不是允许一次大批输入突破C的理由。计算内存时应计对象首部、编码副本和在途任务,而非只计载荷。

就绪表示某操作此刻可能无需阻塞地推进,不保证整块数据都能完成;状态可能在执行前改变,实际返回值仍是依据。背压应沿生产链传播,若一层选择丢弃或拒绝而非等待,必须把这项语义明确告知上游。

直觉

有限缓冲像蓄水池,背压是水位升高时关小上游阀门。换一个更大的池子能多撑一会儿,却不能长期容纳“进水大于出水”。

已经交给本地TCP的前缀与仍在应用队列的后缀必须分清。如果短写后从整块开头重发,TCP会忠实传送重复前缀,无法知道这是应用自己的重试错误。

例子与边界

发送目标ABCDEFGH,初始未发送Q=ABCDEFGH。第一次send返回3,Q变DEFGH;下一次EAGAIN,Q仍DEFGH;第三次返回2,Q变FGH;最后返回3,Q空。四次调用中三次有进展,本地接受的总串恰为ABCDEFGH。若第三次又传ABCDEFGH,重复的是应用流内容,不是TCP可以按原序号去掉的网络重传。

另一条独立接收轨迹固定C=8字节、H=6、L=2,计费对象就是缓存字节。到达6字节后占用6,暂停继续读取;消费者取走3字节,占用3,仍暂停;再取1字节,占用2,恢复。下一次即使网络有10字节可读,最多接受剩余6字节,保持占用≤8。若解析器要求完整9字节帧才能交付,而总可用帧缓存只有8,又不支持流式消费,这个配置无法完成该帧;水位正确也不能修复容量合同矛盾。

高水位还须与分帧协同。即使C=8足以保存一条8字节完整帧,若收到6字节便暂停,消费者又必须等满8字节才取走,双方也会互等。可先为已准入帧预留完整预算,并允许该帧在容量内收完,只暂停新帧准入;或采用有界流式消费。不能无条件把逐字节高水位规则套到“只消费完整帧”的队列。

两端若都要先写完超过对端缓存的大消息,再开始读对方响应,可能相互等在写操作上。解决方向是协议允许交错收发、分块与并行推进,而不是把某个send设成“永远等到成功”。每种做法还要继续维护消息顺序和资源上限。

推论与应用

在简化连续速率模型中,生产速率为λ、消费速率为μ且λ>μ,初始空、容量C的缓冲约在 C/(λ−μ) 时间后填满。这个公式忽略突发和调度,作用是说明有限容量只能吸收短期差额;稳定系统必须反馈减速、拒绝、丢弃或增加真实消费能力。

发送队列排空只说明所有字节已被本地传输接口接受。它不证明远端read完成,更不证明业务提交。对整个调用还需要总期限,否则一个有界而永远等待的队列虽不耗尽内存,仍可能永久占用连接和任务槽。

在非阻塞就绪事件循环中,预算耗尽后仍须保存续执行,容量不足则离开运行队列但保留hint,消费者释放容量再重排;只有实际EAGAIN才撤销本模型的可推进提示。该页把本页的帧容量预留接到ET通知之后,避免有剩余字节却再也不被调度。

参考资料
  • POSIX.1-2024,send、recv:实际返回长度、非阻塞无进展以及发送成功不保证交付。
  • Peterson、Davie,Computer Networks: A Systems Approach,§5.2.4:应用填充/排空缓冲与流控。高低水位和容量账本是本页独立指定的应用模型。
关系图谱7 个相邻概念 · 1 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组