一、impala同步hive的中繼資料的兩種方式
1、invalidate metadata
對于通過Hive建立,删除或者修改表等操作,Impala無法自動感覺到Hive中繼資料的變化,想讓Impala識别到這個變化需要在impala shell中輸入invalidate metadata,該語句會使得impala原中繼資料失效并且重新從中繼資料庫同步中繼資料資訊。可以對所有表執行,也可以指定某張表
invalidate metadata; -- 廢除所有表的中繼資料; 這種指令一般禁用
invalidate metadata [table]; -- 廢除表table的中繼資料
2、refresh
對于通過hive加載,插入,改變的資料操作,或者通過hdfs對資料進行改變的操作,impala都無法自動識别資料的變化,可以使用REFRESH table_name,該語句可以讓impala識别到資料的變化,可以對某張表更新中繼資料,也可以對某張表的某分區更新中繼資料。
refresh [table]; -- 重新整理表table的中繼資料
refresh [table] partition [partition]; -- 重新整理表table的partition分區中繼資料
3、同步中繼資料生産腳本(适合表結構沒變的)
#bin/sh
set -e
shopt -s expand_aliases #這裡是可以在shell裡面用重命名
.~/.bash_profiles
typeset -u sub_part_flag #把變量轉換成大寫
# typeset的-l選項将一個變量的字元變成小寫
# typeset的-u選項将一個變量的字元變成大寫
table_name=$1
part_name=$2
sub_part_flag=$3
dw_hdfs_path="/user/hive/warehouse"
if ["x${sub_part_flag}!=xY"];then
--如果參數3輸入的是非Y的字元,那麼代表沒有二級分區的
sync_cmd="use impala;refresh ${table_name} partition(${part_name})"
echo "`date`:sync_cmd=${sync_cmd}"
impala2 -e "${sync_cmd}"
echo "date`:finish:${sync_cmd}"
else
part_hdfs_path="${dw_hdfs_path}"/$({echo ${table_name}} | sed "s/\./\.db\//")/$(echo {part_name}| sed "s/ //g;s/'//g;s/\,/\//")
for sub_part in $({hdfs dfs -ls ${part_hdfs_path} | grep ^d | awk -F"/" '{print $NF}'| awk -F"=" '{print $1"='\''"$2"'\''"}');do
sync_cmd="use impala;refresh ${table_name} partition(${part_name},${sub_part})"
echo "`date`:sync_cmd"
impala2 -e "${sync_cmd}"
echo "`date`:finnish:${sync_cmd}"
done
echo "$part_hdfs_path"
fi
4、總結
- invalidate metadata 會加載相關表的所有中繼資料資訊,這個操作對于有很多分區的大表成本非常高,refresh加載中繼資料更快,因為它隻要加載新增的資料檔案塊的位置資料,如果數倉中發生了增删表或改變表結構的行為,如create table、drop table、alter table add column等,就使用invalidate metadata [table]語句。
- 如果數倉中某表加入了新資料,或者有分區的改動,如load data、alter table add partition等,就使用refresh [table] (partition [partition])語句。
- invalidate metadata比起refresh而言要重量級得多,并且它造成impalad之間查詢不一緻也會更嚴重。是以,也幾乎禁止使用 不帶表名的invalidate metadata語句。
- 如果數倉中涉及到非常大批量的中繼資料更改,那麼建議直接重新開機catalogd和statestored,這總比使用不帶表名的invalidate metadata來得高效一些。