通过shell脚本执行hive语句(批量添加hive分区)

  • A+
所属分类:Shell

通过shell脚本执行hive语句(批量添加hive分区)

最近临近年关,2018年在向我们招手,但是有好多东西也要处理一番啦,这不马上到2018年,hive分区只建立啦2017年和之前的呢,所以要把hive的2018年的分区建立好,其实hive数据仓库的文件是放在hdfs目录的,hive只是映射的hdfs目录的文件,所以说,首先要创建的是hdfs目录,创建hdfs目录这个简单,就是建立一个文件夹而已,一行语句就可以搞定,并且速度也挺快,一年的数据按天创建目录,创建了快72小时啦还在创建,不过表多,有340张左右,这个暂且不谈,下面所说的内容是建立在hdfs上面的目录已经创建好的基础之上.

以前也创建过hive分区,只不过是一张表的一个月分区,数据量太小,直接写语句就可以创建好,时间长短可以忽略不计;代码如下(部分代码...)

  1. #!/bin/sh
  2. thisyyyy=`date +%Y`
  3. for i in 201702 201703 201704 201705 201706 201707 201708 201709 201710 201711 201712;
  4. do
  5. sql_add_partition="
  6. use papp;
  7. ALTER TABLE ap_wx_high_arpu_dm_m ADD PARTITION (partition_date='$i') LOCATION '/PAPP/ap_wx_high_arpu_dm_m/partition_date=$i';
  8. "
  9. echo "  
  10. $sql_add_partition
  11. exit;"| /e3base/hive/bin/hive
  12. done

这是最简单的添加hive分区方法,其实就是映射一下HDFS目录而已.
但是我们都知道,在linux上输入hive命令进入hive的CLI命令行的时候很慢,我大致数了一下,我在centos命令行敲入hive按回车之后大约等待了8秒钟的时间才进入hive自己的命令行,之后执行这个alter table的语句连一秒钟都没花上,是不是差别很大哈哈
现实情况:有350张表,每张表需要创建365个分区.
要求:尽快创建完.

所以说如果还用之前的方式那不得创建到猴年马月啊!!!
网上看了点资料,发现在shell里面执行hive语句有三种方法(勿喷,菜鸟小白)
1、CLI 方式直接执行
2、作为字符串通过shell调用hive –e执行(-S开启静默,去掉”OK”,”Time taken”)
3、作为独立文件,通过shell调用 hive –f或hive –i执行执行

方式1和方式2暂且不说,今天就来说说方式3,发现方式3真的很好用啊!!!哈哈
不是要创建350张表的分区吗,一张表大约有365个分区,那么大致应该是12万多个分区,啊我的天,我们可以把要执行的alter table 语句生成之后放到一个文件中,然后直接调用文件执行就可以啦,那样的速度快了不止一点半点啊!
生成之后的hfile.sql文件内容如下:

  1. use PODS;
  2. ALTER TABLE dd_a_reactive_no_d ADD PARTITION (partition_date='20180101') LOCATION '/PODS/dd_a_reactive_no_d/partition_date=20180101';
  3. ALTER TABLE dd_bill_invoice_detail_m ADD PARTITION (partition_date='201801') LOCATION '/PODS/dd_bill_invoice_detail_m/partition_date=201801';
  4. ALTER TABLE dd_bll_gprs_d ADD PARTITION (partition_date='20180101') LOCATION '/PODS/dd_bll_gprs_d/partition_date=20180101';
  5. ALTER TABLE dd_bll_mess_d ADD PARTITION (partition_date='20180101') LOCATION '/PODS/dd_bll_mess_d/partition_date=20180101';
  6. ALTER TABLE dd_bll_tot_d ADD PARTITION (partition_date='20180101') LOCATION '/PODS/dd_bll_tot_d/partition_date=20180101';
  7. ALTER TABLE dd_bll_vac_d ADD PARTITION (partition_date='20180101') LOCATION '/PODS/dd_bll_vac_d/partition_date=20180101';

