Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在DataLab笔记本中使用Dataproc和Spark BigQuery连接器时出错_Python_Google Cloud Platform_Google Bigquery_Google Cloud Dataproc_Google Cloud Datalab - Fatal编程技术网

Python 在DataLab笔记本中使用Dataproc和Spark BigQuery连接器时出错

Python 在DataLab笔记本中使用Dataproc和Spark BigQuery连接器时出错,python,google-cloud-platform,google-bigquery,google-cloud-dataproc,google-cloud-datalab,Python,Google Cloud Platform,Google Bigquery,Google Cloud Dataproc,Google Cloud Datalab,我能够使用正确的TCP防火墙权限在Google Chrome中运行Google Datalab(笔记本电脑)。使用简单的脚本,这将启动最新的spark集群(1个主集群,3个工作集群使用Dataproc)。首先,我们在spark submit中测试下面的代码,然后在启动DataLab之后,我不确定如何修复下面的错误 第一步:从Cloud Shell启动Dataproc集群 gcloud dataproc clusters create cluster1021 \ --subnet defa

我能够使用正确的TCP防火墙权限在Google Chrome中运行Google Datalab(笔记本电脑)。使用简单的脚本,这将启动最新的spark集群(1个主集群,3个工作集群使用Dataproc)。首先,我们在
spark submit
中测试下面的代码,然后在启动DataLab之后,我不确定如何修复下面的错误

第一步:从Cloud Shell启动Dataproc集群

gcloud dataproc clusters create cluster1021 \
    --subnet default --zone us-west1-a \
    --master-machine-type n1-standard-2 \
    --master-boot-disk-size 30 --num-workers 2 \
    --worker-machine-type n1-standard-2 \
    --worker-boot-disk-size 30 --image-version 1.3-deb9 \
    --project bigdata-228217 \
    --initialization-actions 'gs://dataproc-initialization-actions/datalab/datalab.sh','gs://dataproc-initialization-actions/connectors/connectors.sh' \
    --metadata 'gcs-connector-version=1.9.11' \
    --metadata 'bigquery-connector-version=0.13.11'
成功启动后,我测试了Bigquery连接器是否与来自的
spark submit wordcount.py
示例一起工作

第二步:使用
触摸wordcount.py
将此代码作为
wordcount.py
包含在主目录中,然后从
nano wordcount.py
粘贴到下面的代码中并保存。

#!/usr/bin/python
"""BigQuery I/O PySpark example."""
from __future__ import absolute_import
import json
import pprint
import subprocess
import pyspark
from pyspark.sql import SQLContext

sc = pyspark.SparkContext()

# Use the Cloud Storage bucket for temporary BigQuery export data used
# by the InputFormat. This assumes the Cloud Storage connector for
# Hadoop is configured.
bucket = sc._jsc.hadoopConfiguration().get('fs.gs.system.bucket')
project = sc._jsc.hadoopConfiguration().get('fs.gs.project.id')
input_directory = 'gs://{}/hadoop/tmp/bigquery/pyspark_input'.format(bucket)

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': 'publicdata',
    'mapred.bq.input.dataset.id': 'samples',
    'mapred.bq.input.table.id': 'shakespeare',
}

# Output Parameters.
output_dataset = 'wordcount_dataset'
output_table = 'wordcount_output'

# Load data in from BigQuery.
table_data = sc.newAPIHadoopRDD(
    'com.google.cloud.hadoop.io.bigquery.JsonTextBigQueryInputFormat',
    'org.apache.hadoop.io.LongWritable',
    'com.google.gson.JsonObject',
    conf=conf)

# Perform word count.
word_counts = (
    table_data
    .map(lambda record: json.loads(record[1]))
    .map(lambda x: (x['word'].lower(), int(x['word_count'])))
    .reduceByKey(lambda x, y: x + y))

# Display 10 results.
pprint.pprint(word_counts.take(10))

# Stage data formatted as newline-delimited JSON in Cloud Storage.
output_directory = 'gs://{}/hadoop/tmp/bigquery/pyspark_output'.format(bucket)
output_files = output_directory + '/part-*'

sql_context = SQLContext(sc)
(word_counts
 .toDF(['word', 'word_count'])
 .write.format('json').save(output_directory))

