背景
在DtataWorks平台上开发spark任务时,选择 spark 2.x 版本,Python language,配置如下:
python 代码如下:
# -*- coding: UTF-8 -*-
from pyspark.sql import SparkSession
import pyspark.sql.functions as f
from pyspark.sql.types import IntegerType,BooleanType,DateType,DecimalType,StringType,StructType,StructField,FloatType,DoubleType
from datetime import datetime, timedelta
from pyspark.storagelevel import StorageLevel
from functools import reduce
import json
import sys
spark = SparkSession.builder.appName("test").getOrCreate()
sc = spark.sparkContext
lastday_pt = sys.argv[1]
sql = """
select *
from user_info
where pt = '{yyyymmdd}'
limit 300
"""
df = spark.sql(sql.format(yyyymmdd = lastday_pt))
print(df.show(5))
历史记录都是成功的,但是在2024-08-28
在 MaxCompute 上升级 schema 存储之后就突然报错,而我升级的目的其实是想通过创建外部schema 来进行联邦查询,具体可见 湖仓一体2.0使用指南。
问题描述
由上图可知,同一个任务 2024-08-21
运行成功,但是 2024-08-30
运行失败,spark 版本是 2.3.0 ,catalog 使用的是内部odps
,报错信息提示:Caused by: org.apache.spark.sql.catalyst.analysis.NoSuchTableException: Table or view 'user_info' not found in database 'default'
,百思不得解,因为数仓中明明有这张表,起初我以为是升级 schema 导致的。
但又很快否认了,因为升级 schema 之后要使其生效必须通过参数开启,况且我并没有配置这个参数,schema 使用文档可见Schema操作。
然后我查看其他同事的spark任务,发现他们增加了一个参数spark.hadoop.odps.spark.version
= spark-2.4.5-odps0.33.0
,我也尝试增加如上参数并执行成功,此时环境信息如下:
spark 版本变成了 2.4.5,元数据服务也变成了 hive
,接着我又尝试了一下 spark 3.x 版本,我分别尝试是否配置参数spark.hadoop.odps.spark.version
=spark-3.1.1-odps0.35.0
,发现都成功。
解决方法
就上述问题跟阿里云客服沟通,整理了一下聊天记录,如下:
- 1、从Python代码上来看,读取数仓中的表走的是单层模型模式,也就是
from tablename
,不是两层模型(from project.tablename
) 或者 三层模型方式(fromproject.schema.tablename
)。 - 2、spark 2.x 版本都不支持三层模型的方式读表。
- 3、之所以 2.4.5 运行成功 ,2.3.0运行失败并读取到不该读取的默认schema:
default
应该是个BUG,等待修复。 - 4、之后的任务最好都使用 spark 3.x 版本应该可以避免。