HBase
 sql >> Base de Dados >  >> NoSQL >> HBase

Usando o Hive para interagir com o HBase, Parte 1

Esta postagem do blog foi publicada no Hortonworks.com antes da fusão com a Cloudera. Alguns links, recursos ou referências podem não ser mais precisos.

Este é o primeiro de dois posts que examinam o uso do Hive para interação com tabelas HBase. A segunda postagem está aqui.

Uma das coisas que me perguntam com frequência é como usar o HBase do Apache Hive. Não apenas como fazer, mas o que funciona, como funciona e como fazer bom uso disso. Eu fiz um pouco de pesquisa nesta área, então espero que isso seja útil para alguém além de mim. Este é um tópico que não abordamos no HBase in Action, talvez essas notas se tornem a base para a 2ª edição 😉 Essas notas são aplicáveis ​​ao Hive 0.11.x usado em conjunto com o HBase 0.94.x. Eles devem ser amplamente aplicáveis a 0.12.x + 0.96.x, embora eu ainda não tenha testado tudo.



O projeto Hive inclui uma biblioteca opcional para interagir com o HBase. É aqui que a camada de ponte entre os dois sistemas é implementada. A interface principal que você usa ao acessar o HBase a partir de consultas do Hive é chamada de  BaseStorageHandler . Você também pode interagir com tabelas HBase diretamente por meio dos formatos de entrada e saída, mas o manipulador é mais simples e funciona para a maioria dos usos.

Tabelas HBase do Hive


Use o HBaseStorageHandler para registrar tabelas do HBase com o metastore do Hive. Opcionalmente, você pode especificar a tabela HBase como EXTERNAL , nesse caso o Hive não criará para descartar essa tabela diretamente - você terá que usar o shell do HBase para fazer isso.

[sql]
CREATE [EXTERNAL] TABLE foo(…)
ARMAZENADO POR 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
TBLPROPERTIES ('hbase.table.name' =' bar');
[/sql]

A instrução acima registra a tabela HBase chamada bar no metastore do Hive, acessível no Hive pelo nome foo .

Sob o capô, HBaseStorageHandler está delegando interação com a tabela HBase para
HiveHBaseTableInputFormatHiveHBaseTableOutputFormat . Você pode registrar sua tabela HBase no Hive usando essas classes diretamente, se desejar. A declaração acima é aproximadamente equivalente a:

[sql]
CREATE TABLE foo(…)
ARMAZENADO COMO
INPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHBaseTableInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive .hbase.HiveHBaseTableOutputFormat'
TBLPROPERTIES ('hbase.table.name' ='bar');
[/sql]

Também é fornecido o HiveHFileOutputFormat o que significa que deve ser possível gerar HFiles para carregamento em massa do Hive também. Na prática, não consegui fazer isso funcionar de ponta a ponta (consulte HIVE-4627).

Mapeamento de esquema


Registrar a tabela é apenas o primeiro passo. Como parte desse registro, você também precisa especificar um mapeamento de coluna. É assim que você vincula os nomes das colunas do Hive à chave de linha e às colunas da tabela do HBase. Faça isso usando o hbase.columns.mapping Propriedade SerDe.

[sql]
CREATE TABLE foo(rowkey STRING, a STRING, b STRING)
ARMAZENADO POR 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ('hbase.columns .mapping' =':key,f:c1,f:c2')
TBLPROPERTIES ('hbase.table.name' ='bar');

[/sql]

Os valores fornecidos na propriedade de mapeamento correspondem um a um com os nomes das colunas da tabela hive. Os nomes das colunas do HBase são totalmente qualificados por família de colunas e você usa o token especial :key para representar a chave de linha. O de cima

exemplo cria linhas da tabela HBase bar disponível na tabela Hive foo . O foo coluna rowkey mapeia para a chave de linha da tabela do HBase, a para c1 no f família de colunas e b para c2 , também no f família.

Você também pode associar o MAP do Hive estruturas de dados para famílias de colunas do HBase. Nesse caso, apenas o STRING O tipo de colmeia é usado. O outro tipo de Hive compatível atualmente é BINARY . Veja a página wiki para mais exemplos.

