Google cloud platform 从bigtable读取数据时,数据流DoFn意外挂起
我们的数据流管道有一个DoFn,它使用hbase multiget客户端api从bigtable读取数据。这似乎会导致数据流在以下堆栈中随机暂停: 处理卡在步骤AttachStuff/BigtableAttacher中至少04H10M00秒,而不输出或完成状态过程 在sun.misc.Unsafe.park(本机方法) 位于java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 位于com.google.bigtable.repackaged.com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:523) 在com.google.bigtable.repackaged.com.google.api.core.AbstractApiFuture.get(AbstractApiFuture.java:56)上 位于com.google.cloud.bigtable.hbase.BatchExecutor.batchCallback(BatchExecutor.java:276) 位于com.google.cloud.bigtable.hbase.BatchExecutor.batch(BatchExecutor.java:239) 位于com.google.cloud.bigtable.hbase.AbstractBigtableTable.get(AbstractBigtableTable.java:241) 请访问com.askscio.google.docbuilder.BigtableAnchorsAttacher.getAnchors(BigtableAnchorsAttacher.java:86) 位于com.askscio.google.docbuilder.BigtableAnchorsAttacher.process(BigtableAnchorsAttacher.java:129) 位于com.askscio.docbuilder.core.ScioDoFn.processHandling(ScioDoFn.java:39) 位于com.askscio.google.docbuilder.BigtableAnchorsAttacher$DoFnInvoker.invokeproceselement(未知源) 我们使用的是梁库2.12.0。DoFn初始化StartBundle中的bigtable连接 每个DoFn调用从bigtable中查找的键不超过10个 它的单集群、3个节点和SSD。存储利用率为2.2 GB,最大节点CPU利用率为13%,最大读/写速率为2000读/秒和1000写/秒 起始价:Google cloud platform 从bigtable读取数据时,数据流DoFn意外挂起,google-cloud-platform,google-cloud-dataflow,google-cloud-bigtable,Google Cloud Platform,Google Cloud Dataflow,Google Cloud Bigtable,我们的数据流管道有一个DoFn,它使用hbase multiget客户端api从bigtable读取数据。这似乎会导致数据流在以下堆栈中随机暂停: 处理卡在步骤AttachStuff/BigtableAttacher中至少04H10M00秒,而不输出或完成状态过程 在sun.misc.Unsafe.park(本机方法) 位于java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 位于com.google.bigtable
bigtableConn = BigtableConfiguration.connect(
config.getString(ConfigKeys.Google.PROJECT_ID),
config.getString(ConfigKeys.Google.INSTANCE_ID)
);
fooTable = bigtableConn.getTable(TableName.valueOf(BigtableDocumentStore.FOO_TABLE_NAME));
过程:
List<Get> gets = Lists.newArrayList();
// keys are no more than 10
for (String s : keys) {
Get get = new Get(Bytes.toBytes(s))
.addFamily(Bytes.toBytes(BigtableDocumentStore.FOO_COLUMN_FAMILY))
.setMaxVersions(1);
gets.add(get);
}
Result[] results= fooTable.get(gets);
我建议将连接管理移动到@Setup&Teardown,并在使用多核工作人员时使用引用计数 Bigtable连接的重量非常重,每个进程都是单件的。BigtableConfiguration.connect()返回的HBase连接对象实际上包装了一个grpc通道池,每个cpu有2个通道,这非常昂贵 您有几个选项可以改进管道:
//实例变量
静态对象连接锁=新对象();
静态连接bigtableConn=null;
//@设置
已同步(连接锁定){
if(numWorkers++==0){
bigtableConn=BigtableConfiguration.connect(…);
}
}
//@Teardown
已同步(连接锁定){
如果(--numWorkers==0){
bigtableConn.close();
}
}
请注意,startBundle应与finishBundle配对,而setup应与teardown配对。假设startBundle是按bundle调用的,而teardown是按DoFn实例调用的,那么您可能正在打开和关闭太多的bigtable连接?因此实际的startBundle代码如下所示。如果我们只在变量为null时创建连接,那么这种不匹配不应该导致连接泄漏,对吗类Foo{static Connection conn=null;@StartBundle public void StartBundle(StartBundleContext bundleContext)抛出异常{synchronized(Foo.class){if(conn==null){//create bigtable conn并将conn分配给该}}}}`好的,看起来不错。您是否(接近)超出了阅读限制?它看起来确实在等待读取完成。根据bigtable实例页面,我的3节点ssd群集可以每秒执行30000行。我检查了我的bigtable实例的最大读取速率是否为2000行/秒。您能否提供有关正在使用的客户端库版本的更多详细信息,即pom.xml中bigtable hbase beam的版本?
fooTable.close();
bigTableConn.close();