JVM 在 java dataflow-sdk 1.9.1 和 hbase 1.0.0 退出时挂起(但不是以前的 hbase 库)
JVM hangs on exit with java dataflow-sdk 1.9.1 and hbase 1.0.0 (but not with previous hbase libraries)
我们大量使用Dataflow和Bigtable,最近遇到了一个奇怪的问题。
使用 Dataflow SDK 1.9.1 和 bigtable-hbase-dataflow 1.0.0,我们读取 Bigtable 的 Java 代码运行得非常好(即,数据流管道正常成功)但 JVM 似乎挂在退出.我们在多台本地机器 (OS X) 和 GCP VM 上尝试过它,它总是在退出时挂起。
如果我们在 main 方法的末尾添加 System.exit(0)
,幸运的是它正常终止,所以我们可以通过这种方式解决问题,但我们无法弄清楚为什么会这样。
当我们尝试将 Dataflow SDK 1.9.1 与其他 hbase 版本(具体来说,0.9.7.1、1.0.0-pre1 和 1.0.0-pre4)结合使用时,这个问题就消失了。
至于 Java 代码(对于数据流管道),它看起来像下面这样(我们简化了多次重现此错误的事情,无论扫描作业 returns 是否为空都会发生这种情况是否收藏)。
// ... some Dataflow pipeline options are set prior to this step.
Pipeline pipeline = Pipeline.create(options);
Scan scan = new Scan();
scan.setCacheBlocks(false).setMaxVersions(1); // Disable caching and read only the latest cell.
scan.addFamily(Bytes.toBytes("x")); // Read only 'x' column family.
scan.setStartRow(Bytes.toBytes("prefix1")).setStopRow(Bytes.toBytes("prefix2"));
try {
long tsBegin = DateTime.parse("2018-03-01T00:00:00Z").getMillis();
long tsEnd = DateTime.parse("2018-03-01T01:00:00Z").getMillis();
scan.setTimeRange(tsBegin, tsEnd);
} catch (IOException e) {
// If unable to set time range, do not run this job as it may read the entire UPT and affect production.
LOG.error("Unable to set Time Range for Bt Scan object.", e);
return;
}
CloudBigtableScanConfiguration btConfig = new
CloudBigtableScanConfiguration.Builder()
.withProjectId("projectId")
.withInstanceId("instanceId")
.withTableId("tableId")
.withScan(scan)
.build();
pipeline.apply(Read.from(CloudBigtableIO.read(btConfig)));
System.out.println("before run");
PipelineResult pipelineResult = pipeline.run();
System.out.println("after run");
// This hangs on exit.
// System.exit(0); would work fine and exit.
// throw new RuntimeException("test re"); this will throw an exception, but will hang (provided that System.exit() above is not present).
```
这是我们在 gradle 依赖项中使用的内容。
同样,对于 bigtable-hbase-dafatflow 库的先前(但已弃用)版本,我们没有看到此问题。
compile 'com.google.cloud.dataflow:google-cloud-dataflow-java-sdk-all:1.9.1'
compile 'com.google.cloud.bigtable:bigtable-hbase-dataflow:1.0.0'
我想知道 Bigtable 或 Dataflow 团队是否可以在他们的末端重现此错误(无论扫描结果如何,只要读取任何 Bigtable instance/table 都会给我们这个错误),因为 hbase 中似乎有些东西1.0.0(不在以前的版本中)可能是导致问题的原因。
我们使用 Java 1.8.0 (0_151) 和 Gradle 版本 3.1 和 4.3.1 来重现错误。
为有类似问题的人更新:
正如下面所指出的,在进行线程转储之后,我们发现了以下内容,其中包括 (grep lmax
):
"pool-4-thread-1" #23 prio=5 os_prio=31 tid=0x00007fd8d4d88000 nid=0x150f runnable [0x000070000b016000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338)
at com.google.bigtable.repackaged.com.lmax.disruptor.SleepingWaitStrategy.applyWaitMethod(SleepingWaitStrategy.java:82)
at com.google.bigtable.repackaged.com.lmax.disruptor.SleepingWaitStrategy.waitFor(SleepingWaitStrategy.java:55)
at com.google.bigtable.repackaged.com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:56)
at com.google.bigtable.repackaged.com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:124)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
这是基于 Cloud Bigtable 客户端在 v 1.0.0 中对 opencensus stackdriver 的依赖而引入的问题。如果您想确认这一点,可以进行线程转储;如果确实如此,您会看到带有 lmax disruptor 的条目。
我建议您升级到 1.2.0 并使用 Beam / Dataflow v2。如果做不到,请降级到 1.0.0-pre4。
我们大量使用Dataflow和Bigtable,最近遇到了一个奇怪的问题。
使用 Dataflow SDK 1.9.1 和 bigtable-hbase-dataflow 1.0.0,我们读取 Bigtable 的 Java 代码运行得非常好(即,数据流管道正常成功)但 JVM 似乎挂在退出.我们在多台本地机器 (OS X) 和 GCP VM 上尝试过它,它总是在退出时挂起。
如果我们在 main 方法的末尾添加 System.exit(0)
,幸运的是它正常终止,所以我们可以通过这种方式解决问题,但我们无法弄清楚为什么会这样。
当我们尝试将 Dataflow SDK 1.9.1 与其他 hbase 版本(具体来说,0.9.7.1、1.0.0-pre1 和 1.0.0-pre4)结合使用时,这个问题就消失了。
至于 Java 代码(对于数据流管道),它看起来像下面这样(我们简化了多次重现此错误的事情,无论扫描作业 returns 是否为空都会发生这种情况是否收藏)。
// ... some Dataflow pipeline options are set prior to this step.
Pipeline pipeline = Pipeline.create(options);
Scan scan = new Scan();
scan.setCacheBlocks(false).setMaxVersions(1); // Disable caching and read only the latest cell.
scan.addFamily(Bytes.toBytes("x")); // Read only 'x' column family.
scan.setStartRow(Bytes.toBytes("prefix1")).setStopRow(Bytes.toBytes("prefix2"));
try {
long tsBegin = DateTime.parse("2018-03-01T00:00:00Z").getMillis();
long tsEnd = DateTime.parse("2018-03-01T01:00:00Z").getMillis();
scan.setTimeRange(tsBegin, tsEnd);
} catch (IOException e) {
// If unable to set time range, do not run this job as it may read the entire UPT and affect production.
LOG.error("Unable to set Time Range for Bt Scan object.", e);
return;
}
CloudBigtableScanConfiguration btConfig = new
CloudBigtableScanConfiguration.Builder()
.withProjectId("projectId")
.withInstanceId("instanceId")
.withTableId("tableId")
.withScan(scan)
.build();
pipeline.apply(Read.from(CloudBigtableIO.read(btConfig)));
System.out.println("before run");
PipelineResult pipelineResult = pipeline.run();
System.out.println("after run");
// This hangs on exit.
// System.exit(0); would work fine and exit.
// throw new RuntimeException("test re"); this will throw an exception, but will hang (provided that System.exit() above is not present).
```
这是我们在 gradle 依赖项中使用的内容。
同样,对于 bigtable-hbase-dafatflow 库的先前(但已弃用)版本,我们没有看到此问题。
compile 'com.google.cloud.dataflow:google-cloud-dataflow-java-sdk-all:1.9.1'
compile 'com.google.cloud.bigtable:bigtable-hbase-dataflow:1.0.0'
我想知道 Bigtable 或 Dataflow 团队是否可以在他们的末端重现此错误(无论扫描结果如何,只要读取任何 Bigtable instance/table 都会给我们这个错误),因为 hbase 中似乎有些东西1.0.0(不在以前的版本中)可能是导致问题的原因。 我们使用 Java 1.8.0 (0_151) 和 Gradle 版本 3.1 和 4.3.1 来重现错误。
为有类似问题的人更新:
正如下面所指出的,在进行线程转储之后,我们发现了以下内容,其中包括 (grep lmax
):
"pool-4-thread-1" #23 prio=5 os_prio=31 tid=0x00007fd8d4d88000 nid=0x150f runnable [0x000070000b016000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338)
at com.google.bigtable.repackaged.com.lmax.disruptor.SleepingWaitStrategy.applyWaitMethod(SleepingWaitStrategy.java:82)
at com.google.bigtable.repackaged.com.lmax.disruptor.SleepingWaitStrategy.waitFor(SleepingWaitStrategy.java:55)
at com.google.bigtable.repackaged.com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:56)
at com.google.bigtable.repackaged.com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:124)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
这是基于 Cloud Bigtable 客户端在 v 1.0.0 中对 opencensus stackdriver 的依赖而引入的问题。如果您想确认这一点,可以进行线程转储;如果确实如此,您会看到带有 lmax disruptor 的条目。
我建议您升级到 1.2.0 并使用 Beam / Dataflow v2。如果做不到,请降级到 1.0.0-pre4。