Google bigquery 数据流';s BigQuery插入器线程池已耗尽

Google bigquery 数据流';s BigQuery插入器线程池已耗尽,google-bigquery,google-cloud-dataflow,Google Bigquery,Google Cloud Dataflow,我正在使用数据流将数据写入BigQuery 当卷变大时,经过一段时间后,我从数据流中得到以下错误: { metadata: { severity: "ERROR" projectId: "[...]" serviceName: "dataflow.googleapis.com" region: "us-east1-d" labels: {…} timestamp: "2016-08-19T06:39:54.492Z"

我正在使用数据流将数据写入BigQuery

当卷变大时,经过一段时间后,我从数据流中得到以下错误:

{
 metadata: {
  severity: "ERROR"    
  projectId: "[...]"    
  serviceName: "dataflow.googleapis.com"    
  region: "us-east1-d"    
  labels: {…}    
  timestamp: "2016-08-19T06:39:54.492Z"    
  projectNumber: "[...]"    
 }
 insertId: "[...]"   
 log: "dataflow.googleapis.com/worker"   
 structPayload: {
  message: "Uncaught exception: "    
  work: "[...]"    
  thread: "46"    
  worker: "[...]-08180915-7f04-harness-jv7y"    
  exception: "java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@1a1680f rejected from java.util.concurrent.ThreadPoolExecutor@b11a8a1[Shutting down, pool size = 100, active threads = 100, queued tasks = 2316, completed tasks = 1192]
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
    at java.util.concurrent.Executors$DelegatedExecutorService.submit(Executors.java:681)
    at com.google.cloud.dataflow.sdk.util.BigQueryTableInserter.insertAll(BigQueryTableInserter.java:218)
    at com.google.cloud.dataflow.sdk.io.BigQueryIO$StreamingWriteFn.flushRows(BigQueryIO.java:2155)
    at com.google.cloud.dataflow.sdk.io.BigQueryIO$StreamingWriteFn.finishBundle(BigQueryIO.java:2113)
    at com.google.cloud.dataflow.sdk.util.DoFnRunnerBase.finishBundle(DoFnRunnerBase.java:158)
    at com.google.cloud.dataflow.sdk.runners.worker.SimpleParDoFn.finishBundle(SimpleParDoFn.java:196)
    at com.google.cloud.dataflow.sdk.runners.worker.ForwardingParDoFn.finishBundle(ForwardingParDoFn.java:47)
    at com.google.cloud.dataflow.sdk.util.common.worker.ParDoOperation.finish(ParDoOperation.java:62)
    at com.google.cloud.dataflow.sdk.util.common.worker.MapTaskExecutor.execute(MapTaskExecutor.java:79)
    at com.google.cloud.dataflow.sdk.runners.worker.StreamingDataflowWorker.process(StreamingDataflowWorker.java:657)
    at com.google.cloud.dataflow.sdk.runners.worker.StreamingDataflowWorker.access$500(StreamingDataflowWorker.java:86)
    at com.google.cloud.dataflow.sdk.runners.worker.StreamingDataflowWorker$6.run(StreamingDataflowWorker.java:483)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)"    
  logger: "com.google.cloud.dataflow.sdk.runners.worker.StreamingDataflowWorker"    
  stage: "F10"    
  job: "[...]"    
 }
}
看起来我正在耗尽中定义的线程池。此线程池的硬编码大小为100个线程,无法配置

我的问题是:

  • 我怎样才能避免这个错误呢

  • 我做错什么了吗

  • 池大小不应该是可配置的吗?100线如何才能完美地满足所有需求和机器类型

下面是我使用的一些上下文:

  • 我在流模式下使用数据流,使用

  • “一段时间后”是几个小时(少于12小时)

  • 我使用了36名n1-standard-4型工人

  • 我每天从卡夫卡(Kafka)那里读到大约18万条消息(我的员工每天收到大约130MB的网络输入)

  • 消息被分组在一起,将大约7k条消息/秒输出到BigQuery中

  • 数据流工作者位于us-east1-d区域,BigQuery数据集位置为us


您没有做错任何事情,尽管您可能需要更多的资源,这取决于容量保持在高位的时间长短

流式
BigQueryIO
write通过执行一些基本的插入批处理。如果我正确理解了您的数字,那么您的行足够大,每个行都将在自己的请求中提交给BigQuery

似乎应该安装用于插入的线程池,这会导致调用方在作业超过执行器的容量时阻塞并同步运行作业。我已经发帖了。当所有处理线程阻塞时,这将把工作队列溢出转换为管道积压

在这一点上,问题是标准的:

  • 如果积压是暂时的,那么一旦数量减少,您就会迎头赶上
  • 如果待办事项没有限制地增长,那么它当然不能解决问题,您将需要应用更多的资源。标志应与任何其他积压工作相同

另一点需要注意的是,每个线程大约250行/秒,这将超过表的BigQuery配额100k次/秒(这种失败将被重试,因此您可能无论如何都会通过它们)。如果我正确理解了您的数字,您就远远没有做到这一点。

谢谢您,当我达到100线程限制时,它看起来可以避免错误和阻塞。但是我不理解固定的100线程限制。无论机器类型如何,这怎么可能是一个相关的限制(我认为n1-standard-32可以处理比n1-standard-1多一点的线程)?如果这是BigQuery方面的一个硬限制,那么BigQuery的总吞吐量不是取决于工作线程的数量吗?100线程的限制没有得到很好的调整。从历史上看,通常使用少于100个线程。这是每个捆绑的行数和每行大小的函数。我们已经注意到了您的特定用例——大行的大包。谢谢