hive partition이란?
일자별로 데이터를 만드는 테이블이 있다고 가정해보자. 이 테이블에서 특정날짜의 데이터를 찾는다면, 전체 테이블을 다 탐색해야만 원하는 결과를 얻을 수 있을 것이다.
여기서 전체를 찾지 않고 날짜별로 Directory를 만든다고 생각해보자, 원하는 날짜가 아니면 파일이 아닌 Directory 단위로 지나칠 수 있다.
즉 위와 같은 파티셔닝의 개념을 적용하면, 같은 쿼리를 수행해도 훨씬 빠른 결과를 얻을 수 있다.
파티셔닝은 물리적 구조를 바꾸는 개념으로 전체 탐색이 아닌 hierarchical 구조로 탐색이 가능하다.
CREATE Partitioning Table (파티션 테이블 만들기)
Partitioning Table을 간단하게 만들자면 아래와 같이 'CREATE TABLE'에 이어
'PARTITIONED BY'라는 문구를 추가해주고 파티션 컬럼에 대해 기입해주면 된다.
주의할 점은 TABLE의 컬럼 정의시에 파티션 컬럼을 중복하여 생성할 수 없다.(상식적으로 겹치면 생성이 안 될 것이다.)
CREATE TABLE 테이블명 (컬럼명 data_type)
PARTITIONED BY(컬럼명 data_type);
-- #1 Single Partion 테이블의 CREATE 문
CREATE TABLE supply (id int,part string, quantity int)
PARTITIONED BY(int day);
-- #2 Multi Partition 테이블의 CREATE 문
CREATE TABLE supply (id int,part string, quantity int)
PARTITIONED BY(int day, cd int);
HDFS(Hadoop File System)의 관점에서 보면
HDFS 관점에서 보면 파티션은 테이블 Directory 하위에 생성된 sub Directory이다.
위에서 생성한 #1과 #2의 테이블의 Directory 구조의 차이는 아래와 같다.
#1 Single Partion 테이블의 Directory 구조
/user/hive/warehouse/production.db/supply/day=20190622/file1
/user/hive/warehouse/production.db/supply/day=20190622/file2...
#2 Multi Partition 테이블의 Directory 구조
/user/hive/warehouse/production.db/supply/day=20190622/cd=22/file1
/user/hive/warehouse/production.db/supply/day=20190622/cd=22/file2...
특별히 서술하진 않았지만, 파티션이 없는 테이블과 같은 경우 테이블명인 supply 이하의 Directory에 파일이 생성된다.
Partitioned TABLE에 INSERT 하기
파티셔닝된 테이블에 INSERT 하기 위해선 크게 두 종류로 구분할 수 있다.
두 종류를 구분짓는 것은 partition value를 지정하는지의 차이이다.
- Static Partitioning(정적 파티셔닝)
특정 Partition 값을 지정하여 Insert 할 때, 사용하기 편하다.
-- Static Partitioning 예시
INSERT INTO TABLE supply PARTITION(day=20190621)
SELECT FROM * source WHERE day=20190621;
-- 위와 같이 Partition Value를 지정하였고,
-- supply라는 테이블은 해당되는 날짜에 대한 파티션만 insert 할 것이다.
-- Local 파일에서 가져와 적재를 하는경우는 data 파일에 파티션 컬럼에 값이 없어야 한다.
-- 지정된 값으로 적재하기 때문이다.
- Dynamic Partitioning(동적 파티셔닝)
특정 Partition 값을 지정하는 것이 아니라 전체 Partition에 대해서 Insert를 한다고 가정해보자.
그러면 Static Partitioning과 같이 어떤 파티션이 있는지 찾아야 하고
그에 대해서 일일이 Insert 하는 것은 상당히 수고스럽다.
따라서 hive에서는 Insert 할 때, Partition key를 지정하면 자동으로 source table에 있는 partition이 생성된다.
-- Dynamic Paritioining 예시
INSERT INTO TABLE supply PARTITION (day,cd)
SELECT id,part,quantity FROM source ;
-- 위 내용을 조금만 응용해보면, mix dynamic and static partitioning을 할 수 있다.
-- 말 그대로, multi partion인 Table의 경우 하나의 Partition은 고정된 값이고
-- 다른 하나의 Partition은 dynamic value인 것이다.
INSERT INTO TABLE supply PARTITION (day=20190621,cd)
SELECT id,part,quantity FROM source ;
-- 위 쿼리를 적용하면 day가 20190621일 때, cd 파티션은 자동으로 생성되고 적재된다.
-- 주의할 점은, static partition key가 dynamic partition key 보다 상위 partition이어야 한다.
Dynamic Partitioning을 활용하기 위해서는 hive 설정이 필요하다.
hive-site.xml에서 관련 property가 있다.
해당 option이 있는 이유는 과도한 partition 생성으로 생기는 side effect를 막고자 함에 있다.(후술)
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions=1000;
set hive.exec.max.dynamic.partitions.pernode=1000;
Hive Partition에 대한 다양한 명령어
#1 Partition 조회하기
SHOW PARTITIONS supply;
day=20190621/cd=21
day=20190621/cd=22
day=20190622/cd=14
특정 파티션의 sub partition을 확인하려면
SHOW PARTITONS supply(day=20190621)
day=20190621/cd=21
day=20190621/cd=22
#2 Partition Description(정보) 보기
DESCRIBE FORMATTED supply PARTITION(day=20190621,cd=25);
#3 ALTER PARTITIONS
#파티션 삭제
ALTER TABLE supply (DROP IF EXISTS) PARTITION(day=20190621, cd=21);
Partition 생성 시, 유의할 점
위에서 Partition 생성관련 option이 있고, Partition이 무분별하게 생성을 방지하고자 한다.
그 이유는 HDFS에서는 Partition을 하나의 Directory로 인식하게 되고, 이는 HDFS Directory 별로 파일을 갖게 되므로
결과적으로 Partition 당 10~100배 가량의 파일이 더 생기는 원인이 된다.
HDFS의 모든 meta 정보를 memory에 보관하고 있는 NameNode는 버거울 수 밖에 없다.
결론적으로 HDFS Directory 즉 하나의 파티션으로 생성되는 사이즈는 설정된 HDFS block size에 몇배 크기 이상이 되는
컬럼에 한해 Partition을 지정하는 것이 좋다.