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文件

你可能感兴趣的:(#,混合处理框架spark,hive,sql,spark)