Respostas:
Os dados de particionamento costumam ser usados para distribuir a carga horizontalmente, isso traz benefícios de desempenho e ajuda na organização de dados de maneira lógica. Exemplo : se estamos lidando com uma employee
tabela grande e geralmente executamos consultas com WHERE
cláusulas que restringem os resultados a um país ou departamento específico. Para uma resposta mais rápida da consulta, a tabela Hive pode ser PARTITIONED BY (country STRING, DEPT STRING)
. As tabelas de particionamento alteram como o Hive estrutura o armazenamento de dados e o Hive agora cria subdiretórios que refletem a estrutura de particionamento, como
... / funcionários / país = ABC / DEPT = XYZ .
Se os limites de consulta para funcionários de country=ABC
, ele verificará apenas o conteúdo de um diretório country=ABC
. Isso pode melhorar drasticamente o desempenho da consulta, mas apenas se o esquema de particionamento refletir uma filtragem comum. O recurso de particionamento é muito útil no Hive, no entanto, um design que cria muitas partições pode otimizar algumas consultas, mas pode ser prejudicial para outras consultas importantes. Outra desvantagem é ter muitas partições: o grande número de arquivos e diretórios do Hadoop que são criados desnecessariamente e sobrecarga para o NameNode, pois ele deve manter todos os metadados do sistema de arquivos na memória.
O balde é outra técnica para decompor conjuntos de dados em partes mais gerenciáveis. Por exemplo, suponha que uma tabela usando date
como partição de nível superior e employee_id
como partição de segundo nível leve a muitas partições pequenas. Em vez disso, se juntarmos a tabela de funcionários e usarmos employee_id
como a coluna de balde, o valor dessa coluna será dividido por hashes por um número definido pelo usuário em baldes. Os registros com o mesmo employee_id
sempre serão armazenados no mesmo balde. Supondo que o número de employee_id
seja muito maior que o número de buckets, cada bucket terá muitos employee_id
. Ao criar a tabela, você pode especificar comoCLUSTERED BY (employee_id) INTO XX BUCKETS;
onde XX é o número de baldes. O balde tem várias vantagens. O número de buckets é fixo para que não flutue com os dados. Se duas tabelas forem agrupadas employee_id
, o Hive poderá criar uma amostra logicamente correta. O balde também ajuda a fazer junções eficientes no lado do mapa, etc.
Faltam alguns detalhes nas explicações anteriores. Para entender melhor como funciona o particionamento e o bucket, verifique como os dados são armazenados no hive. Digamos que você tenha uma mesa
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
o hive armazenará dados em uma hierarquia de diretórios como
/user/hive/warehouse/mytable/y=2015/m=12/d=02
Portanto, você deve ter cuidado ao particionar, porque, por exemplo, se você particionar por employee_id e tiver milhões de funcionários, acabará tendo milhões de diretórios em seu sistema de arquivos. O termo ' cardinalidade ' refere-se ao número de valor possível que um campo pode ter. Por exemplo, se você tem um campo de 'país', os países do mundo são cerca de 300, portanto a cardinalidade seria ~ 300. Para um campo como 'timestamp_ms', que muda a cada milissegundo, a cardinalidade pode ser bilhões. Em geral, ao escolher um campo para particionamento, ele não deve ter uma alta cardinalidade, porque você acabará com muitos diretórios em seu sistema de arquivos.
O armazenamento em cluster, também conhecido como depósito, resultará em um número fixo de arquivos, pois você especifica o número de depósitos. O que a seção fará é entrar em campo, calcular um hash e atribuir um registro a esse balde. Mas o que acontece se você usar, digamos, 256 buckets e o campo em que está bucketed tiver uma cardinalidade baixa (por exemplo, é um estado dos EUA, então pode haver apenas 50 valores diferentes)? Você terá 50 depósitos com dados e 206 depósitos sem dados.
Alguém já mencionou como as partições podem reduzir drasticamente a quantidade de dados que você está consultando. Portanto, na minha tabela de exemplo, se você deseja consultar apenas a partir de uma determinada data, a partição por ano / mês / dia reduzirá drasticamente a quantidade de IO. Eu acho que alguém também mencionou como o bucketing pode acelerar junções com outras tabelas que têm exatamente o mesmo bucket , portanto, no meu exemplo, se você estiver juntando duas tabelas no mesmo employee_id, o hive poderá fazer o join bucket por bucket (ainda melhor se eles já estiverem classificados por employee_id, pois ele irá mesclar partes que já estão classificadas, o que funciona em tempo linear, também conhecido como O (n)).
Portanto, o depósito funciona bem quando o campo tem alta cardinalidade e os dados são distribuídos igualmente entre os depósitos. O particionamento funciona melhor quando a cardinalidade do campo de particionamento não é muito alta.
Além disso, é possível particionar em vários campos , com um pedido (ano / mês / dia é um bom exemplo), enquanto você pode agrupar apenas um campo .
Acho que estou atrasado em responder a essa pergunta, mas ela continua aparecendo no meu feed.
Navneet forneceu uma resposta excelente. Adicionando a ele visualmente.
O particionamento ajuda na eliminação de dados, se usado na cláusula WHERE, onde o bucket ajuda a organizar os dados em cada partição em vários arquivos, para que o mesmo conjunto de dados seja sempre gravado no mesmo bucket. Ajuda muito na junção de colunas.
Suponha que você tenha uma tabela com cinco colunas, nome, data_do_servidor, some_col3, some_col4 e some_col5. Suponha que você tenha particionado a tabela em server_date e agrupado a coluna de nome em 10 blocos, sua estrutura de arquivos será semelhante a abaixo.
Aqui server_date = xyz é a partição e 000 arquivos são os intervalos em cada partição. Os buckets são calculados com base em algumas funções de hash; portanto, as linhas com name = Sandy sempre estarão no mesmo bucket.
Particionamento do Hive:
A partição divide grande quantidade de dados em várias fatias com base no valor de uma (s) coluna (s) da tabela.
Suponha que você esteja armazenando informações de pessoas em todo o mundo espalhadas por mais de 196 países, abrangendo cerca de 500 milhões de entradas. Se você deseja consultar pessoas de um país em particular (cidade do Vaticano), na ausência de particionamento, é necessário digitalizar todas as 500 crores de entradas, mesmo para buscar milhares de entradas de um país. Se você particionar a tabela com base no país, poderá ajustar o processo de consulta apenas verificando os dados de apenas uma partição de país. A partição Hive cria um diretório separado para um valor de coluna (s).
Prós:
Contras:
Bucketing da colmeia:
O agrupamento decompõe os dados em partes mais gerenciáveis ou iguais.
Com o particionamento, é possível criar várias pequenas partições com base nos valores da coluna. Se você for fazer o bucket, estará restringindo o número de buckets para armazenar os dados. Esse número é definido durante os scripts de criação de tabela.
Prós
Contras
Antes de Bucketing
entrarmos, precisamos entender o que Partitioning
é. Vamos tomar a tabela abaixo como exemplo. Observe que forneci apenas 12 registros no exemplo abaixo para entender o nível iniciante. Em cenários em tempo real, você pode ter milhões de registros.
PARTITIONING
---------------------
Partitioning
é usado para obter desempenho ao consultar os dados. Por exemplo, na tabela acima, se escrevermos o sql abaixo, ele precisará verificar todos os registros da tabela, o que reduz o desempenho e aumenta a sobrecarga.
select * from sales_table where product_id='P1'
Para evitar a varredura completa da tabela e ler apenas os registros relacionados product_id='P1'
, podemos particionar (dividir os arquivos da tabela da seção) em vários arquivos com base na product_id
coluna. Por isso, o arquivo da tabela de seção será dividido em dois arquivos, um com product_id='P1'
e outro com product_id='P2'
. Agora, quando executamos a consulta acima, ela examinará apenas o product_id='P1'
arquivo.
../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2
A sintaxe para criar a partição é fornecida abaixo. Observe que não devemos usar a product_id
definição de coluna junto com as colunas não particionadas na sintaxe abaixo. Isso deve estar apenas na partitioned by
cláusula.
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10))
Contras : devemos ter muito cuidado ao particionar. Ou seja, não deve ser usado para as colunas em que o número de valores repetidos é muito menor (especialmente as colunas da chave primária), pois aumenta o número de arquivos particionados e aumenta a sobrecarga para o Name node
.
BUCKETING
------------------
Bucketing
é usado para superar o cons
que eu mencionei na seção de particionamento. Isso deve ser usado quando houver muito poucos valores repetidos em uma coluna (exemplo - coluna da chave primária). Isso é semelhante ao conceito de índice na coluna de chave primária no RDBMS. Em nossa tabela, podemos Sales_Id
usar a coluna para o balde. Será útil quando precisarmos consultar a sales_id
coluna.
Abaixo está a sintaxe para o bucket.
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
Aqui, dividiremos ainda mais os dados em mais alguns arquivos sobre as partições.
Como especificamos os 3
buckets, ele é dividido em três arquivos cada para cada um product_id
. Ele usa internamente modulo operator
para determinar em qual balde cada um sales_id
deve ser armazenado. Por exemplo, para o product_id='P1'
, o sales_id=1
serão armazenados em 000001_0 arquivo (ou seja, 1% 3 = 1), sales_id=2
será armazenado em 000002_0 ficheiro (isto é, 2% 3 = 2), sales_id=3
será armazenado em 000000_0 ficheiro (isto é, 3% 3 = 0) etc.
hashCode()
da sequência como a função hash? O programador pode escolher a função hash?
A diferença é que o bucket divide os arquivos por Nome da coluna e o particionamento divide os arquivos em Por um valor específico na tabela
Espero ter definido corretamente
Há ótimas respostas aqui. Gostaria de mantê-lo curto para memorizar a diferença entre partição e baldes.
Você geralmente particiona em uma coluna menos exclusiva. E balde na coluna mais exclusiva.
Exemplo se você considerar a população mundial com país, nome da pessoa e seu ID bio-métrico como exemplo. Como você pode imaginar, o campo do país seria a coluna menos exclusiva e o ID bio-métrico seria a coluna mais exclusiva. Idealmente, você precisaria particionar a tabela por país e agrupá-la pelo ID bio-métrico.
O uso de Partições na tabela Hive é altamente recomendado pelo motivo abaixo -
Exemplo: -
Suponha que o arquivo de entrada (100 GB) esteja carregado na tabela temp-hive e contenha dados bancários de diferentes geografias.
Tabela de colméia sem partição
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
O problema com esta abordagem é - Ele verificará os dados inteiros em busca de qualquer consulta que você executar nesta tabela. O tempo de resposta será alto se comparado a outras abordagens nas quais o particionamento e o bucket são usados.
Tabela de colméia com partição
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)
Prós - Aqui é possível acessar os dados mais rapidamente quando se trata de consultar dados para transações geográficas específicas. Contras - A inserção / consulta de dados pode ser melhorada dividindo-se os dados dentro de cada partição. Consulte a opção Bucketing abaixo.
Mesa de colméia com partição e caçamba
Nota: Crie tabela de seção ..... com "CLUSTERED BY (Partiton_Column) em 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)
Prós - inserção mais rápida. Consulta mais rápida.
Contras - O bucket irá criar mais arquivos. Pode haver um problema com muitos arquivos pequenos em alguns casos específicos
Espero que isso ajude !!