IT story

Hive에서 테이블 파티셔닝과 버킷 팅의 차이점은 무엇입니까?

hot-time 2020. 7. 12. 09:32
반응형

Hive에서 테이블 파티셔닝과 버킷 팅의 차이점은 무엇입니까?


둘 다 테이블의 열에서 수행되지만 각 작업이 어떻게 다른지 알고 있습니다.


파티션 데이터는 종종로드를 수평으로 분배하는 데 사용되며 성능상의 이점이 있으며 논리적으로 데이터를 구성하는 데 도움이됩니다. : 우리가 큰 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 개의 버킷 에서 이름 열에 버킷으로 묶었다고 가정하면 파일 구조는 다음과 같습니다.

  1. server_date = xyz
    • 00000_0
    • 00001_0
    • 00002_0
    • ........
    • 00010_0

여기서 server_date = xyz 는 파티션이고 000 파일은 각 파티션의 버킷입니다. 버킷은 일부 해시 함수를 기반으로 계산되므로 name = Sandy 인은 항상 동일한 버킷으로 이동합니다.


하이브 파티셔닝 :

파티션은 테이블 열의 값에 따라 많은 양의 데이터를 여러 조각으로 나눕니다.

전 세계에있는 사람들의 정보를 약 500crore의 항목에 걸쳐 196 개 이상의 국가에 걸쳐 저장하고 있다고 가정하십시오. 특정 국가 (바티칸 시국)에서 사람들을 쿼리하려면 분할이없는 상태에서 한 국가의 천 항목을 가져 오기 위해 500 crore의 항목을 모두 스캔해야합니다. 국가를 기준으로 테이블을 분할하는 경우 하나의 국가 파티션에 대한 데이터 만 확인하여 쿼리 프로세스를 미세 조정할 수 있습니다. 하이브 파티션은 열 값에 대해 별도의 디렉토리를 만듭니다.

장점 :

  1. 실행로드를 수평으로 분배
  2. 데이터 양이 적은 파티션의 경우 쿼리 실행 속도가 빨라집니다. 예를 들어 " 바티칸 시티 " 에서 인구를 얻으려면 전 세계 인구를 검색하는 대신 매우 빠르게 돌아옵니다.

단점 :

  1. Possibility of too many small partition creations - too many directories.
  2. Effective for low volume data for a given partition. But some queries like group by on high volume of data still take long time to execute. e.g. Grouping of population of China will take long time compared to grouping of population in Vatican city. Partition is not solving responsiveness problem in case of data skewing towards a particular partition value.

Hive Bucketing:

Bucketing decomposes data into more manageable or equal parts.

With partitioning, there is a possibility that you can create multiple small partitions based on column values. If you go for bucketing, you are restricting number of buckets to store the data. This number is defined during table creation scripts.

Pros

  1. Due to equal volumes of data in each partition, joins at Map side will be quicker.
  2. Faster query response like partitioning

Cons

  1. You can define number of buckets during table creation but loading of equal volume of data has to be done manually by programmers.

The difference is bucketing divides the files by Column Name, and partitioning divides the files under By a particular value inside table

Hopefully I defined it correctly


Before going into Bucketing, we need to understand what Partitioning is. Let us take the below table as an example. Note that I have given only 12 records in the below example for beginner level understanding. In real-time scenarios you might have millions of records.

enter image description here



PARTITIONING
---------------------
Partitioning is used to obtain performance while querying the data. For example, in the above table, if we write the below sql, it need to scan all the records in the table which reduces the performance and increases the overhead.

select * from sales_table where product_id='P1'

To avoid full table scan and to read only the records related to product_id='P1' we can partition (split hive table's files) into multiple files based on the product_id column. By this the hive table's file will be split into two files one with product_id='P1' and other with product_id='P2'. Now when we execute the above query, it will scan only the product_id='P1' file.

../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2

The syntax for creating the partition is given below. Note that we should not use the product_id column definition along with the non-partitioned columns in the below syntax. This should be only in the partitioned by clause.

create table sales_table(sales_id int,trans_date date, amount int) 
partitioned by (product_id varchar(10))

Cons : We should be very careful while partitioning. That is, it should not be used for the columns where number of repeating values are very less (especially primary key columns) as it increases the number of partitioned files and increases the overhead for the Name node.



BUCKETING
------------------
Bucketing is used to overcome the cons that I mentioned in the partitioning section. This should be used when there are very few repeating values in a column (example - primary key column). This is similar to the concept of index on primary key column in the RDBMS. In our table, we can take Sales_Id column for bucketing. It will be useful when we need to query the sales_id column.

Below is the syntax for bucketing.

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

Here we will further split the data into few more files on top of partitions.

enter image description here

Since we have specified 3 buckets, it is split into 3 files each for each product_id. It internally uses modulo operator to determine in which bucket each sales_id should be stored. For example, for the product_id='P1', the sales_id=1 will be stored in 000001_0 file (ie, 1%3=1), sales_id=2 will be stored in 000002_0 file (ie, 2%3=2),sales_id=3 will be stored in 000000_0 file (ie, 3%3=0) etc.


There are great responses here. I would like to keep it short to memorize the difference between partition & buckets.

You generally partition on a less unique column. And bucketing on most unique column.

Example if you consider World population with country, person name and their bio-metric id as an example. As you can guess, country field would be the less unique column and bio-metric id would be the most unique column. So ideally you would need to partition the table by country and bucket it by bio-metric id.


Using Partitions in Hive table is highly recommended for below reason -

  • Insert into Hive table should be faster ( as it uses multiple threads to write data to partitions )
  • Query from Hive table should be efficient with low latency.

Example :-

Assume that Input File (100 GB) is loaded into temp-hive-table and it contains bank data from across different geographies.

Hive table without Partition

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

Problem with this approach is - It will scan whole data for any query you run on this table. Response time will be high compare to other approaches where partitioning and Bucketing are used.

Hive table with Partition

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)

Pros - Here one can access data faster when it comes to querying data for specific geography transactions. Cons - Inserting/querying data can further be improved by splitting data within each partition. See Bucketing option below.

Hive table with Partition and Bucketing

Note: Create hive table ..... with "CLUSTERED BY(Partiton_Column) into 5 buckets

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)

Pros - Faster Insert. Faster Query.

Cons - Bucketing will creating more files. There could be issue with many small files in some specific cases

Hope this will help !!

참고URL : https://stackoverflow.com/questions/19128940/what-is-the-difference-between-partitioning-and-bucketing-a-table-in-hive

반응형