Hive的Transform功能詳解

pythontab發表於2017-02-28

Hive的 TRANSFORM 關鍵字提供了在SQL中呼叫自寫指令碼的功能,適合實現Hive中沒有的功能又不想寫UDF的情況。例如,按日期統計每天出現的 uid 數,通常用如下的SQL

SELECT date, count(uid)
FROM xxx
GROUP BY date

但是,如果我想在reduce階段對每天的 uid 形成一個列表,進行排序並輸出,這在Hive中沒有現成的功能。那麼,可以自寫指令碼實現該功能,並用 TRANSFORM 關鍵字呼叫

SELECT TRANSFORM(date, uid)
FROM xxx
CLUSTER BY date

這是一個類似streaming的功能,但是可以更方便的訪問Hive中的資料,也可以把SQL語句和自寫指令碼整合在一起執行。


簡單分析 官網 上的一個例子

FROM (
    FROM pv_users
    SELECT TRANSFORM(pv_users.userid, pv_users.date)
    USING 'map_script'
    AS dt, uid
    CLUSTER BY dt
) map_output
INSERT OVERWRITE TABLE pv_users_reduced
SELECT TRANSFORM(map_output.dt, map_output.uid)
USING 'reduce_script'
AS date, count;

這段程式碼的大致工作流程描述如下:


map_script 作為mapper, reduce_script 作為reducer。將 pv_users 表中的 userid , date 兩列作為mapper的輸入欄位,處理後的輸出的前兩個欄位分別命名為 dt , uid ,並按照 dt 欄位作partition和sort送給reduce階段處理。reducer的輸入欄位為 dt 和 uid ,輸出處理後的前兩個欄位,並命名為 date , count ,寫入到 pv_users_reduced 表中。


這裡有幾個細節:


mapper和reducer用到的script可以是任何可執行檔案。 注意 如果用到的是本地檔案,應當在語句開始前用 ADD FILE 或 ADD FILES 將檔案加入進來

mapper和reducer的輸入輸出都是以TAB為分隔符

如果 USING ‘script’ 語句後面沒有 AS ,則Hive預設 script 的輸出中第一個TAB之前的欄位為key,後面的部分全部為value。若指定了 AS ,則嚴格按照 AS 後面的欄位數輸出,例如 AS dt, uid ,則輸出前兩個欄位並忽略後面的欄位。此外, AS 語句可以指定資料型別,如 AS (date STRING, count INT) 。預設都是 string 型別。

CLUSTER BY 關鍵字是 DISTRIBUTE BY 和 SORT BY 的簡寫,這兩者可以認為對應與Hadoop的partition和sort過程。如果partition和sort的key是不同的,可以使用 DISTRIBUTE BY 和 SORT BY 分別指定。

MAP 和 REDUCE 關鍵字是 SELECT TRANSFORM 關鍵字的別名,原文中給出了上面等價程式碼

FROM (
    FROM pv_users
    MAP pv_users.userid, pv_users.date
    USING 'map_script'
    AS dt, uid
    CLUSTER BY dt
) map_output
INSERT OVERWRITE TABLE pv_users_reduced
REDUCE map_output.dt, map_output.uid
USING 'reduce_script'
AS date, count;

因此,原文中特別提醒, MAP 並沒有強制產生一個map過程的作用, REDUCE 同理。只是為了閱讀更清晰。


相關文章