从bigtable读取数据时DataFlow DoFn意外挂起

时间:2019-06-13 23:10:11

标签: google-cloud-platform google-cloud-dataflow google-cloud-bigtable

我们的数据流管道具有一个DoFn,该DoFn使用hbase multiget客户端api从bigtable读取。这似乎会导致数据流在以下堆栈中随机停止:

在步骤AttachStuff / BigtableAttacher中停留了至少04h10m00s的过程,没有在状态过程中输出或完成   在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.processWithErrorHandling(ScioDoFn.java:39)   com.askscio.google.docbuilder.BigtableAnchorsAttacher $ DoFnInvoker.invokeProcessElement(未知来源)

我们正在使用束库2.12.0。 DoFn在StartBundle中启动bigtable连接。

每个DoFn调用从bigtable查找最多不超过10个键

其单个群集,3个节点和SSD。存储利用率为2.2 GB,最大节点CPU利用率为13%,最大读写速率为2000次读取/秒和1000次写入/秒

startBundle:

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);

拆卸:

fooTable.close();
bigTableConn.close();

1 个答案:

答案 0 :(得分:0)

如果您使用的是多核工作程序,我建议将连接管理移至@Setup&Teardown并使用引用计数。

大表连接非常重,每个过程旨在成为单例。 BigtableConfiguration.connect()返回的HBase连接对象实际上包装了一个grpc通道池,每个cpu有2个通道,这是非常昂贵的。

您有一些选择可以改善管道:

  1. 将配置选项“ google.bigtable.use.cached.data.channel.pool”设置为“ true”,这将重用内部连接池

  2. 在您的DoFn中执行以下操作:

    // instance vars
    static Object connectionLock = new Object();
    static Connection bigtableConn = null;
    
    // @Setup
    synchronized(connectionLock) {
      if (numWorkers++ == 0) {
        bigtableConn = BigtableConfiguration.connect(...);
      } 
    }
    
    // @Teardown
    synchronized(connectionLock) {
      if (--numWorkers == 0) {
        bigtableConn.close();
      } 
    }