grpc - gRPC 中的高吞吐量低延迟一元调用指南
问题描述
我正在寻找指南以最大限度地提高吞吐量并最大限度地减少 gRPC 一元调用的延迟。我需要达到大约 20,000 QPS,每个 < 50ms。在中等硬件(4 核 CPU)上,我只能实现大约 15K QPS,平均延迟为 200 毫秒。我正在使用 Java 客户端和服务器。服务器除了返回响应之外什么都不做。客户端使用异步存根发送多个并发请求。并发请求的数量是有限的。CPU 保持在 ~80% 的范围内。相比之下,使用 Apache Kafka 我可以实现更高的吞吐量(数千个 QPS)以及 10 毫秒范围内的延迟。
解决方案
如果您使用的是 grpc-java 1.21 或更高版本,并且grpc-netty-shaded
您应该已经在使用 Netty Epoll 传输。如果您正在使用grpc-netty
,请添加运行时依赖项io.netty:netty-transport-native-epoll
(可以通过查看grpc-netty
pom.xml 或SECURITY.md 中的版本表找到正确的版本)。
回调的默认执行器是“缓存线程池”。如果您不阻塞(或知道阻塞的限制),指定固定大小的线程池可以提高性能。Executors.newFixedThreadPool
你可以同时尝试ForkJoinPool
; 我们已经看到“最佳”选择因工作量而异。ServerBuilder.executor()
你通过and指定你自己的执行者ManagedChannelBuilder.executor()
。
如果您有高吞吐量(使用 TLS 的每个客户端约 Gbps+;如果是纯文本则更高)使用多个通道可以通过使用多个 TCP 连接来提高性能。每个 TCP 连接都固定到一个线程,因此拥有更多 TCP 连接允许使用更多线程。您可以创建多个频道,然后对它们进行循环;为每个 RPC 选择不同的。请注意,您可以轻松地实现Channel
接口以“隐藏”应用程序其余部分的复杂性。这看起来会特别为您提供很大的收益,但我把它放在最后,因为它通常不是必需的。
推荐阅读
- apache-spark - 从另一行填充缺失值
- python - 根据发布请求删除数据库中的对象
- arrays - 使用 Swift 过滤嵌套数组
- javascript - 单击导航链接后无法关闭全屏菜单
- css - 当屏幕变小时,避免在带有图标的按钮中换行
- ios - 检索 UIActivityViewController 保存的图像路径
- notepad++ - 在 Notepad++ 中更改 URL/超链接的颜色?
- coq - 小于两个自然数之间的关系
- node.js - 如何在 type-graphql 中使用带整数的 simple-json
- python - PermissionError: [WinError 5] Access is denied - 在 vs 代码中运行程序