在Impala中缺狠,invalidate metadata與refresh語句都可以用來刷新表糕殉,但它們本質(zhì)上還是不同的颈将。本文簡要分析一下昌阿,并說明它們應(yīng)該在什么情況下使用饥脑。
Impala on Hive介紹
我們一般會采用傳統(tǒng)的MySQL或PostgreSQL數(shù)據(jù)庫作為Hive的Metastore(元數(shù)據(jù)存儲)組件。在CDH中默認(rèn)是MySQL懦冰,我們可以通過show tables in hive
語句清晰地看到Hive Metastore中的各個表灶轰。
mysql> show tables in hive;
+---------------------------+
| Tables_in_hive |
+---------------------------+
| BUCKETING_COLS |
| CDS |
| COLUMNS_V2 |
| COMPACTION_QUEUE |
| COMPLETED_TXN_COMPONENTS |
| DATABASE_PARAMS |
| DBS |
| DB_PRIVS |
| DELEGATION_TOKENS |
| FUNCS |
| FUNC_RU |
| GLOBAL_PRIVS |
| HIVE_LOCKS |
| IDXS |
| INDEX_PARAMS |
| MASTER_KEYS |
| METASTORE_DB_PROPERTIES |
| NEXT_COMPACTION_QUEUE_ID |
| NEXT_LOCK_ID |
| NEXT_TXN_ID |
| NOTIFICATION_LOG |
| NOTIFICATION_SEQUENCE |
| NUCLEUS_TABLES |
| PARTITIONS |
| PARTITION_EVENTS |
| PARTITION_KEYS |
| PARTITION_KEY_VALS |
| PARTITION_PARAMS |
| PART_COL_PRIVS |
| PART_COL_STATS |
| PART_PRIVS |
| ROLES |
| ROLE_MAP |
| SDS |
| SD_PARAMS |
| SEQUENCE_TABLE |
| SERDES |
| SERDE_PARAMS |
| SKEWED_COL_NAMES |
| SKEWED_COL_VALUE_LOC_MAP |
| SKEWED_STRING_LIST |
| SKEWED_STRING_LIST_VALUES |
| SKEWED_VALUES |
| SORT_COLS |
| TABLE_PARAMS |
| TAB_COL_STATS |
| TBLS |
| TBL_COL_PRIVS |
| TBL_PRIVS |
| TXNS |
| TXN_COMPONENTS |
| TYPES |
| TYPE_FIELDS |
| VERSION |
+---------------------------+
54 rows in set (0.00 sec)
它的組織方式與MySQL中的information_schema類似。如TBLS保存有所有表的元數(shù)據(jù)刷钢,COLUMNS保存有所有列的元數(shù)據(jù)笋颤,PARTITIONS存儲分區(qū)信息,SDS存儲表及分區(qū)對應(yīng)的HDFS目錄映射,等等伴澄。
Impala作為一個MPP查詢引擎赋除,經(jīng)常會配合Hive一同使用,我們的業(yè)務(wù)中也是如此非凌。下圖示出Impala及周邊組件的大體結(jié)構(gòu)举农。
Impala的核心組件是impalad,它負(fù)責(zé)提供所有查詢服務(wù)敞嗡。另外颁糟,還有catalogd負(fù)責(zé)獲取與緩存表元數(shù)據(jù),statestored則負(fù)責(zé)表元數(shù)據(jù)到每個impalad的更新喉悴。
這種方案完美解決了每次查詢都要獲取表元數(shù)據(jù)的問題棱貌,因為一旦表結(jié)構(gòu)非常復(fù)雜或者數(shù)據(jù)很多,獲取元數(shù)據(jù)會造成很大的延遲箕肃。如果將它們緩存下來键畴,元數(shù)據(jù)就可以重用,節(jié)省時間突雪。
但是起惕,它又帶來了一個新的問題:由于緩存不會即時刷新,當(dāng)在Hive本身進(jìn)行元數(shù)據(jù)甚至數(shù)據(jù)的更改時咏删,Impala無法感知到惹想。常見的情境如在Hive中新建了一張表,或者直接在Hive表對應(yīng)的HDFS目錄中新增文件等督函。所以嘀粱,Impala才提供了invalidate metadata與refresh兩條語句來打補丁。
invalidate metadata
invalidate的意思是“使無效辰狡、使作廢”锋叨,因此invalidate metadata的含義就是“廢除(緩存的)元數(shù)據(jù)”。它的語法是:
invalidate metadata; -- 廢除所有表的元數(shù)據(jù)
invalidate metadata [table]; -- 廢除表table的元數(shù)據(jù)
如果在某個impalad(簡稱為I)上執(zhí)行了invalidate metadata table
語句宛篇,會發(fā)生如下的動作:
- I獲取到表table娃磺,對catalogd發(fā)起resetMetadata請求;
- catalogd收到該請求叫倍,執(zhí)行invalidateTable操作偷卧,清除所有與table相關(guān)的元數(shù)據(jù)緩存,重新讀取Metastore中的所有元數(shù)據(jù)吆倦,并生成新的緩存听诸。但是此時生成的緩存只包含庫名和表名,是不完整的蚕泽;
- catalogd再生成一個標(biāo)記緩存的版本號晌梨,將這個不完整的緩存和版本號一起返回給I,然后繼續(xù)異步加載其余的元數(shù)據(jù);
- I收到catalogd返回的不完整緩存和版本號仔蝌,用它來更新本地緩存砸逊。
invalidate metadata的特點就是異步性和全量性。從上面可以看出掌逛,在剛執(zhí)行完時师逸,除了I之外的其他impalad仍然保有舊的元數(shù)據(jù)緩存,就算I保有的新元數(shù)據(jù)也是殘缺的。只有當(dāng)catalogd異步加載完了table對應(yīng)的所有元數(shù)據(jù),才會生成一個更新的版本號夺英,并將完整的元數(shù)據(jù)通過statestored廣播給所有impalad,整個Impala集群的元數(shù)據(jù)感知才會達(dá)到一致员辩。
refresh
refresh的意思比較簡單,“刷新”鸵鸥。它的語法是:
refresh [table]; -- 刷新表table的元數(shù)據(jù)
refresh [table] partition [partition]; -- 刷新表table的partition分區(qū)元數(shù)據(jù)
在I上執(zhí)行refresh table
語句會發(fā)生如下的動作:
- I獲取到表table奠滑,對catalogd發(fā)起resetMetadata請求;
- catalogd收到該請求:對指定了partition的請求妒穴,執(zhí)行reloadPartition操作宋税,獲取該分區(qū)最新的元數(shù)據(jù)并刷新;對未指定partition的請求讼油,執(zhí)行reloadTable操作杰赛,獲取全部分區(qū)最新的元數(shù)據(jù)并刷新。這里的“刷新”是指Metastore中與緩存對比如果沒有變化矮台,就保持原狀乏屯;如果有增刪改,才會發(fā)生改變瘦赫;
- I收到catalogd返回的完整緩存辰晕,用它來更新本地緩存。
當(dāng)然确虱,statestored仍會負(fù)責(zé)廣播新的元數(shù)據(jù)到其他節(jié)點含友。在廣播完之前,除了I之外的其他impalad也保有舊的緩存蝉娜。
由此可見唱较,與invalidate metadata不同,refresh的特點是同步性和增量性召川。并且,它的執(zhí)行是圍繞單表以及單表的分區(qū)進(jìn)行的胸遇,因此它更輕量級荧呐,也更適合分區(qū)元數(shù)據(jù)或數(shù)據(jù)文件更改之后的刷新。
如何正確使用
通過上面的簡單分析,容易做出以下總結(jié):
- 如果數(shù)倉中發(fā)生了增刪表或改變表結(jié)構(gòu)的行為倍阐,如
create table
概疆、drop table
、alter table add column
等峰搪,就使用invalidate metadata [table]
語句岔冀。 - 如果數(shù)倉中某表加入了新數(shù)據(jù),或者有分區(qū)的改動概耻,如
load data
使套、alter table add partition
等,就使用refresh [table] (partition [partition])
語句鞠柄。 - invalidate metadata比起refresh而言要重量級得多侦高,并且它造成impalad之間查詢不一致也會更嚴(yán)重。因此厌杜,也幾乎禁止使用不帶表名的invalidate metadata語句奉呛。
- 如果數(shù)倉中涉及到非常大批量的元數(shù)據(jù)更改,那么建議直接重啟catalogd和statestored夯尽,這總比使用不帶表名的invalidate metadata來得高效一些瞧壮。