使用AWS Glue从BigQuery加载数据到Spark DataFrame失败:找不到数据源bigquery
问题:AWS Glue加载BigQuery数据至Spark DataFrame时出现ClassNotFoundException
环境与操作步骤
- Spark版本:3.1
- 使用的BigQuery连接器版本:
com.google.cloud.spark:spark-3.1-bigquery:0.36.1,已上传至S3桶 - 在Glue Notebook中执行以下代码创建Spark Session并加载数据:
from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("Data from BQ") \ .config("spark.jars", "s3://path/to/driver.jar") \ .getOrCreate() df = spark.read \ .format("bigquery") \ .load("project.dataset.table")
报错信息
Py4JJavaError: Py4JJavaError: An error occurred while calling o127.load. : java.lang.ClassNotFoundException: Failed to find data source: bigquery. Please find packages at http://spark.apache.org/third-party-projects.html at org.apache.spark.sql.execution.datasources.DataSource$.lookupDataSource(DataSource.scala:689) at org.apache.spark.sql.execution.datasources.DataSource$.lookupDataSourceV2(DataSource.scala:743) at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:266) at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:226) 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:750) Caused by: java.lang.ClassNotFoundException: bigquery.DefaultSource at java.net.URLClassLoader.findClass(URLClassLoader.java:387) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352) at java.lang.ClassLoader.loadClass(ClassLoader.java:351). : java.lang.ClassNotFoundException: Failed to find data source: bigquery. Please find packages at http://spark.apache.org/third-party-projects.html at org.apache.spark.sql.execution.datasources.DataSource$.lookupDataSource(DataSource.scala:689) at org.apache.spark.sql.execution.datasources.DataSource$.lookupDataSourceV2(DataSource.scala:743) at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:266) at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:226) 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:750) Caused by: java.lang.ClassNotFoundException: bigquery.DefaultSource at java.net.URLClassLoader.findClass(URLClassLoader.java:387) at java.lang.ClassLoader.loadClass(ClassLoader.java:418) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352) at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
解决方案
这个错误是因为Spark找不到BigQuery数据源的类,核心原因是连接器的配置方式不符合AWS Glue要求,或依赖包未正确加载。以下是可行的解决方法:
1. 正确配置Glue作业依赖包
AWS Glue无法直接通过spark.jars加载S3中的JAR包,需在作业配置中指定:
- 打开AWS Glue控制台,找到目标Notebook或作业
- 在「作业参数」中添加
--extra-jars s3://path/to/driver.jar - 同时添加
--conf spark.driver.extraClassPath=s3://path/to/driver.jar和--conf spark.executor.extraClassPath=s3://path/to/driver.jar
2. 使用Glue Notebook魔法命令加载依赖
在Glue Notebook中,可通过%additional_jars魔法命令直接加载S3中的JAR包:
%additional_jars s3://path/to/driver.jar
之后创建Spark Session时,无需在builder中指定spark.jars配置。
3. 确认连接器包完整性
确保下载的是包含所有依赖的胖包(fat jar),如果是瘦包(thin jar),需手动下载所有依赖并上传至S3,否则会出现类缺失问题。
4. 指定完整数据源类名
若上述方法无效,可在format中替换为完整的数据源类名:
df = spark.read \ .format("com.google.cloud.spark.bigquery") \ .load("project.dataset.table")
5. 配置BigQuery权限
确保Glue作业具备访问BigQuery的权限,可在Spark配置中添加:
spark = SparkSession.builder \ .appName("Data from BQ") \ .config("spark.hadoop.google.cloud.auth.service.account.enable", "true") \ .config("spark.hadoop.google.cloud.auth.service.account.json.keyfile", "s3://path/to/your-service-account-key.json") \ .getOrCreate()
内容的提问来源于stack exchange,提问作者Safwan Asghar
相关产品推荐
相关产品推荐

