天天看點

Impala的資料重新整理開始INVALIDATE METADATAREFRESH最後

開始

Impala 在傳統的 MySQL 或 PostgreSQL 資料庫稱為 Metastore 上保持其表定義,Hive 也在相同的資料庫上儲存此類型的資料。是以,Impala 可以通路由 Hive 定義或加載的表。

對于具有大量資料或多個分區的表,檢索表内所有中繼資料可能會花費很長時間,在某些情況下需要幾分鐘。是以,每個 Impala 節點緩存所有這些資料,以便在未來對同一表進行查詢時重複使用。

如果更新表定義或表資料,叢集中所有其他Impala Daemon必須接收到最新的中繼資料、更換過時的緩存中繼資料,然後再對該表發出查詢。是以在hive裡做了相應操作,需要使用impala同步最新資料。主要有兩種方式,INVALIDATE METADATA和REFRESH。關于實時重新整理的一點想法,請戳連結

INVALIDATE METADATA

INVALIDATE METADATA是用于重新整理全庫或者某個表的中繼資料,包括表的中繼資料和表内的檔案資料,它會首先清楚表的緩存,然後從metastore中重新加載全部資料并緩存,該操作代價比較重,主要用于在hive中修改了表的中繼資料,需要同步到impalad,例如create table/drop table/alter table add columns等。

INVALIDATE METADATA 文法

INVALIDATE METADATA;                   //重新加載所有庫中的所有表
INVALIDATE METADATA [table]            //重新加載指定的某個表
           

INVALIDATE METADATA原理

對于INVALIDATE METADATA操作,由用戶端将查詢送出到某個impalad節點上,執行如下的操作:

  1. 擷取需要執行INVALIDATE METADATA的表,如果沒指定表則不設定表示全部表(不考慮這種情況)。
  2. 請求catalogd執行resetMetadata操作,并将isFresh參數設定為false。
  3. catalogd接收到該請求之後執行invalidateTable操作,将該表的緩存清除,然後重新生成該表的緩存對象,新生成的對象隻包含表名+庫名的資訊,為新生成的表對象生成一個新的catalog版本号(假設新的version=1),将這部分資訊傳回給調用方(impalad),然後異步執行中繼資料和資料的加載。
  4. impalad收到catalogd的傳回值,傳回值是更新之後的表緩存對象+版本号,但是這是一個不完整的表中繼資料,impalad将這個中繼資料應用到本地中繼資料緩存。
  5. INVALIDATE METADATA執行完成。

INVALIDATE METADATA操作帶來的副作用是生成一個新的未完成的中繼資料對象,對于操作請求的impalad(稱它為impalad-A),能夠立馬擷取到該對象,對于其它的impalad需要通過statestored同步,是以執行完該操作,處理該操作的impalad對于該表的緩存是一個新的但是不完整的對象,其餘的impalad儲存的是舊的中繼資料。

對于後續的該表查詢操作,分為如下四種情況:

  1. 如果catalogd已經完成該表所有中繼資料加載,會對該表生成一個新的版本号(假設version=2),然後更新到statestored,由statestored廣播到各個impalad節點上,此時所有的查詢都查詢到最新的中繼資料和資料。
  2. 如果catalogd尚未完成表的中繼資料加載或者statestored未廣播完成,并且接下來請求到impalad-A(之前執行INVALIDATE METADATA的節點),此時impalad在執行語義分析的時候能夠檢測到表的中繼資料不完整(因為目前隻有表名和庫名,沒有任何其餘的中繼資料),impalad會直接請求catalogd擷取該表最新的中繼資料,如果catalogd尚未完成中繼資料加載,則該請求會等到直到catalogd加載完成并傳回impalad最新的中繼資料。
  3. 如果catalogd尚未完成表的中繼資料加載或statestored未廣播完成,接下來請求到了其他的impalad節點,如果接受請求的impalad尚未通過statestored同步新的不完整的表中繼資料(version=1),則該impalad中緩存的關于該表的中繼資料是執行INVALIDATE METADATA之前的,是以根據舊的中繼資料處理該查詢(可能因為檔案被删除導緻錯誤)。
  4. 如果catalogd尚未完成表的中繼資料加載,接下來請求到了其他的impalad節點,如果接受請求的impalad已經通過statestored同步新的不完整的表中繼資料(version=1),那麼接下來會像第二種情況一樣處理。

    從INVALIDATE METADATA的實作來看,該操作不僅僅會全量加載表的中繼資料和分區、檔案中繼資料,還會影響後面關于該表的查詢。

