gRPC C++同步与异步服务端两类场景下性能对比问题咨询
gRPC C++ 同步/异步服务端场景性能对比回答
场景1:同步服务端加自定义队列缓冲Write操作 vs 原生异步服务端Write
二者性能不会完全一致,核心差异如下:
- 额外中间层开销:自定义队列无论是锁实现还是无锁实现,都会多一次内存拷贝、线程同步的开销;而异步服务端的
Write是直接把操作提交到gRPC原生Completion Queue(CQ),没有中间层冗余消耗 - 线程调度损耗:同步服务端原有业务线程加上新增的队列消费线程,会多一层上下文切换的概率;异步服务端提交
Write操作后可以直接处理其他任务,不需要中间线程中转 - 异常响应延迟:自定义队列的流量控制、超时、错误回调都需要自己实现,一旦出现堆积或者写入失败,响应速度远低于原生异步服务端直接从CQ返回的事件状态
如果自定义队列优化程度很高,低QPS、小包场景下二者性能差异会非常小,但高并发大包场景下,原生异步服务端性能通常会高出10%~30%。
场景2:异步服务端为每个客户端单独创建线程+CQ vs 原生同步服务端
二者性能也不会一致,这种异步实现甚至可能比原生同步服务端性能更差:
- 线程切换开销不可控:原生同步服务端的线程池固定为CPU核心数,上下文切换开销被控制在极低水平;如果每个客户端单独建线程,当客户端数量涨到几百上千时,线程切换的CPU消耗会陡增,整体吞吐量会明显低于同步服务端
- IO多路复用效率下降:原生同步服务端的内部CQ是多连接共享的,可以批量处理多个连接的事件,单CQ的事件处理吞吐量远高于多个分散的小CQ,每个客户端单独建CQ会直接浪费gRPC的IO复用能力
- 内存开销更高:每个线程+CQ都有独立的栈空间、事件缓冲区,客户端数量上来之后,内存占用会是原生同步服务端的数倍
除非客户端数量长期维持在个位数,否则这种异步实现完全放弃了异步模型少线程处理大量连接的核心优势,性能会远低于原生同步服务端。
内容的提问来源于stack exchange,提问作者debonair
相关产品推荐
相关产品推荐

