【问题标题】:Grpc transfer big data, one unary call is slower than streaming,Grpc传输大数据,一元调用比流式传输慢,
【发布时间】:2020-10-18 13:16:13
【问题描述】:

我正在尝试使用 grpc 在两个服务之间传输大数据。

数据大小约为23M,由42个大List组成。

然后我使用一元调用与服务器端流式传输(一次流式传输一个列表)测试性能。

一元调用耗时 276.59 毫秒。

流式调用需要 126.64 毫秒。

但是如果我将数据更改为包含 1000 个小列表,每个列表只有一个数字,流式调用比一元调用慢得多。

结果正常吗?为什么?

这是服务器端代码:

public override Task<MemDtoToWbs> GetLargeMEM(Empty request, ServerCallContext context)
{
    return Task.FromResult(MemData.GrpcLargeMem);
}
public override async Task StreamLargeMem(Empty request, IServerStreamWriter<LogDtoToWbs> responseStream, ServerCallContext context)
{
    foreach (var log in MemData.GrpcLargeMem.Logs)
    {
         await responseStream.WriteAsync(log);
    }
}

我使用 .net core 3.1 和 grpc nuget 包 2.32.0。 在 aks 集群中运行测试。

谢谢。

【问题讨论】:

  • 嗯,这就是为什么在谈论性能时您可能会听到“一切都是权衡”这句话的原因。没有一种最好的方法,每种情况都需要以特定的方式做事。
  • 感谢@CamiloTerevinto 的回复。但我想知道是什么导致了这种差异。
  • 基本上,即使在流式调用中发送消息的开销很小,但当您发送大量小消息(例如您的情况)时,发送每条消息的开销可能会累加,事情可能会结束比你把所有东西都放在一堆里发送的速度要慢(这当然取决于那一堆有多大)。基本上,当您的用例需要逐步接收数据时(例如,您想在数据可用时立即发送数据),流式调用很有用,但这并不意味着拆分许多小消息总是更快(通常不是)。

标签: c# .net grpc


【解决方案1】:

我认为@Jan Tattermusch 是对的。

我在 localhost 中测试,TCP 段大小为 64K。 当小消息太小时,比如 32K,它在每个 TCP 段中只有 6.5K 的有效载荷长度。但是如果消息很大,它可以使用所有的 64K。所以是的,发送每条消息的开销可能会增加,事情最终会变慢。

所以对我来说,如果消息很大,流式传输速度更快是合理的。 因为服务器端发送数据和客户端处理数据是并行运行的。

【讨论】:

    猜你喜欢
    • 2020-08-08
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 2021-07-06
    • 2015-08-30
    • 2011-09-24
    相关资源
    最近更新 更多