# Shell out to bq CLI to perform BigQuery import.
subprocess.check_call(
    'bq load --source_format NEWLINE_DELIMITED_JSON '
    '--replace '
    '--autodetect '
    '{dataset}.{table} {files}'.format(
        dataset=output_dataset, table=output_table, files=output_files
    ).split())

# Manually clean up the staging_directories, otherwise BigQuery
# files will remain indefinitely.
input_path = sc._jvm.org.apache.hadoop.fs.Path(input_directory)
input_path.getFileSystem(sc._jsc.hadoopConfiguration()).delete(input_path, True)
output_path = sc._jvm.org.apache.hadoop.fs.Path(output_directory)
output_path.getFileSystem(sc._jsc.hadoopConfiguration()).delete(
    output_path, True)
现在,在shell中,
spark submit
的输出结果显示了BigQuery连接器的工作原理

spark-submit wordcount.py
...
(pinnace,3)
(bone,21)
(lug,2)
(vailing,2)
(bombast,3)
(gaping,11)
(hem,5)
('non,1)
(stinks,1)
(forsooth,48)
步骤3设置防火墙以允许在浏览器中查看TCP数据实验室

为DataLab创建防火墙规则

在设置页面上,您将为DataLab防火墙规则创建一个名称,并允许以下TCP端口,以及紧跟在网络IP地址之后的“/32”——您可以找到这些端口

第4步:使用
:8080在Google Chrome中启动DataLab,您应该会看到DataLab笔记本

你会看到这个。现在打开一个新笔记本,在第一个单元格中,我停止了spark上下文并将上面的莎士比亚代码粘贴到第二个单元格中

这是输出。问题,我需要做什么才能让Bigquery连接器在Datalab中与Pyspark一起工作

Py4JJavaErrorTraceback (most recent call last)
<ipython-input-4-62761a09a7c5> in <module>()
     36     'org.apache.hadoop.io.LongWritable',
     37     'com.google.gson.JsonObject',
---> 38     conf=conf)
     39 
     40 # Perform word count.

/usr/lib/spark/python/lib/pyspark.zip/pyspark/context.py in newAPIHadoopRDD(self, inputFormatClass, keyClass, valueClass, keyConverter, valueConverter, conf, batchSize)
    735         jrdd = self._jvm.PythonRDD.newAPIHadoopRDD(self._jsc, inputFormatClass, keyClass,
    736                                                    valueClass, keyConverter, valueConverter,
--> 737                                                    jconf, batchSize)
    738         return RDD(jrdd, self)
    739 

/usr/lib/spark/python/lib/py4j-0.10.7-src.zip/py4j/java_gateway.py in __call__(self, *args)
   1255         answer = self.gateway_client.send_command(command)
   1256         return_value = get_return_value(
-> 1257             answer, self.gateway_client, self.target_id, self.name)
   1258 
   1259         for temp_arg in temp_args:

/usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/utils.py in deco(*a, **kw)
     61     def deco(*a, **kw):
     62         try:
---> 63             return f(*a, **kw)
     64         except py4j.protocol.Py4JJavaError as e:
     65             s = e.java_exception.toString()

