LanguageManual Transform
LanguageManual Transform
Hive는 커스텀 매퍼(mapper)와 리듀서(reducer)를 데이터 스트림에 끼워 넣을 수 있는 TRANSFORM 절을 제공해요. external 스크립트를 이용해 복잡한 변환 로직을 실행할 수 있습니다.
출처: 문서
본문
Transform/Map-Reduce 문법
Hive 언어가 기본 지원하는 기능을 이용해 커스텀 매퍼와 리듀서를 데이터 스트림에 끼워 넣을 수 있어요. 예를 들어 커스텀 매퍼 스크립트 - map_script - 와 커스텀 리듀서 스크립트 - reduce_script - 를 실행하려면 TRANSFORM 절을 사용해 매퍼/리듀서 스크립트를 임베드하는 다음 명령을 내리면 됩니다.
기본적으로 컬럼은 사용자 스크립트에 전달되기 전에 STRING으로 변환되고 TAB으로 구분돼요. 마찬가지로 모든 NULL 값은 빈 문자열과 구분하기 위해 리터럴 문자열 \N으로 변환됩니다. 사용자 스크립트의 표준 출력은 TAB으로 구분된 STRING 컬럼으로 취급되고, \N만 포함한 셀은 NULL로 재해석된 뒤 결과 STRING 컬럼이 테이블 선언에 지정된 데이터 타입으로 평소 방식대로 캐스팅돼요. 사용자 스크립트는 표준 에러로 디버그 정보를 출력할 수 있으며, 이는 hadoop 태스크 상세 페이지에 표시됩니다. 이 기본값들은 ROW FORMAT ...으로 재정의할 수 있어요.
Windows에서는 스크립트 이름 대신 "cmd /c your_script"를 사용하세요.
경고(Warning)
변환 전에 STRING 컬럼을 살균(sanitize)하는 건 사용자 책임이에요. STRING 컬럼에 탭이 있으면, identity transformer로 시작값을 그대로 되돌릴 수 없어요! 도움이 필요하면 REGEXP_REPLACE를 참고해 탭을 TRANSFORM() 호출로 들어가기 전에 다른 문자로 바꾸세요.
경고(Warning)
형식상 *MAP ...*와 *REDUCE ...*는 *SELECT TRANSFORM( ... )*의 구문 변환(syntactic transformation)이에요. 다시 말해 쿼리를 읽는 사람에게 주석이나 메모 역할을 합니다. 조심하세요: 이 키워드의 사용은 위험할 수 있어요 (예: "REDUCE"를 입력한다고 reduce 단계가 강제로 발생하지 않고, "MAP"을 입력한다고 새 map 단계가 강제로 발생하지 않습니다!)
Sort By / Cluster By / Distribute By와 Larry Ogrodnek의 블로그 글도 함께 보세요.
clusterBy: CLUSTER BY colName (',' colName)*
distributeBy: DISTRIBUTE BY colName (',' colName)*
sortBy: SORT BY colName (ASC | DESC)? (',' colName (ASC | DESC)?)*
rowFormat
: ROW FORMAT
(DELIMITED [FIELDS TERMINATED BY char]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[ESCAPED BY char]
[LINES SEPARATED BY char]
|
SERDE serde_name [WITH SERDEPROPERTIES
property_name=property_value,
property_name=property_value, ...])
outRowFormat : rowFormat
inRowFormat : rowFormat
outRecordReader : RECORDREADER className
query:
FROM (
FROM src
MAP expression (',' expression)*
(inRowFormat)?
USING 'my_map_script'
( AS colName (',' colName)* )?
(outRowFormat)? (outRecordReader)?
( clusterBy? | distributeBy? sortBy? ) src_alias
)
REDUCE expression (',' expression)*
(inRowFormat)?
USING 'my_reduce_script'
( AS colName (',' colName)* )?
(outRowFormat)? (outRecordReader)?
FROM (
FROM src
SELECT TRANSFORM '(' expression (',' expression)* ')'
(inRowFormat)?
USING 'my_map_script'
( AS colName (',' colName)* )?
(outRowFormat)? (outRecordReader)?
( clusterBy? | distributeBy? sortBy? ) src_alias
)
SELECT TRANSFORM '(' expression (',' expression)* ')'
(inRowFormat)?
USING 'my_reduce_script'
( AS colName (',' colName)* )?
(outRowFormat)? (outRecordReader)?
SQL 표준 기반 인증은 TRANSFORM을 허용하지 않음
Hive 0.13.0 이상 릴리스에서 SQL 표준 기반 인증(SQL standard based authorization)을 구성하면 TRANSFORM 절은 허용되지 않아요 (HIVE-6415).
TRANSFORM 예제
예제 #1:
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;
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;
예제 #2:
FROM (
FROM src
SELECT TRANSFORM(src.key, src.value) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.TypedBytesSerDe'
USING '/bin/cat'
AS (tkey, tvalue) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.TypedBytesSerDe'
RECORDREADER 'org.apache.hadoop.hive.contrib.util.typedbytes.TypedBytesRecordReader'
) tmap
INSERT OVERWRITE TABLE dest1 SELECT tkey, tvalue
스키마 없는 Map-reduce 스크립트(Schema-less Map-reduce Scripts)
USING my_script 뒤에 AS 절이 없으면 Hive는 스크립트 출력이 2부분으로 구성된다고 가정해요: 첫 번째 탭 앞의 key와, 첫 번째 탭 뒤의 나머지 value입니다. 참고로 이는 AS key, value를 지정하는 것과 다릅니다. 그 경우 탭이 여러 개면 value는 첫 탭과 두 번째 탭 사이의 부분만 포함하기 때문이에요.
스크립트의 출력 스키마를 지정하지 않고 CLUSTER BY key를 직접 할 수 있다는 점도 참고하세요.
FROM (
FROM pv_users
MAP pv_users.userid, pv_users.date
USING 'map_script'
CLUSTER BY key) map_output
INSERT OVERWRITE TABLE pv_users_reduced
REDUCE map_output.key, map_output.value
USING 'reduce_script'
AS date, count;
TRANSFORM 출력의 타입 지정(Typing the output of TRANSFORM)
스크립트의 출력 필드는 기본적으로 문자열로 타입이 정해져요. 예를 들어:
SELECT TRANSFORM(stuff)
USING 'script'
AS thing1, thing2
다음 문법으로 바로 캐스팅할 수 있어요:
SELECT TRANSFORM(stuff)
USING 'script'
AS (thing1 INT, thing2 INT)
더 알아보기 (Learn more)
TRANSFORM은 Hive 외부의 스크립트로 유연한 처리를 할 수 있게 해주지만, 탭이나 NULL 처리에 주의해야 해요. CLUSTER BY/DISTRIBUTE BY/SORT BY와 함께 사용해 데이터 분배를 제어할 수 있습니다.