Interagindo com dados


Com os mapeamentos de coluna definidos, agora você pode acessar os dados do HBase como faria com qualquer outro dado do Hive. Atualmente, apenas predicados de consulta simples são compatíveis.

[sql]
SELECT * FROM foo WHERE …;
[/sql]

Você também pode preencher uma tabela HBase usando o Hive. Isso funciona com o INTO e OVERWRITE cláusulas.

[sql]
FROM source_hive_table INSERT INTO TABLE my_hbase_table
SELECT source_hive_table.* WHERE …;
[/sql]

Esteja ciente de que há uma regressão no Hive 0.12.0 que quebra esse recurso, consulte HIVE-5515.

Na prática


Ainda é necessário um pouco de sutileza para que tudo seja conectado corretamente no tempo de execução. O módulo de interação do HBase é totalmente opcional, portanto, você precisa certificar-se de que ele e suas dependências do HBase estejam disponíveis no classpath do Hive.

[bash]
$ export HADOOP_CLASSPATH=…
$ hive -e “CREATE TABLE … STORED BY ‘org.apache…HBaseStorageHandler'”
[/bash]

O ambiente de instalação pode lidar melhor com isso para os usuários, mas, por enquanto, você deve gerenciá-lo sozinho. Idealmente, a hive O script bin pode detectar a presença do HBase e fazer automaticamente o CLASSPATH necessário ajustes. Esse aprimoramento parece ser rastreado no HIVE-2055. A última milha é fornecida pela própria distribuição, garantindo que as variáveis ​​de ambiente sejam definidas para hive . Essa funcionalidade é fornecida pelo BIGTOP-955.

Você também precisa garantir que os jars necessários sejam enviados para os trabalhos do MapReduce ao executar as instruções do Hive. O Hive fornece um mecanismo para enviar dependências de job adicionais por meio do recurso auxjars.

[bash]
$ export HIVE_AUX_JARS_PATH=…
$ hive -e “SELECT * FROM …”
[/bash]

Descobri um pequeno bug nas compilações do HDP-1.3 que mascara os valores especificados pelo usuário de HIVE_AUX_JARS_PATH . Com direitos administrativos, isso é facilmente corrigido corrigindo a linha em hive-env.sh respeitar um valor existente. A
solução em scripts de usuário é usar o SET declaração para fornecer um valor depois de lançar a CLI do Hive.

[bash]
SET hive.aux.jars.path =…
[/bash]

O Hive deve ser capaz de detectar quais jars são necessários e adicioná-los sozinho. O HBase fornece os  TableMapReduceUtils#addDependencyJars  métodos para este fim. Parece que isso é feito em hive-0.12.0, pelo menos de acordo com HIVE-2379.

Trabalho futuro


Muito foi dito sobre o suporte adequado para pushdown de predicado (HIVE-1643, HIVE-2854, HIVE-3617,
HIVE-3684) e reconhecimento de tipo de dados (HIVE-1245, HIVE-2599). Eles andam de mãos dadas, pois a semântica de predicado é definida em termos dos tipos nos quais eles operam. Mais poderia ser feito para mapear os tipos de dados complexos do Hive, como Maps e Structs, nas famílias de colunas do HBase (HIVE-3211). O suporte para carimbos de data/hora do HBase é um pouco confuso. eles não são disponibilizados para aplicativos Hive com qualquer nível de granularidade (HIVE-2828, HIVE-2306). A única interação que um usuário tem é por meio da configuração do gerenciador de armazenamento para escrever um carimbo de data/hora personalizado com todas as operações.

