我正在寻找准则来最大化吞吐量和最小化gRPC一元调用的延迟。我需要达到大约20,000 QPS,每个<50毫秒。在中等硬件(4核CPU)上,我只能达到大约15K QPS,平均延迟为200ms。我使用的是Java客户端和服务器。服务器除了返回一个响应之外什么也不做。客户端使用异步存根发送多个并发请求。并发请求数limited.CPU保持在~80%的范围内。相比之下,使用Apache Kafka I可以实现更高的吞吐量(上千QPS的100),以及10ms范围内的延迟。
发布于 2019-10-25 01:30:01
如果您正在使用grpc-java1.21或更高版本和grpc-netty-shaded,那么您应该已经在使用Netty Epoll传输了。如果您使用的是grpc-netty,请在io.netty:netty-transport-native-epoll上添加一个运行时依赖项(通过查看grpc-netty的pom.xml或通过version table in SECURITY.md可以找到正确的版本)。
回调的默认执行器是“缓存线程池”。如果不阻塞(或知道阻塞的限制),指定固定大小的线程池可以提高性能。您可以尝试Executors.newFixedThreadPool和ForkJoinPool;我们已经看到,根据工作负载的不同,“最佳”选择会有所不同。您可以通过ServerBuilder.executor()和ManagedChannelBuilder.executor()指定自己的执行器。
如果您具有高吞吐量(使用TLS的每个客户端的~Gbps+;如果是明文,则更高),则使用多个通道可以通过使用多个TCP连接来提高性能。每个TCP连接都固定在一个线程上,因此拥有更多的TCP连接可以使用更多的线程。您可以创建多个通道,然后轮询它们;为每个RPC选择一个不同的通道。请注意,您可以轻松地实现Channel接口,以便对应用程序的其余部分“隐藏”这种复杂性。这看起来会给你带来很大的收益,但我把它放在最后,因为它通常是不必要的。
https://stackoverflow.com/questions/58423401
复制相似问题