首页 > 解决方案 > gRPC 中的高吞吐量低延迟一元调用指南

问题描述

我正在寻找指南以最大限度地提高吞吐量并最大限度地减少 gRPC 一元调用的延迟。我需要达到大约 20,000 QPS,每个 < 50ms。在中等硬件(4 核 CPU)上,我只能实现大约 15K QPS,平均延迟为 200 毫秒。我正在使用 Java 客户端和服务器。服务器除了返回响应之外什么都不做。客户端使用异步存根发送多个并发请求。并发请求的数量是有限的。CPU 保持在 ~80% 的范围内。相比之下,使用 Apache Kafka 我可以实现更高的吞吐量(数千个 QPS)以及 10 毫秒范围内的延迟。

标签: grpcgrpc-java

解决方案


如果您使用的是 grpc-java 1.21 或更高版本,并且grpc-netty-shaded您应该已经在使用 Netty Epoll 传输。如果您正在使用grpc-netty,请添加运行时依赖项io.netty:netty-transport-native-epoll(可以通过查看grpc-nettypom.xml 或SECURITY.md 中的版本表找到正确的版本)。

回调的默认执行器是“缓存线程池”。如果您不阻塞(或知道阻塞的限制),指定固定大小的线程池可以提高性能。Executors.newFixedThreadPool你可以同时尝试ForkJoinPool; 我们已经看到“最佳”选择因工作量而异。ServerBuilder.executor()你通过and指定你自己的执行者ManagedChannelBuilder.executor()

如果您有高吞吐量(使用 TLS 的每个客户端约 Gbps+;如果是纯文本则更高)使用多个通道可以通过使用多个 TCP 连接来提高性能。每个 TCP 连接都固定到一个线程,因此拥有更多 TCP 连接允许使用更多线程。您可以创建多个频道,然后对它们进行循环;为每个 RPC 选择不同的。请注意,您可以轻松地实现Channel接口以“隐藏”应用程序其余部分的复杂性。这看起来会特别为您提供很大的收益,但我把它放在最后,因为它通常不是必需的。


推荐阅读