/usr/lib/spark/python/lib/py4j-0.10.7-src.zip/py4j/protocol.py in get_return_value(answer, gateway_client, target_id, name)
    326                 raise Py4JJavaError(
    327                     "An error occurred while calling {0}{1}{2}.\n".
--> 328                     format(target_id, ".", name), value)
    329             else:
    330                 raise Py4JError(

Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.newAPIHadoopRDD.
: java.lang.ClassNotFoundException: com.google.cloud.hadoop.io.bigquery.JsonTextBigQueryInputFormat
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.apache.spark.util.Utils$.classForName(Utils.scala:239)
    at org.apache.spark.api.python.PythonRDD$.newAPIHadoopRDDFromClassNames(PythonRDD.scala:313)
    at org.apache.spark.api.python.PythonRDD$.newAPIHadoopRDD(PythonRDD.scala:296)
    at org.apache.spark.api.python.PythonRDD.newAPIHadoopRDD(PythonRDD.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
    at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
    at py4j.Gateway.invoke(Gateway.java:282)
    at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
    at py4j.commands.CallCommand.execute(CallCommand.java:79)
    at py4j.GatewayConnection.run(GatewayConnection.java:238)
    at java.lang.Thread.run(Thread.java:748)
Py4JJavaErrorTraceback(最近一次调用)
在()
36'org.apache.hadoop.io.LongWritable',
37'com.google.gson.JsonObject',
--->38形态=形态)
39
40#执行字数计算。
/newAPIHadoopRDD中的usr/lib/spark/python/lib/pyspark.zip/pyspark/context.py(self、inputFormatClass、keyClass、valueClass、keyConverter、valueConverter、conf、batchSize)
735 jrdd=self.\u jvm.PythonRDD.newAPIHadoopRDD(self.\u jsc、inputFormatClass、keyClass、,
736 valueClass、keyConverter、valueConverter、,
-->737 jconf,批量大小)
738返回RDD(jrdd,自我)
739
/usr/lib/spark/python/lib/py4j-0.10.7-src.zip/py4j/java_gateway.py in____调用(self,*args)
1255 answer=self.gateway\u client.send\u命令(command)
1256返回值=获取返回值(
->1257应答,self.gateway_客户端,self.target_id,self.name)
1258
1259对于临时参数中的临时参数:
/装饰中的usr/lib/spark/python/lib/pyspark.zip/pyspark/sql/utils.py(*a,**kw)
61 def装饰(*a,**千瓦):
62尝试:
--->63返回f(*a,**kw)
64除py4j.protocol.Py4JJavaError外的其他错误为e:
65 s=e.java_exception.toString()
/获取返回值中的usr/lib/spark/python/lib/py4j-0.10.7-src.zip/py4j/protocol.py(答案、网关客户端、目标id、名称)
326 raise Py4JJavaError(
327“调用{0}{1}{2}时出错。\n”。
-->328格式(目标id,“.”,名称),值)
329其他:
330升起Py4JError(
Py4JJavaError:调用z:org.apache.spark.api.python.PythonRDD.newAPIHadoopRDD时出错。
:java.lang.ClassNotFoundException:com.google.cloud.hadoop.io.bigquery.JsonTextBigQueryInputFormat
位于java.net.URLClassLoader.findClass(URLClassLoader.java:382)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:424)
位于java.lang.ClassLoader.loadClass(ClassLoader.java:357)
位于java.lang.Class.forName0(本机方法)
位于java.lang.Class.forName(Class.java:348)
位于org.apache.spark.util.Utils$.classForName(Utils.scala:239)
位于org.apache.spark.api.PythonRDD$.newAPIHadoopRDDFromClassNames(PythonRDD.scala:313)
位于org.apache.spark.api.PythonRDD$.newAPIHadoopRDD(PythonRDD.scala:296)
位于org.apache.spark.api.PythonRDD.newAPIHadoopRDD(PythonRDD.scala)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
位于py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
位于py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
在py4j.Gateway.invoke处(Gateway.java:282)
位于py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
在py4j.commands.CallCommand.execute(CallCommand.java:79)
在py4j.GatewayConnection.run处(GatewayConnection.java:238)
运行(Thread.java:748)
从中可以看出,Datalab init action将BQ和GCS连接器安装到Docker容器中

由于Dataproc 1.3默认情况下不附带BQ连接器,并且您指定了连接器初始化操作,这将在集群上安装BQ连接器,因此在DataLab初始化操作之后,Docker无法在DataLab初始化操作执行期间将BQ连接器装入DataLab容器

要解决此问题,您需要更改初始化操作的顺序:

gcloud dataproc clusters create \
    . . .
    --initialization-actions=gs://dataproc-initialization-actions/datalab/connectors.sh,gs://dataproc-initialization-actions/connectors/datalab.sh

作为一个小改进,您不需要指定GCS连接器版本(
--元数据“GCS连接器版本=1.9.11”
)目前,因为最新的Dataproc 1.3映像已经预装了GCS connector 1.9.11。

完美的解决方案;它工作了!直接从源代码开始。使用https设置Datalab的任何标志?另外,在通过Dataproc启动屏幕设置linux gcloud输出时,使用元数据选项也会很有用。此外,最好有一个默认安装