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文件
相关推荐
cg50174 小时前
力扣数据库——组合两个表
sql·算法·leetcode
阿里云大数据AI技术6 小时前
迅雷基于阿里云 EMR Serverless Spark 实现数仓资源效率与业务提升
spark
memgLIFE7 小时前
SQL 优化方法详解(1)
java·数据库·sql
保定公民10 小时前
DMDRS数据库同步用户最小权限脚本示例
数据库·sql·达梦数据库·数据同步·dmdrs·同步权限
自燃人~10 小时前
怎么优化慢SQL
数据库·sql
心止水j11 小时前
hive问题
数据仓库·hive·hadoop
不屈的铝合金11 小时前
SQL 语言概述与数据库核心前置配置了解
数据库·sql·mysql·约束·sql 语句分类·字符集配置·校对规则
萧曵 丶11 小时前
可重复读(Repeatable Read)隔离级别下幻读产生的原因
数据库·sql·mysql
·云扬·12 小时前
MySQL运维效率提升:实用SQL语句合集
运维·sql·mysql
伟大的大威12 小时前
在 NVIDIA DGX Spark部署 Stable Diffusion 3.5 并使用ComfyUI
stable diffusion·spark·comfyui