我有持久的Bigtable客户端golang服务。这些服务每秒在Bigtable上进行数百次读/写操作。
从服务启动的每个小时,我都会遇到像这样的一百个错误:
Retryable error: rpc error: code = Unavailable desc =
the connection is draining, retrying in 74.49241ms
错误之后是发生错误时我不能允许的增加的处理时间。
我弄清楚Bigtable客户端正在使用gRPC连接池。
似乎Bigtable gRPC服务器的连接maxAge为1小时,这可以解释上面的错误以及重新连接期间处理时间的增加。
maxAgeGrace配置应该为完成当前操作提供额外的时间,并避免所有池连接同时终止。
我将连接池大小从默认值4增加到12,没有任何实际好处
考虑到我的流量会不断增长,如何防止重新连接期间的处理时间增加以及发生这些错误?
Cloud bigtable客户端使用gRPC连接池连接到bigtable。 Java客户端每个HBase连接使用一个通道池,每个通道池有多个gRPC连接。每小时(或不活动15分钟后)关闭gRPC连接,底层gRPC基础架构执行重新连接。每个新连接上的第一个请求执行许多设置任务,例如TLS握手和加热服务器端缓存。这些操作相当昂贵,可能会导致延迟峰值。
Bigtable旨在成为一个高吞吐量系统,这些重新连接与持续查询量的摊销成本应该可以忽略不计。但是,如果客户端应用程序在查询之间具有非常低的QPS或长时间的空闲时间并且无法容忍这些延迟峰值,则它可以每30-40分钟创建一个新的Hbase连接(java)或新的CBT客户端(golang)。在新的连接/客户端上运行没有op调用(存在于hbase客户端上或读取一小行)以填充底层gRPC连接(每个连接一个调用,对于hbase,默认值是CPU数量的两倍,默认情况下有4个连接) 。启动后,您可以为客户端应用程序中的主要操作换出新的连接/客户端。 Here是此变通方法的示例代码。