gRPC中高吞吐量低延迟一元调用的准则

时间:2019-10-17 00:45:04

标签: grpc grpc-java

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

1 个答案:

答案 0 :(得分:1)

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

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

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