답변:
파티션 데이터는 종종로드를 수평으로 분배하는 데 사용되며 성능상의 이점이 있으며 논리적으로 데이터를 구성하는 데 도움이됩니다. 예 : 우리가 큰 employee
테이블을 다루고 있고 종종 WHERE
특정 국가 나 부서로 결과를 제한하는 절로 쿼리를 실행하는 경우 . 보다 빠른 쿼리 응답을 위해 Hive 테이블이 될 수 있습니다 PARTITIONED BY (country STRING, DEPT STRING)
. 파티션 테이블은 Hive가 데이터 스토리지를 구조화하는 방식을 변경하고 이제 Hive는 파티션 구조를 반영하는 서브 디렉토리를 작성합니다.
... / 직원 / 국가 = ABC / DEPT = XYZ .
에서 직원에 대한 쿼리가 제한되면 country=ABC
한 디렉토리의 내용 만 검색합니다 country=ABC
. 이는 파티션 구성표가 공통 필터링을 반영하는 경우에만 쿼리 성능을 크게 향상시킬 수 있습니다. 파티션 기능은 Hive에서 매우 유용하지만 너무 많은 파티션을 만드는 디자인은 일부 쿼리를 최적화 할 수 있지만 다른 중요한 쿼리에는 해 롭습니다. 파티션이 너무 많다는 단점은 파일 시스템의 모든 메타 데이터를 메모리에 보관해야하기 때문에 불필요하게 생성되고 네임 노드에 오버 헤드가 발생하는 많은 수의 하둡 파일 및 디렉토리입니다.
버킷 팅 은 데이터 세트를보다 관리하기 쉬운 부분으로 분해하는 또 다른 기술입니다. 예를 들어 date
최상위 파티션 employee_id
으로 사용하고 두 번째 수준 파티션으로 사용하는 테이블 이 너무 작은 파티션을 생성 한다고 가정 합니다. 대신 직원 테이블을 employee_id
버킷 화하고 버킷 팅 열로 사용 하는 경우이 열의 값은 사용자 정의 숫자에 의해 버킷으로 해시됩니다. 동일한 레코드 employee_id
는 항상 동일한 버킷에 저장됩니다. 의 수가 employee_id
버킷 수보다 훨씬 크다고 가정하면 각 버킷에는 많은 수가 employee_id
있습니다. 테이블을 만드는 동안 다음과 같이 지정할 수 있습니다CLUSTERED BY (employee_id) INTO XX BUCKETS;
여기서 XX는 버킷 수입니다. 버킷 팅에는 몇 가지 장점이 있습니다. 버킷 수는 고정되어 있으므로 데이터에 변동이 없습니다. 에 의해 두 개의 테이블이 버킷 employee_id
되면 Hive는 논리적으로 올바른 샘플링을 생성 할 수 있습니다. 버킷 팅은 효율적인 맵측 조인 등을 수행하는 데 도움이됩니다.
이전 설명에서 몇 가지 세부 사항이 누락되었습니다. 파티셔닝 및 버킷 팅의 작동 방식을보다 잘 이해하려면 데이터가 하이브에 저장되는 방식을 살펴 봐야합니다. 테이블이 있다고 가정 해 봅시다.
CREATE TABLE mytable (
name string,
city string,
employee_id int )
PARTITIONED BY (year STRING, month STRING, day STRING)
CLUSTERED BY (employee_id) INTO 256 BUCKETS
하이브는 다음과 같은 디렉토리 계층에 데이터를 저장합니다.
/user/hive/warehouse/mytable/y=2015/m=12/d=02
따라서 예를 들어 employee_id로 파티션을 나누고 수백만 명의 직원이있는 경우 파일 시스템에 수백만 개의 디렉토리가있게되므로 분할시주의해야합니다. ' 카디널리티 ' 라는 용어 는 필드가 가질 수있는 가능한 값의 수를 나타냅니다. 예를 들어 '국가'필드가있는 경우 전 세계 국가는 약 300 개이므로 카디널리티는 ~ 300이됩니다. 밀리 초마다 변경되는 'timestamp_ms'와 같은 필드의 경우 카디널리티는 수십억이 될 수 있습니다. 일반적으로 파티셔닝 할 필드를 선택할 때 파일 시스템에 너무 많은 디렉토리가 생겨 카디널리티가 높아서는 안됩니다.
반면 버킷 (일명 버킷)은 버킷 수를 지정하므로 고정 된 수의 파일이 생성됩니다. 하이브는 필드를 가져와 해시를 계산하고 해당 버킷에 레코드를 할당하는 것입니다. 그러나 256 버킷을 사용하고 버킷하는 필드의 카디널리티가 낮다고 가정하면 어떻게됩니까 (예 : 미국 상태이므로 50 개의 다른 값만 가능)? 데이터가 포함 된 50 개의 버킷과 데이터가없는 206 개의 버킷이 있습니다.
누군가가 파티션이 쿼리하는 데이터 양을 획기적으로 줄일 수있는 방법을 이미 언급했습니다. 따라서 예제 테이블에서 특정 날짜부터 만 쿼리하려는 경우 년 / 월 / 일별 파티셔닝은 IO의 양을 크게 줄입니다. 누군가 버킷 팅 이 정확히 동일한 버킷을 가진 다른 테이블과의 조인 속도를 높이는 방법을 언급했다고 생각합니다. 예를 들어, 동일한 employee_id에서 두 테이블을 조인하는 경우 하이브는 버킷별로 조인 버킷을 수행 할 수 있습니다 (더 나은 이미 정렬 된 정렬 부분을 병합하기 때문에 employee_id로 이미 정렬 된 경우 선형 시간 (일명 O (n))으로 작동합니다.
따라서 필드의 카디널리티가 높고 버킷간에 데이터가 고르게 분산되어 있으면 버킷 팅이 잘 작동합니다. 파티셔닝 필드의 카디널리티가 너무 높지 않은 경우 파티셔닝이 가장 효과적입니다.
또한 순서대로 (년 / 월 / 일이 좋은 예) 여러 필드로 분할 할 수 있지만 한 필드에서만 버킷 을 만들 수 있습니다 .
이 질문에 대답하는 데 늦었다 고 생각하지만 계속 피드에 나타납니다.
Navneet은 훌륭한 답변을 제공했습니다. 시각적으로 추가합니다.
WHERE 절에서 사용될 경우 파티셔닝은 데이터를 제거하는 데 도움이됩니다. 버킷 팅은 각 파티션의 데이터를 여러 파일로 구성하는 데 도움이되므로 동일한 데이터 집합이 항상 동일한 버킷에 기록됩니다. 열 결합에 많은 도움이됩니다.
이름, server_date, some_col3, some_col4 및 some_col5의 5 개의 열이있는 테이블이 있다고 가정하십시오. server_date 에서 테이블을 분할하고 10 개의 버킷 에서 이름 열에 버킷으로 묶었다고 가정하면 파일 구조는 다음과 같습니다.
여기서 server_date = xyz 는 파티션이고 000 파일은 각 파티션의 버킷입니다. 버킷은 일부 해시 함수를 기반으로 계산되므로 name = Sandy 인 행 은 항상 동일한 버킷으로 이동합니다.
하이브 파티셔닝 :
파티션은 테이블 열의 값에 따라 많은 양의 데이터를 여러 조각으로 나눕니다.
전 세계에있는 사람들의 정보를 약 500crore의 항목에 걸쳐 196 개 이상의 국가에 분산시켜 놓았다고 가정하십시오. 특정 국가 (바티칸 시국)에서 사람들을 쿼리하려면 분할이없는 상태에서 한 국가의 천 항목을 가져 오기 위해 500 crore의 항목을 모두 스캔해야합니다. 국가를 기준으로 테이블을 분할하는 경우 하나의 국가 파티션에 대한 데이터 만 확인하여 쿼리 프로세스를 미세 조정할 수 있습니다. 하이브 파티션은 열 값에 대해 별도의 디렉토리를 만듭니다.
장점 :
단점 :
하이브 버킷 팅 :
버킷 팅은 데이터를보다 관리하기 쉬운 부분으로 분해합니다.
파티셔닝을 사용하면 열 값을 기반으로 여러 개의 작은 파티션을 만들 수 있습니다. 버킷 팅을 사용하는 경우 데이터를 저장할 버킷 수를 제한하고 있습니다. 이 숫자는 테이블 작성 스크립트 중에 정의됩니다.
찬성
단점
에 들어가기 전에 Bucketing
무엇인지 이해해야합니다 Partitioning
. 아래 표를 예로 들어 보겠습니다. 초보자 수준 이해를 위해 아래 예제에서 12 개의 레코드 만 제공했습니다. 실시간 시나리오에서는 수백만 개의 레코드가있을 수 있습니다.
PARTITIONING
---------------------
Partitioning
는 데이터를 쿼리하는 동안 성능을 얻는 데 사용됩니다. 예를 들어, 위 표에서 아래 SQL을 작성하면 성능을 저하시키고 오버 헤드를 증가시키는 표의 모든 레코드를 스캔해야합니다.
select * from sales_table where product_id='P1'
전체 테이블 스캔을 피하고 관련된 레코드 만 읽으 product_id='P1'
려면 product_id
열을 기준으로 여러 파일로 분할 (하이브 테이블 파일 분할) 할 수 있습니다 . 이것에 의하여 하이브 테이블의 파일은 두 파일이 하나로 분할됩니다 product_id='P1'
및 기타 product_id='P2'
. 위의 쿼리를 실행하면 product_id='P1'
파일 만 검색 합니다.
../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2
파티션 생성 구문은 다음과 같습니다. product_id
아래 구문에서 파티션되지 않은 열과 함께 열 정의를 사용해서는 안됩니다 . 이것은 partitioned by
절 에만 있어야합니다 .
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10))
단점 : 파티션을 나누는 동안 매우 조심해야합니다. 즉, 분할 된 파일 수를 늘리고에 대한 오버 헤드를 증가 시키므로 반복 값 수가 매우 적은 열 (특히 기본 키 열)에는 사용하면 안됩니다 Name node
.
BUCKETING
------------------
Bucketing
는 cons
파티셔닝 섹션에서 언급 한 것을 극복하기 위해 사용됩니다 . 열에 반복되는 값이 매우 적은 경우에 사용해야합니다 (예 : 기본 키 열). 이는 RDBMS의 기본 키 열에 대한 인덱스 개념과 유사합니다. 테이블에서 Sales_Id
버킷 팅을위한 열을 사용할 수 있습니다 . sales_id
열 을 쿼리해야 할 때 유용합니다 .
다음은 버킷 팅 구문입니다.
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10)) Clustered by(Sales_Id) into 3 buckets
여기서는 데이터를 파티션 위에 몇 개의 파일로 더 나눕니다.
3
버킷 을 지정 했으므로 각 버킷마다 3 개의 파일로 분할됩니다 product_id
. 내부적으로 modulo operator
각 버킷을 sales_id
저장할 버킷을 결정하는 데 사용 됩니다. 예를 들어,에 대한 product_id='P1'
상기가 sales_id=1
저장 될 000001_0 (즉, 1 % 3 = 1) 파일 sales_id=2
에 저장 될 000002_0 (즉, 2 % 3 = 2) 파일 sales_id=3
에 저장 될 000000_0 파일 (즉, 3 % 3 = 0) 등
hashCode()
를 해시 함수로 사용합니까? 프로그래머가 해시 함수를 선택할 수 있습니까?
다음과 같은 이유로 Hive 테이블에서 파티션을 사용하는 것이 좋습니다.
예 :-
입력 파일 (100GB)이 임시 하이브 테이블에로드되고 여러 지역의 은행 데이터가 포함되어 있다고 가정하십시오.
파티션이없는 하이브 테이블
Insert into Hive table Select * from temp-hive-table
/hive-table-path/part-00000-1 (part size ~ hdfs block size)
/hive-table-path/part-00000-2
....
/hive-table-path/part-00000-n
이 방법의 문제점은-이 테이블에서 실행하는 모든 쿼리에 대한 전체 데이터를 스캔합니다. 파티셔닝 및 버킷 팅이 사용되는 다른 접근 방식에 비해 응답 시간이 길어집니다.
파티션이있는 하이브 테이블
Insert into Hive table partition(country) Select * from temp-hive-table
/hive-table-path/country=US/part-00000-1 (file size ~ 10 GB)
/hive-table-path/country=Canada/part-00000-2 (file size ~ 20 GB)
....
/hive-table-path/country=UK/part-00000-n (file size ~ 5 GB)
장점-특정 지역 트랜잭션에 대한 데이터를 쿼리 할 때 데이터에 더 빠르게 액세스 할 수 있습니다. 단점-각 파티션 내에서 데이터를 분할하여 데이터 삽입 / 쿼리를 더욱 향상시킬 수 있습니다. 아래 버킷 옵션을 참조하십시오.
파티션 및 버킷이 포함 된 하이브 테이블
참고 : 5 개의 버킷에 "CLUSTERED BY (Partiton_Column)을 사용하여 하이브 테이블 생성 .....
Insert into Hive table partition(country) Select * from temp-hive-table
/hive-table-path/country=US/part-00000-1 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-2 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-3 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-4 (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-5 (file size ~ 2 GB)
/hive-table-path/country=Canada/part-00000-1 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-2 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-3 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-4 (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-5 (file size ~ 4 GB)
....
/hive-table-path/country=UK/part-00000-1 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-2 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-3 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-4 (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-5 (file size ~ 1 GB)
장점-빠른 삽입. 빠른 쿼리.
단점-버킷 팅은 더 많은 파일을 생성합니다. 특정 경우에 많은 작은 파일에 문제가있을 수 있습니다
이것이 도움이되기를 바랍니다 !!