我可以过滤BigQuery连接器返回的Spark数据吗?

时间:2018-11-08 11:26:40

标签: google-bigquery google-cloud-dataproc

我修改了Use the BigQuery connector with Spark中的说明,以使用PySpark从私有BigQuery对象提取数据。我在Dataproc上运行代码。有问题的对象是基数大于5亿行的视图。当我发表以下声明时:

table_data = spark.sparkContext.newAPIHadoopRDD(
    'com.google.cloud.hadoop.io.bigquery.JsonTextBigQueryInputFormat',
    'org.apache.hadoop.io.LongWritable',
    'com.google.gson.JsonObject',
    conf=conf)

在作业输出中,我看到:

Bigquery connector version 0.10.7-hadoop2
Creating BigQuery from default credential.
Creating BigQuery from given credential.
Using working path: 'gs://dataproc-9e5dc592-1a35-42e6-9dd6-5f9dd9c8df87-europe-west1/hadoop/tmp/bigquery/pyspark_input20181108091647'
Estimated number of shards < desired num maps (0 < 93); clipping to 0.
Computed '2' shards for sharded BigQuery export.
Table 'projectname:datasetname.viewname' to be exported has 0 rows and 0 bytes
Estimated number of shards < desired num maps (0 < 93); clipping to 0.
Computed '2' shards for sharded BigQuery export.
Table 'projectname:datasetname.viewname' to be exported has 0 rows and 0 bytes

(出于可读性考虑,删除了时间戳/消息级别/命名空间)

那是2个多小时前,作业仍在运行,在那段时间没有更多输出。我查看了上述gs位置,可以看到已找到名为shard-0的目录,但该目录为空。在过去的两个小时内,基本上没有可见的活动。

我担心bq连接器试图提取整个视图。有没有一种方法可以发出查询来定义要提取的数据,而不是提取整个视图?


更新
输出中的此消息引起了我的兴趣:

Estimated number of shards < desired num maps (0 < 93); clipping to 0

我对分片的估计数量为0感到奇怪。我看过一些在这里和上面执行的代码ShardedExportToCloudStorage.java消息是从 computeNumShards() 记录的。给定numShards=0,我假设numTableBytes=0表示函数调用:

tableToExport.getNumBytes();

ShardedExportToCloudStorage.java#L97

返回0,我认为 的原因是我正在访问的对象是视图,而不是表。我是在这里找东西还是在追赶野鹅?


更新2 ... 为了检验我的理论(上述),源对象是视图会引起问题,我做了以下工作:

在与我的dataproc集群相同的项目中创建了一个表

create table jt_test.jttable1 (col1 string)

将数据插入其中

insert into jt_test.jttable1 (col1) values ('foo')

提交了一个dataproc作业以读取表并输出行数

代码如下:

conf = {
    # Input Parameters.
     'mapred.bq.project.id': project
    ,'mapred.bq.gcs.bucket': bucket
    ,'mapred.bq.temp.gcs.path': input_directory
    ,'mapred.bq.input.project.id': 'myproject'
    ,'mapred.bq.input.dataset.id': 'jt_test'
    ,'mapred.bq.input.table.id': jttable1
}
table_data = spark.sparkContext.newAPIHadoopRDD(
    'com.google.cloud.hadoop.io.bigquery.JsonTextBigQueryInputFormat',
    'org.apache.hadoop.io.LongWritable',
    'com.google.gson.JsonObject',
    conf=conf)
print ('got table_data')
print (table_data.toDF().head(10))
print ('row tally={}'.format(table_data.toDF().count()))

当我运行dataproc pyspark作业时,输出如下:

8/11/08 14:59:26 INFO <cut> Table 'myproject:jt_test.jttable1' to be exported has 1 rows and5 bytes
got table_data
[Row(_1=0, _2=u'{"col1":"foo"}')]
row tally=1

在表格上创建视图

create view jt_test.v_jtview1 as select col1 from `myproject.jt_test.jttable1`

运行相同的作业,但是这次使用视图而不是表

conf = {
    # Input Parameters.
     'mapred.bq.project.id': project
    ,'mapred.bq.gcs.bucket': bucket
    ,'mapred.bq.temp.gcs.path': input_directory
    ,'mapred.bq.input.project.id': 'myproject'
    ,'mapred.bq.input.dataset.id': 'jt_test'
    ,'mapred.bq.input.table.id': v_jtview1
}

当我运行dataproc pyspark作业时,输出如下:

Table 'dh-data-dev-53702:jt_test.v_jtview1' to be exported has 0 rows and 0 bytes

就是这样!没有更多的输出,并且作业仍在运行,与我上面解释的完全相同。它实际上挂了。

似乎是BigQuery连接器的局限性-我不能用它来从视图中使用。

1 个答案:

答案 0 :(得分:1)

要在此处关闭循环,jamiet @在评论中确认,根本原因是BigQuery不支持从Views导出,它仅支持从Tables导出。