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文件
相关推荐
数据库小学妹9 小时前
数据库连接池避坑指南:告别“连接超时”与“资源耗尽”,让系统跑得更快!
数据库·redis·sql·mysql·缓存·dba
这个DBA有点耶11 小时前
数据库上云 vs 自建:从成本到人力的三维对比与决策框架
数据库·经验分享·sql·创业创新·dba
小的~~11 小时前
CentOS7安装CDH6.3.2
hive·hdfs·kafka
随缘而动,随遇而安12 小时前
第九十八篇 工程落地视角:Session/Cookie/Token 原理辨析与大数据实战
大数据·spark·token·cookie·session
CQU_JIAKE16 小时前
5.13【A】
数据库·sql
lzhdim16 小时前
SQL 入门 14:SQL 触发器与事件:自动化数据处理
linux·前端·数据库·sql·自动化
lolo大魔王17 小时前
Go 语言原生 SQL 操作 MySQL 超详细全解 + 生产级项目模板(纯官方库无ORM)
数据库·sql·golang
qq_3660862218 小时前
SQL 中 OR 与 UNION ALL选择指南
数据库·sql
逸Y 仙X21 小时前
文章三十:Elasticsearch SQL实战案例
java·大数据·sql·elasticsearch·搜索引擎·全文检索
小陈的进阶之路1 天前
Python系列课(10)——SQL
开发语言·python·sql