hive sql&spark 优化

在数据抽取中常用到从其他数据库抽取数据后数据灌入到hive数据库的情况。

大体逻辑是,连接源数据库,抽取数据,缓存转换,数据插入到hive数据库(或者直接覆盖db文件)。

中间源数据库的效率和代码质量、抽取数据的服务器资源、数据转换的效率、hive数据的插入sql效率等都是限制数据抽取效率的瓶颈,如何在保证系统稳定的情况下,效的优化各阶段的运行速度,从而整体提高数据抽取的效率,是一个比较大的课题。

从三个方面做思考:源数据库优化,抽取过程优化,数据灌入优化

源数据库优化

数据在抽取源数据库的时候,根据table是否有索引,视图代码是否有优化等,在源数据库本身对源表(视图)代码进行优化

抽取过程优化

使用spark或平台工具对源数据库抽取,对spark和平台的优化设置

spark优化

spark并行抽取数据

连接Oracle数据库抽取数据,spark可以更细致的控制并行抽取数据

dbconf的设置

复制代码
    var DBconf = Map(
      "url" -> url,
      "user" -> username,
      "password" -> password,
      "fetchsize" -> "100",
      "upperBound" -> "150000000",
      "lowerBound" -> "1",
      "numPartitions" -> "10",
      //"partitionColumn" -> "ROW_ID",
      "partitionColumn" -> "rn",
      "driver" -> driver
    )

具体含义如下

复制代码
partitionColumn:
  分区字段,需要是数值类的(partitionColumn must be a numeric column from the table in question.),
  经测试,除整型外,float、double、decimal都是可以的
  **必须是sql中存在的字段名(别名也可以吧),否则会报错
  分区列得是数字类型;所谓的并行读取其实就是开了多个数据库连接,分块读取的。
 lowerBound:
  下界,必须为整数
 upperBound:
  上界,必须为整数
 numPartitions:
  最大分区数量,必须为整数,当为0或负整数时,实际的分区数为1;
  并不一定是最终的分区数量,
    例如“upperBound - lowerBound< numPartitions”时,实际的分区数量是“upperBound - lowerBound”;

 在分区结果中,分区是连续的,虽然查看每条记录的分区,不是顺序的,但是将rdd保存为文件后,可以看出是顺序的。
 **以上四个值必须同时有指定,或都不指定,否则会报错

如果一个表分10个分区读取,id为分区列,其值从0-101,但是设置的lowerBound是1,upperBound是100,那么读取的规则如下:
第一个分区:select * from tablename where id<=10;
第二个分区:select * from tablename where id >=10 and id<20;
第三个分区:select * from tablename where id >=20 and id <30;
……
第十个分区:select * from tablename where id >=90;//
即一次读取100条数据,分10个区来平均读取,每个分区读取(upperBound-lowerBound)/numPartitions=(101-1)/10的条数量
从这里立即,numPartitions字段最好是连续的数字,这样可以保证每次每个分区读取的数据是饱满的,oracle中建议使用rownum

参考连接

Spark读写Oracle性能深度调优_rowid自定义分区键-CSDN博客

如何理解SparkSQL中的partitionColumn, lowerBound, upperBound, numPartitions_spark numpartitions-CSDN博客

spark sql代码优化

即调用的sql实际上是在Oracle数据库执行,所以可以利用Oracle 特性执行一些优化策略。

服务器资源优化

数据灌入优化

数据抽取和转换后,开始进入hive数据库,此时的一些优化建议

hive sql优化

在使用hive sql插入表的时候,启用一些优化设置,可以有效的提高insert的效率

复制代码
set mapreduce.map.memory.mb=2048;--2gb--设置map任务的内存大小
set mapreduce.reduce.memory.mb=2048;--2gb--设置reduce任务的内存大小
set hive.exec.dynamic.partition.mode = nonstrict; 
--开启非严格模式,允许所有分区都是动态的,否则必须要有一个静态分区

set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
set mapred.max.split.size = 51200000;--50m
--每个Map最大输入大小
set mapred.min.split.size.per.node=51200000;--50m
set mapred.min.split.size.per.rack=51200000;--50m
set hive.exec.reducers.max = 128;--最大的 reduce 数
--开启map join
set hive.auto.convert.join = true;
set hive.mapjoin.smalltable.filesize = 62500000;--单位Byte 62.5m
set mapred.job.name = ads_fm_ma_xxmaexpallodtl_di_mm;--设置job名字,可以yarn里方便查阅
--设置任务名称

spark优化

有两种方式:使用spark sql插入hive数据库和直接覆盖hdsf的服务器DB文件

spark sql插入

可以在spark sql中执行hive sql的相关优化

覆写DB文件
相关推荐
XYiFfang7 小时前
【MYSQL】SQL学习指南:从常见错误到高级函数与正则表达式
sql·mysql·正则表达式·regexp_like·group_concat
十碗饭吃不饱9 小时前
sql报错:java.sql.SQLSyntaxErrorException: Unknown column ‘as0‘ in ‘where clause‘
java·数据库·sql
呆呆小金人9 小时前
SQL入门: HAVING用法全解析
大数据·数据库·数据仓库·sql·数据库开发·etl·etl工程师
Yana_Zeng13 小时前
win10安装spark3.1详细流程(小白用)
hadoop·windows·spark
l1t14 小时前
用parser_tools插件来解析SQL语句
数据库·sql·插件·duckdb
TDengine (老段)15 小时前
TDengine 数学函数 ABS() 用户手册
大数据·数据库·sql·物联网·时序数据库·tdengine·涛思数据
Hello.Reader18 小时前
Apache StreamPark 快速上手从一键安装到跑起第一个 Flink SQL 任务
sql·flink·apache
1024find18 小时前
Spark on k8s部署
大数据·运维·容器·spark·kubernetes
养生技术人1 天前
Oracle OCP认证考试题目详解082系列第57题
运维·数据库·sql·oracle·开闭原则
养生技术人1 天前
Oracle OCP认证考试题目详解082系列第53题
数据库·sql·oracle·database·开闭原则·ocp