spark-sql读写数据源

spark读写数据源的相关操作

一、读FileSystem

1. 使用说明

1 基本用法

select col_01, col_02 from file_format.`save_path` where dt = '20220413';

注意:

1) from后的表名用“文件格式.`存储路径`”代替;

2) 可以使用分区字段, 但路径要指定到分区字段的上一层;

2 高级用法

create temporary view view_name using json options ('path'='test2.txt', 'multiline'='true');

select name, age from view_name where dt = '20220413';

注意:

1) 用options设定参数, 实现个性化读取;

2) 可以使用分区字段, 但路径要指定到分区字段的上一层;

3)获取记录所在文件路径:input_file_name()

-- 获取某些记录所在文件
select
    input_file_name() as file_name
    ,count(1) as cnt
from 
    table_name
where
    dt = '20220720' 
group by
    file_name
order by
    cnt
;

3 参考参数

1)文件异常处理

set spark.sql.files.ignoreCorruptFiles=true;   -- 忽略损坏的文件
set spark.sql.files.ignoreMissingFiles=true;  -- 忽略丢失的文件

2)参考链接

用途链接
文件源参数Generic File Source Options - Spark 3.1.2 Documentation
读文件优化Performance Tuning - Spark 3.1.2 Documentation
数据源-参考options参数Data Sources - Spark 3.2.1 Documentation

2. 使用样例

1 读取json文件

-- 方式01,自动推断数据类型
select id,age from json.`save_path`

-- 方式02,都是字符串类型
select
    name,
    age
from
    text.`save_path`
    lateral view json_tuple(value, 'name',  'age') tmp as name, age
;

注意:

1) json文件自带结构信息,select后可以直接通过key获取数据;

2)以上两种解析方式,执行效率差不多;

2 读取parquet文件

select id,age from parquet.`save_path`

注意:parquet文件自带结构信息,select后可以直接读取parquet文件中所包含的列;

3 读取orc文件

select id,age from orc.`save_path`

注意:orc文件自带结构信息,select后可以直接读取orc文件中所包含的列;

4 读取text文件

select value from text.`save_path`

注意:text文件没有自带结构信息,读取后只有一个value列;

5. 读取csv文件

CSV Files - Spark 3.3.1 Documentation

方式01
-- 设定路径
set path=oss://path/20230607.csv;

-- 设定读取参数
create temporary view view_name using csv options ('path'='${path}', 'delimiter'=',', 'header'='true','encoding'='gbk');

-- 写出到parquet格式表
insert overwrite table table_name
select * from view_name;


-- 方式02
-- 设定路径
set path=oss://path/20230607.csv;
 
-- 设定读取参数
create temporary view view_name using csv options ('path'='${path}', 'delimiter'=',', 'header'='true','encoding'='utf-8');
 
-- 写出到parquet格式表
create table table_name using parquet as
select * from view_name;

常见问题:

中文乱码,确认文件的字符集与hive表(一般是utf-8)是否一致;linux上查看文件字符集 file ${file_name}

分割异常,字段值中有逗号,要么更改csv的分割符,要么使用能正常处理的引擎(spark)处理成parquet文件;

处理方式

文件格式转换 --> 导入目标hive

本地使用spark转成parquet文件,再上传到hive表;

csv文件先上传,再使用spark读取后写入hive表;

3. 读取错误

1. select from parquet.`save_path`

1)  读取的路径存在, 但没有数据

Error in query: Unable to infer schema for Parquet. It must be specified manually.

Error in query: Unable to infer schema for Orc. It must be specified manually.

2)  读取的路径不存在

Error in query: Path does not exist: s3://save_path

3) 增加字段后,报字段不存在错误

Error in query: cannot resolve '`name`' given input columns: [id, age]; 

-- 报字段不存在(读基础路径,会根据这个目录下的所有数据获取schema,历史数据中无新增字段,可以设定spark.sql.parquet.mergeSchema=true来解决)
select 
    id
    ,age
    ,name
from 
  parquet.`save_base_path`
where 
   dt='20220614'
;

-- 可以正常读取(新目录是最新的schema,包含新增字段,可以正常读取)
select 
    id
    ,age
    ,name
from 
  parquet.`save_base_path/dt=20220614`
;

2. 递归读取分区目录下的子目录

-- 目录结构
oss://path/20230216/00/
oss://path/20230216/01/

-- 添加分区
alter table table_name add if not exists partition (dt='20230216') location 'oss://path/20230216/';

-- 读取数据
set mapreduce.input.fileinputformat.input.dir.recursive=true;
select
    *
from
    table_name
where
    dt = '20230216'
limit 10
;

3. 文件损坏

报错现象:

FileScanRDD: Skipped the rest of the content in the corrupted file: path: ks3://aa/test.gz, range: 0-23046, partition values: [empty row]
java.io.IOException: invalid block type
        at org.apache.hadoop.io.compress.zlib.ZlibDecompressor.inflateBytesDirect(Native Method)

任务卡住不继续运行也不退出,占用资源却没有任何任务运行

解决方式:

set spark.sql.files.ignoreCorruptFiles=true;

-

2 写FileSystem

options能使用的参数和读FileSystem一样

insert overwrite directory 'oss//base_path/' using json options('compression'='gzip')
select
    name
    ,age
from
    tbl_name
;

-

20 相关参考

Spark 内置数据源 options

DataFrameReader (Spark 2.3.0 JavaDoc)

JDBC To Other Databases - Spark 3.2.1 Documentation


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值