最近工作中使用到了Hive, 并对Hive 的数据库,表完成创建。
创建的表为分区表,也涉及到了分区表 的按天动态增加分区。
代码组织结构:
创建数据库:
create_dmp.hql
-- dmp 数据库存储了dmp所需要的数据
CREATE DATABASE IF NOT EXISTS `dmp`
WITH DBPROPERTIES ( 'creator' = 'sunzhenhua', 'create_date' = '2018-06-07');
执行创建命令
hive -f create_dmp.hql
创建表:
create_clearlog.hql
-- dmp_clearlog 存放了清洗过后的投放信息
-- 分区表: 按天分区
-- 外部表
USE dmp;
CREATE EXTERNAL TABLE IF NOT EXISTS `dmp_clearlog` (
`date_log` string COMMENT 'date in file',
`hour` int COMMENT 'hour',
`device_id` string COMMENT '(android) md5 imei / (ios) origin mac',
`imei_orgin` string COMMENT 'origin value of imei',
`mac_orgin` string COMMENT 'origin value of mac',
`mac_md5` string COMMENT 'mac after md5 encrypt',
`android_id` string COMMENT 'androidid',
`os` string COMMENT 'operating system',
`ip` string COMMENT 'remote real ip',
`app` string COMMENT 'appname' )
COMMENT 'cleared log of origin log'
PARTITIONED BY (
`date` date COMMENT 'date used by partition'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
TBLPROPERTIES ('creator'='szh', 'crate_time'='2018-06-07')
;
在编写复杂创建表语句的时候着实遇到了很多问题,创建表的语句的书写格式是要遵循规范的。
具体的规范定义,参考我的博客:
https://blog.csdn.net/u010003835/article/details/80671367
这里我们编写了一个为 dmp.dmp_clearlog 动态增加分区的脚本:
脚本主要实现了以下几种功能:
1.对传入的日期参数进行校验 ,1)可以创建指定日期的分区,2)日期参数必须为yyyy-MM-dd格式
2.向hive执行传递参数
3.使用hive 新版的cli 工具,beeline执行 hql 文件 ,下面脚本包含了两种模式 hive-cli, beeline
延伸内容:
beeline 执行的详细讲解见我的另一篇博客
shell 中对字符串按指定分隔符进行划分的三种方法
shell 中正则表达式的应用
日期判断正则
date_pattern='^[0-9]{4}-((0([1-9]{1}))|(1[1|2]))-(([0-2]([0-9]{1}))|(3[0|1]))$'
下面是我的脚本
load_hdfs_data_into_dmp_clearlog.sh
#! /bin/bash
set -o errexit
source /etc/profile
source ~/.bashrc
ROOT_PATH=$(dirname $(readlink -f $0))
echo $ROOT_PATH
date_pattern_old='^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$'
date_pattern='^[0-9]{4}-((0([1-9]{1}))|(1[1|2]))-(([0-2]([0-9]{1}))|(3[0|1]))$'
#参数数量
argsnum=$#
#一些默认值
curDate=`date +%Y%m%d`
partitionDate=`date -d '-1 day' +%Y-%m-%d`
fileLocDate=`date -d '-1 day' +%Y-%m-%d`
#日志存放位置
logdir=load_hdfs_data_logs
function tips() {
echo "Usage : load_data_into_dmp_clearlog.sh [date]"
echo "Args :"
echo "date"
echo " date use this format yyyy-MM-dd , ex : 2018-06-02"
echo "============================================================"
echo "Example :"
echo " example1 : sh load_data_into_dmp_clearlog.sh"
echo " example2 : sh load_data_into_dmp_clearlog.sh 2018-06-02"
}
if [ $argsnum -eq 0 ] ; then
echo "No argument, use default value"
elif [ $argsnum -eq 1 ] ; then
echo "One argument, check date pattern"
arg1=$1
if ! [[ "$arg1" =~ $date_pattern ]] ; then
echo -e "\033[31m Please specify valid date in format like 2018-06-02"
echo -e "\033[0m"
tips
exit 1
fi
#echo $arg1 |tr "-" " "
dateArr=($(echo $arg1 |tr "-" " "))
echo "dateArr length is "${#dateArr[@]}
partitionDate=${dateArr[0]}-${dateArr[1]}-${dateArr[2]}
fileLocDate=${dateArr[0]}"-"${dateArr[1]}"-"${dateArr[2]}
else
echo -e "\033[31m Not valid num of arguments"
echo -e "\033[0m"
tips
exit 1
fi
if [ ! -d "$logdir" ]; then
mkdir -p $logdir
fi
echo ${partitionDate}
cd $ROOT_PATH
#nohup hive -hivevar p_date=${partitionDate} -hivevar f_date=${fileLocDate} -f hdfs_add_partition_dmp_clearlog.hql >> $logdir/load_${curDate}.log
nohup beeline -u jdbc:hive2://10.180.0.26:10000 -n cloudera-scm --color=true --silent=false --hivevar p_date=${partitionDate} --hivevar f_date=${fileLocDate} -f hdfs_add_partition_dmp_clearlog.hql >> $logdir/load_${curDate}.log
执行脚本示例: (参数校验)
最后动态增加分的脚本
USE dmp;
ALTER TABLE `dmp_clearlog` ADD IF NOT EXISTS PARTITION (`date`='${hivevar:p_date}') LOCATION 'hdfs://dmp-big001.a1.bj.jd:8020/bigdata/clearedLog/Device/${hivevar:f_date}';
留一篇备份,方便以后完成类似的功能~