Do ponto de vista do desempenho, há coisas que o Hive pode fazer hoje (ou seja, não dependendo dos tipos de dados) para aproveitar o HBase. Há também a possibilidade de um Hive com reconhecimento de HBase para fazer uso de tabelas HBase como local de armazenamento intermediário (HIVE-3565), facilitando junções do lado do mapa com tabelas de dimensão carregadas no HBase. O Hive pode usar a estrutura indexada natural do HBase (HIVE-3634, HIVE-3727), potencialmente salvando grandes varreduras. Atualmente, o usuário não tem (nenhum?) controle sobre as verificações executadas. A configuração por trabalho ou pelo menos por tabela deve ser ativada (HIVE-1233). Isso permitiria que um usuário experiente em HBase fornecesse ao Hive dicas sobre como ele deve interagir com o HBase. O suporte para amostragem dividida simples de tabelas HBase (HIVE-3399) também pode ser feito facilmente porque o HBase já gerencia partições de tabela.

Outros canais de acesso


Tudo o que foi discutido até agora exigiu que o Hive interagisse com HBase RegionServers on-line. Os aplicativos podem obter uma taxa de transferência significativa e desfrutar de maior flexibilidade ao interagir diretamente com os dados do HBase persistidos no HDFS. Isso também tem o benefício de impedir que as cargas de trabalho do Hive interfiram nos aplicativos HBase on-line vinculados a SLA (pelo menos até vermos melhorias do HBase no isolamento de QOS entre tarefas, HBASE-4441).

Como mencionado anteriormente, existe o HiveHFileOutputFormat . A resolução do HIVE-4627 deve tornar o Hive uma maneira direta de gerar HFiles para carregamento em massa. Depois de criar os HFiles usando o Hive, ainda há a última etapa de execução dos
LoadIncrementalHFiles utilitário para copiá-los e registrá-los nas regiões. Para isso, o HiveStorageHandler  A interface precisará de algum tipo de gancho para influenciar o plano de consulta à medida que ele é criado, permitindo anexar etapas. Uma vez instalado, deve ser possível SET um sinalizador de tempo de execução, alternando um INSERT  operação para usar o carregamento em massa.

O HBase introduziu recentemente o recurso de instantâneo de tabela. Isso permite que um usuário crie uma visualização pontual persistente de uma tabela, persistida no HDFS. O HBase pode restaurar uma tabela de um snapshot para um estado anterior e criar uma tabela totalmente nova a partir de um snapshot existente. Atualmente, o Hive não é compatível com a leitura de um snapshot do HBase. Por falar nisso, o HBase ainda não é compatível com jobs MapReduce em snapshots, embora o recurso esteja em andamento (HBASE-8369).

Conclusões


A interface entre HBase e Hive é jovem, mas tem um bom potencial. Há muitas frutas fáceis que podem ser colhidas para tornar as coisas mais fáceis e rápidas. O problema mais evidente que impede o desenvolvimento de aplicativos reais é a incompatibilidade de impedância entre o esquema denso e tipado do Hive e o esquema esparso e não tipado do HBase. Este é tanto um problema cognitivo quanto uma questão técnica. As soluções aqui permitiriam várias melhorias, incluindo muitas em termos de melhorias de desempenho. Espero que o trabalho contínuo para adicionar tipos de dados ao HBase (HBASE-8089) possa ajudar a preencher essa lacuna.

As operações básicas geralmente funcionam, pelo menos de maneira rudimentar. Você pode ler dados e gravar dados de volta no HBase usando o Hive. A configuração do ambiente é um processo opaco e manual, que provavelmente impede os novatos de adotar as ferramentas. Há também a questão das operações em massa - o suporte para escrever HFiles e ler instantâneos do HBase usando o Hive está totalmente ausente neste ponto. E, claro, há bugs espalhados por toda parte. A maior melhoria recente é a descontinuação da interface do HCatalog, removendo a decisão inicial necessária sobre qual interface usar.

O Hive fornece uma interface SQL muito útil em cima do HBase, que se integra facilmente a muitos fluxos de trabalho ETL existentes. Essa interface requer a simplificação de algumas das semânticas do BigTable que o HBase fornece, mas o resultado será abrir o HBase para um público muito mais amplo de usuários. A interoperabilidade do Hive complementa extremamente bem a experiência fornecida pela Phoenix. O Hive tem a vantagem de não exigir as complexidades de implantação atualmente exigidas por esse sistema. Esperamos que a definição comum de tipos permita um futuro complementar.