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 版本号原章节未标明,使用前请对照你所用的版本。