REFRESH

REFRESH是用于重新整理某個表或者某個分區的資料資訊,它會重用之前的表中繼資料,僅僅執行檔案重新整理操作,它能夠檢測到表中分區的增加和減少,主要用于表中中繼資料未修改,資料的修改,例如INSERT INTO、LOAD DATA、ALTER TABLE ADD PARTITION、LLTER TABLE DROP PARTITION等,如果直接修改表的HDFS檔案(增加、删除或者重命名)也需要指定REFRESH重新整理資料資訊。

REFRESH 文法

REFRESH [table]                             //重新整理某個表
REFRESH [table] PARTITION [partition]       //重新整理某個表的某個分區
           

REFRESH原理

對于REFRESH操作,由用戶端将查詢送出到某個impalad節點上,執行如下的操作:

  1. 擷取需要執行REFRESH的表和分區資訊。
  2. 請求catalogd執行resetMetadata操作,并将isFresh參數設定為true。
  3. catalogd接收到該請求之後判斷是否指定分區,如果指定了分區則執行reload partition操作,如果未指定則執行reload table操作,對于reloadPartition則從metastore中讀取partition最新的中繼資料,然後重新整理該partition擁有的所有檔案的中繼資料(大小,權限,資料分布等);對于reloadTable則從metadata中讀取全部的partition資訊,然後和緩存中的partition進行比對判斷是否有分區需要增加和删除,對于其餘的分區則執行中繼資料的更新。
  4. impalad收到catalogd的傳回值,傳回值是更新之後該表的緩存資料,impalad會将該資料更新到自己的緩存中。是以接受請求的impalad能夠将目前中繼資料緩存。
  5. REFRESH執行完成。

對于後續的查詢,分為如下兩種情況:

  1. 如果查詢送出到到執行REFRESH的impalad節點,那麼查詢能夠使用最新的中繼資料。
  2. 如果查詢送出到其他impalad節點,需要依賴于該表0更新後的緩存是否已經同步到impalad中,如果已經完成了同步則可以使用最新的中繼資料,如果未完成則使用舊的中繼資料。

可以看出REFRESH操作較之于INVALIDATE METADATA是輕量級的操作,如果更改隻涉及到一個分區設定可以隻重新整理一個分區的中繼資料,并且它是同步的,對于之後查詢的影響較小。

最後

如果在使用過程中涉及到了中繼資料或者資料的更新,則需要使用這兩者中的一個操作完成,具體如何選擇需要根據如下原則:

  1. invalidate metadata操作比refresh要重量級
  2. 如果涉及到表的schema改變,使用invalidate metadata [table]
  3. 如果隻是涉及到表的資料改變,使用refresh [table]
  4. 如果隻是涉及到表的某一個分區資料改變,使用refresh [table] partition [partition]
  5. 禁止使用invalidate metadata什麼都不加,甯願重新開機catalogd。

REFRESH和INVALIDATE METADATA對于impala而言是比較重要的兩個操作,分别處理資料和中繼資料的修改,其中REFRESH操作是同步的,INVALIDATE METADATA是異步的,本文詳細介紹了兩種語句的适用場景和執行原理,以及可能造成的影響,最重要的是,需要謹記這兩種查詢使用場景。

繼續閱讀