gpt4 book ai didi

spring-webflux - Reactive Redis (Lettuce) 总是发布到单线程

转载 作者:行者123 更新时间:2023-12-04 04:27:13 31 4
gpt4 key购买 nike

我正在使用 Spring Webflux(带有 spring-reactor-netty)2.1.0.RC1 和 Lettuce 5.1.1.RELEASE。

当我使用 Reactive Lettuce API 调用任何 Redis 操作时,执行总是切换到同一个单独的线程 (lettuce-nioEventLoop-4-1)。

这导致性能不佳,因为所有执行都在该单个线程中成为瓶颈。

我知道我可以使用 publishOn每次我调用 Redis 切换到另一个线程时,但这很容易出错并且仍然不是最佳的。

有什么办法可以改善吗?我看到 Lettuce 提供了 ClientResources 类来自定义线程分配,但我找不到任何方法将它与 Spring webflux 集成。

此外,对于粗心的开发人员来说,当前的行为会不会很危险?也许应该稍微调整一下默认值。我想理想的情况是 Lettuce 可以重用来自 webflux 的相同事件循环。

我正在添加这个 Spring Boot 单类片段,可用于重现我所描述的内容:

@SpringBootApplication
public class ReactiveApplication {
public static void main(String[] args) {
SpringApplication.run(ReactiveApplication.class, args);
}
}

@Controller
class TestController {

private final RedisReactiveCommands<String, String> redis = RedisClient.create("redis://localhost:6379").connect().reactive();

@RequestMapping("/test")
public Mono<Void> test() {
return redis.exists("key")
.doOnSubscribe(subscription -> System.out.println("\nonSubscribe called on thread " + Thread.currentThread().getName()))
.doOnNext(aLong -> System.out.println("onNext called on thread " + Thread.currentThread().getName()))
.then();
}

}

如果我继续调用 /test端点我得到以下输出:
onSubscribe called on thread reactor-http-nio-2
onNext called on thread lettuce-nioEventLoop-4-1

onSubscribe called on thread reactor-http-nio-3
onNext called on thread lettuce-nioEventLoop-4-1

onSubscribe called on thread reactor-http-nio-4
onNext called on thread lettuce-nioEventLoop-4-1

最佳答案

这是一个很好的问题!

TL;DR;

Lettuce 总是使用绑定(bind)到 netty channel 的 I/O 线程发布。这可能适合也可能不适合您的工作量。

更长的阅读时间

Redis 是单线程的,因此保持单个 TCP 连接是有意义的。 Netty 的线程模型是所有 I/O 工作都由 EventLoop 处理。绑定(bind)到 channel 的线程。由于这个星座,您在同一个线程上接收所有反应信号。使用具有各种选项的各种 react 序列对影响进行基准测试是有意义的。

不同的使用方案(即使用池连接)直接改变观察到的结果,因为池使用不同的连接,因此在不同的线程上接收通知。

另一种选择是提供 ExecutorService仅用于响应信号(数据、错误、完成)。在某些情况下,由于消除了 I/O 线程中的拥塞,上下文切换的成本可以忽略不计。在其他情况下,上下文切换成本可能更显着。

您已经可以使用 WebFlux 观察到相同的行为:每个传入连接都是一个新连接,因此它由不同的入站 EventLoop 处理线。在将 HTTP 响应写入 channel 时,将相同的 EventLoop 线程重用于出站通知(用于入站通知的那个)发生的时间很晚。

这种职责的双重性(完成命令、执行 I/O)可能会对计算量更大的工作负载产生一定的影响,从而将性能从 I/O 中拖出。

其他资源:

  • Investigate on response thread switching #905 .
  • 关于spring-webflux - Reactive Redis (Lettuce) 总是发布到单线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53001283/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com