【发布时间】:2016-09-08 23:21:30
【问题描述】:
gRPC C++ 客户端对谷歌云 Bigtable 进行调用时遇到问题。这些调用偶尔会挂起,只有在设置了调用截止日期时才会返回调用。向 gRPC 团队提交了一个问题:https://github.com/grpc/grpc/issues/6278 提供了堆栈跟踪和一条 gRPC 跟踪日志。
最常挂起的调用是ReadRows流读取调用。我也见过MutateRow 电话挂了几次,但这种情况相当罕见。
gRPC 跟踪显示服务器返回了一些响应,但是该响应似乎不足以让 gRPC 客户端继续。
我确实花了相当多的时间调试代码,到目前为止在客户端没有发现明显的问题,也没有发现内存损坏。这是一个单线程应用程序,一次调用一个,客户端并发不是问题。客户端在谷歌计算引擎盒上运行,因此网络也可能不是问题。 gRPC 客户端与 github 存储库主线保持同步。
任何建议将不胜感激。如果有人有调试想法,那也很棒。到目前为止,使用 valgrind、gdb 将应用程序减少到具有可重现结果的子集并没有帮助,我无法找出问题所在。问题是随机的,偶尔会出现。
关于 2016 年 5 月 17 日的补充说明
有人建议重试可能有助于解决该问题。
不幸的是,重试对我们来说效果不佳,因为我们必须将其转移到应用程序逻辑中。我们可以轻松地重试更新,即MutateRow 调用,我们这样做了,这些不是流式调用,并且易于重试。但是,一旦应用程序开始对数据库查询结果进行迭代,如果失败,重试意味着应用程序需要重新发出查询并重新开始结果的迭代。这是有问题的。总是可以考虑进行更改,使我们的应用程序一次读取整个结果集,然后在应用程序级别的迭代可以在内存中完成。然后可以处理重试。但由于各种原因,例如内存占用和应用程序延迟,这是有问题的。我们希望在数据库查询结果到达后立即处理它们,而不是在所有查询结果都在内存中时处理。当呼叫挂起时,呼叫延迟也会增加超时。因此,查询结果迭代的重试成本非常高,以至于不切实际。
【问题讨论】:
-
长时间运行的读取肯定是有问题的。 Java Bigtable 客户端跟踪它看到的内容,然后在最后看到的行之后创建一个新请求。这是一个微妙的问题。请随时通过 goog le dot com 的 sduskis 与我联系。
-
这些不是长时间运行的查询。我看到的失败通常是流的第一次读取调用。这些不是长时间运行的会话。我在测试应用运行后的一两分钟内看到这些故障。
标签: c++ grpc google-cloud-bigtable