gRPC针对Bigtable的C++客户端调用偶尔挂起

问题描述:

我遇到了gRPC C++客户端针对谷歌云Bigtable进行调用的问题。这些电话偶尔会挂起,只有在呼叫返回时设置了呼叫截止日期。 gRPC团队存在一个问题:https://github.com/grpc/grpc/issues/6278带有堆栈跟踪和提供的一条gRPC跟踪日志。gRPC针对Bigtable的C++客户端调用偶尔挂起

最常挂起的呼叫是ReadRows流读取呼叫。我看到MutateRow呼叫挂了几次,但这是相当罕见的。

gRPC跟踪显示有一些响应从服务器返回,但该响应似乎不足以让gRPC客户端继续进行。

我确实花费了相当多的时间调试代码,目前在客户端没有发现任何明显的问题,没有发现内存损坏。这是一个单线程应用程序,一次只进行一次调用,客户端并发性不是可疑的。客户端运行在谷歌计算引擎框中,因此网络可能也不是问题。 gRPC客户端与github存储库主线保持同步。

任何建议,将不胜感激。如果有人有调试的想法,那也会很棒。使用valgrind,gdb,将应用程序减少到具有可重现结果的子集并没有帮助,但我一直无法找出问题所在。问题是随机的,偶尔会出现。

2016年5月17日的补充说明 有人建议重新尝试可能有助于解决问题。 不幸的是,重试对我们来说效果并不好,因为我们必须将其转换到应用程序逻辑中。我们可以轻松地重新尝试更新,即MutateRow调用,我们这样做,这些不是流式调用,并且很容易重新尝试。但是,一旦数据库查询结果的迭代已经由应用程序开始,如果失败,重试意味着应用程序需要重新发出查询并重新开始迭代结果。这是有问题的。始终可以考虑一个变化,它会让我们的应用程序一次读取整个结果集,然后在应用程序级迭代可以在内存中完成。然后重新尝试可以处理。但是,由于各种原因(如内存占用和应用程序延迟),这是有问题的。我们希望在数据库查询结果到达时立即处理,而不是在所有数据都在内存中时处理。呼叫挂起时,呼叫延迟时间也会增加。因此,对查询结果迭代的重新尝试实际上代价很高,以至于不切实际。

+0

长时间运行读取肯定存在问题。 Java Bigtable客户端跟踪它看到的内容,然后在最后一次看到的行之后开始创建一个新的请求。这是一个细微的问题。请随时联系goog le dot com的sduskis。 –

+0

这些不是长时间运行的查询。我看到的失败通常是流的第一次读取调用。这些都不是长时间运行的会话。我在运行测试应用程序的一两分钟内看到这些故障。 – ay60

我们遇到了gRPC在各种语言中的悬挂问题。 gRPC小组正在调查。

+0

调查的进展如何?我们可以采取哪些措施来缓解这个问题?建议重试,但对于我们的流式调用,重试不起作用。 – ay60

+0

我们进行了一些内部讨论。悬挂与连接关闭和可怕的max_age问题有关吗?如果是这样的话,那么指导就是创建一个重试框架来重试投入/获取。以下是我们在重试中使用的一个Java类:https://github.com/GoogleCloudPlatform/cloud-bigtable-client/blob/master/bigtable-client-core/src/main/java/com/google/ cloud/bigtable/grpc/async/AbstractRetryingRpcListener.java –

+0

不,这不是max_age问题。经过几分钟的操作后,我发现这种情况是随机发生的。 – ay60