Stream.buffer 满了之后,该选哪种策略?

给 Stream 加了 buffer 之后,缓冲区总有满的时候;满了之后要么让上游等,要么直接丢数据,二者对业务的含义完全不同。

默认的 suspend 不丢数据,订单、支付这类不能丢的数据用它;dropping 丢新来的、sliding 丢最旧的,只适合「只关心最新状态」的场景,比如实时指标。

这是因为默认的拉取是紧耦合的:下游没要,上游就不动(背压的来龙去脉见Effect 的 Stream 是什么,背压为什么能让内存有界)。Stream.buffer({ capacity }) 让生产者可以提前跑一点,抹平速度的小抖动,但它不是免费的。

三种策略分别做什么?

  • 默认的 suspend:满了就让上游等,仍然是背压,数据不会丢。
  • dropping:满了丢新来的。
  • sliding:满了丢最旧的。

什么场景选哪一种?

后两种是明确地用丢数据换不阻塞,适合「只关心最新状态」的场景(比如实时指标),不适合订单、支付这类不能丢的数据。选哪一种是业务决定,不是性能调优。

加 buffer 能让慢消费者变快吗?

不能。buffer 只是移动了等待发生的位置;如果消费者持续慢于生产者,缓冲区终究会满,要么阻塞要么丢数据。

缓冲区之外,还有别的办法吗?

消费者慢,更直接的办法是提高处理阶段的并发,例如给 Stream.mapEffect 指定 concurrency(取舍见并发),或者用 Stream.groupedWithin 成批写入。

本文整理自本站 Effect 教程中关于 Stream 的章节,没有在本地重新运行;三种策略的名称与行为以该章节的描述为准,具体 effect 版本号原章节未标明,使用前请对照你所用的版本。