之后我们再通过hive -f命令就可以让hive执行文件里面的语句啦,只需要进一遍hive的cli就可以啦!哈哈大功告成,下面附上生成hfile.sql文件的shell脚本代码(大神勿喷!)

  1. #!/bin/sh
  2. #########################################################
  3. # 程序名称 : hive_add_partitions.sh
  4. # 程序功能 : 生成hql语句文件,用来创建hive分区
  5. # 创建时间 : 2017-12-21 by mahf
  6. # 修改时间 : 
  7. #########################################################
  8. if [ $# -ne 3 ];then
  9.  echo "参数无效 !
  10.        参数1:示例:20180101
  11.        参数2:示例:20181231
  12.        参数3:示例:PODS"
  13.  exit
  14. fi
  15. v_startyyyymmdd=$1              #开始时间(日)
  16. v_endyyyymmdd=$2                #结束时间(日)
  17. v_hdfs=$3                       #HDFS分区一级目录
  18. #将分区第一级目录转换为大写,因为PODS,PMID.PAPP都是大写
  19. v_hdfs_upper=`echo $v_hdfs | tr '[:lower:]' '[:upper:]'`
  20. v_startyyyymm=`date -d "$v_startyyyymmdd" +%Y%m`        #开始月份
  21. v_incyyyymmdd=$v_startyyyymmdd
  22. v_incyyyymm=`date -d "$v_startyyyymmdd" +%Y%m`        #开始月份
  23. start_time=`date +%H:%M:%S`
  24. hdfs_list=(`/e3base/hadoop/bin/hadoop fs -ls /${v_hdfs_upper}/ |awk '{print $8}'`)
  25. echo "use ${v_hdfs_upper};" >>hfile.sql
  26. while [ $v_incyyyymmdd -le $v_endyyyymmdd ]
  27.     do
  28. for i in ${hdfs_list[@]};do
  29.     {
  30.             elem=${i}
  31.             elem_t=${elem##*/}
  32.             last_2_num=${v_incyyyymmdd:0-2}
  33.             if [ "${elem:0-2}" == "_d" ];then
  34.                 {
  35.                 echo "---创建表${elem}的${v_incyyyymmdd}分区ing---"
  36.                 echo "ALTER TABLE ${elem_t} ADD PARTITION (partition_date='$v_incyyyymmdd') LOCATION '/${v_hdfs_upper}/${elem_t}/partition_date=$v_incyyyymmdd';">>hfile.sql
  37.                 }
  38.             elif [ "${elem:0-2}" == "_m" ]&&[ "$last_2_num" == "01" ];then
  39.                 {
  40.                 echo "---创建表${elem}的${v_incyyyymmdd}分区ing---"
  41.                 echo "ALTER TABLE ${elem_t} ADD PARTITION (partition_date='$v_incyyyymm') LOCATION '/${v_hdfs_upper}/${elem_t}/partition_date=$v_incyyyymm';" >>hfile.sql
  42.                 }
  43.             else
  44.             echo "---${elem}不是正式表或者已经创建过分区或者正在等待创建分区!---"
  45.             fi
  46.     }
  47.     done
  48.     v_incyyyymmdd=`date -d "1 day $v_incyyyymmdd" +%Y%m%d`         #自增时间
  49.     v_incyyyymm=`date -d "$v_incyyyymmdd" +%Y%m`                   #取月份
  50. done >>hive_add_partitions.log
  51. end_time=`date +%H:%M:%S`
  52. s_time=`date -d "$start_time" +%s`
  53. e_time=`date -d "$end_time" +%s`
  54. echo "######开始时间: ${start_time}######"
  55. echo "######结束时间: ${end_time}######"
  56. ex_time=`expr $e_time - $s_time`
  57. echo "运行脚本${0}结束,用时: $ex_time(s)!"

PS:我使用的hive版本是hive-0.13.1-cdh5.3.1,这个版本在添加分区的时候必须先use数据库,然后再添加分区,不能通过数据库.数据表这样的方式来添加,会报错,貌似从0.14版本之后这个bug就已经修复啦!

  1. use aa;
  2. ALTER TABLE aaa ADD PARTITION (partition_date='20180101')...

上面是正确的方式,下面的方式会报错!

  1. ALTER TABLE aa.aaa ADD PARTITION (partition_date='20180101')...
  • QQ群二维码
  • 免费维皮恩账号赶紧来吧
  • weinxin
  • 微信公众号
  • 扫一扫关注"你不知道的iPhone技巧"
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: