目录
一.引言
二.检查最新分区
三.检查任意分区
四.总结
一.引言
国庆期间任务因为某个 hive 表分区未成功创建,导致后续任务异常,为此也是苦逼的 6 点起床修复 bug。发生异常对应表的正常分区如下图所示,为 dt、hour 双分区:
为了保证后续不再出现该问题,这里增加了定时的检查机制,用于检测分区 partition 是否生成,未生成则报警并重新执行分区生成任务。根据场景不同,下面使用两种方法检测,示例中我们只检测对应 dt 的分区是否正常生成。
二.检查最新分区
latest_partition_exist() {
local args=("$@") # 将参数存储在本地数组中
table_name=${args[0]}
partition=${args[1]}
latest_partition=`hive -e "show partitions ${table_name};" | tail -1 | cut -d '=' -f2 | cut -d '/' -f1`
echo 最新分区 $latest_partition
if [ $latest_partition == $partition ];then
echo "Table $table_name 分区 $partition 存在"
else
echo "Table $table_name 分区 $partition 不存在"
... <重新生成分区的逻辑> ...
fi
}
latest_partition_exist $table_name $partition
◆ 函数解释
show_partitions 展示所有分区,由于是检测最新分区,所以 tail -1 直接取最后的分区即可。这里由于是 dt、hour 双分区,所以第一层 cut 后得到的结果是 '20231006/hour',为了获取对应 dt 我们又增加了新的 '/' 划分。如果你的分区只有一层,保留一个 cut 即可。
◆ 函数使用
如上示例,如果我们要检测最新的分区是否是 dt='20231006',则:
#!/bin/bash
table_name='xxx'
partition='20231006'
latest_partition_exist $table_name $partition
如果不存在则在 ... 处增加对应的分区生成逻辑即可。
三.检查任意分区
上面通过 tail -1 检查最后一个即当前表的最新分区,还有一些同学可能需要检测之前的分区,此时不同使用 tail 来定位,所以增加了一版任意分区检测的方法。
partition_exist() {
local args=("$@") # 将参数存储在本地数组中
table_name=${args[0]}
partition=${args[1]}
# 在 Hive 中执行 SHOW PARTITIONS 命令,并将结果赋值给变量 result
result=$(hive -e "SHOW PARTITIONS ${table_name};")
# 检查 result 是否包含 partition
if [[ $result == *"${partition}"* ]]; then
echo "Table $table_name 分区 $partition 存在"
else
echo "Table $table_name 分区 $partition 不存在"
... <重新生成分区的逻辑> ...
fi
}
◆ 函数解释
if [[ $result == *"${partition}"* ]]; then
这里将所有分区信息构成数组赋值给 result。这里的 ==
是字符串比较操作符,*
表示任意字符的通配符。也就是说,如果 $result 变量的值中任意位置包含 $partition 变量的值,条件就满足,就会执行 then 后面的代码块。
◆ 函数使用
如上示例,如果我们要检测最新的分区是否是 dt='20231006',则:
#!/bin/bash
table_name='xxx'
partition='20231006'
partition_exist $table_name $partition
如果不存在则在 ... 处增加对应的分区生成逻辑即可。
四.总结
因为分区未生成的原因,影响了国庆的一个早晨懒觉,教训惨痛,对后续也产生了警醒,一定要给任务增加异常检查机制、失败重试机制,这样才能换来每早的安稳睡眠。最后上个中秋的月,纪念这愉快而又短暂的双节假期: