Saiba mais sobre as decisões de design por trás do novo suporte do HBase para MOBs.
O Apache HBase é um banco de dados de valor de chave distribuído, escalável, de alto desempenho e consistente que pode armazenar uma variedade de tipos de dados binários. Ele se destaca por armazenar muitos valores relativamente pequenos (<10K) e fornecer leituras e gravações de baixa latência.
No entanto, há uma demanda crescente por armazenar documentos, imagens e outros objetos moderados (MOBs) no HBase, mantendo baixa latência para leituras e gravações. Um desses casos de uso é um banco que armazena documentos de clientes assinados e digitalizados. Como outro exemplo, as agências de transporte podem armazenar instantâneos de trânsito e carros em movimento. Esses MOBs geralmente são de gravação única.
Infelizmente, o desempenho pode diminuir em situações em que muitos valores de tamanho moderado (100 K a 10 MB) são armazenados devido à pressão de E/S cada vez maior criada pelas compactações. Considere o caso em que 1 TB de fotos de câmeras de trânsito, cada uma com 1 MB de tamanho, são armazenadas no HBase diariamente. Partes dos arquivos armazenados são compactadas várias vezes por meio de compactações menores e, eventualmente, os dados são reescritos por compactações maiores. Juntamente com o acúmulo desses MOBs, a E/S criada pelas compactações diminuirá a velocidade das compactações, bloqueará ainda mais a liberação do memstore e, eventualmente, bloqueará as atualizações. Uma grande loja MOB acionará divisões de região frequentes, reduzindo a disponibilidade das regiões afetadas.
Para resolver essas desvantagens, os engenheiros da Cloudera e da Intel implementaram o suporte MOB em uma ramificação HBase (hbase-11339:HBase MOB). Este branch será mesclado ao master no HBase 1.1 ou 1.2, e já está presente e suportado no CDH 5.4.x também.
As operações em MOBs geralmente exigem muita gravação, com raras atualizações ou exclusões e leituras relativamente infrequentes. Os MOBs geralmente são armazenados junto com seus metadados. Metadados relacionados a MOBs podem incluir, por exemplo, número do carro, velocidade e cor. Os metadados são muito pequenos em relação aos MOBs. Os metadados geralmente são acessados para análise, enquanto os MOBs geralmente são acessados aleatoriamente apenas quando são solicitados explicitamente com chaves de linha.
Os usuários desejam ler e gravar os MOBs no HBase com baixa latência nas mesmas APIs e desejam consistência forte, segurança, instantâneo e replicação do HBase entre clusters e assim por diante. Para atender a esses objetivos, os MOBs foram movidos do caminho de E/S principal do HBase para um novo caminho de E/S.
Neste post, você aprenderá sobre essa abordagem de design e por que ela foi selecionada.
Possíveis abordagens
Havia algumas abordagens possíveis para este problema. A primeira abordagem que consideramos foi armazenar MOBs no HBase com uma divisão ajustada e políticas de compactação - um desejadoMaxFileSize maior diminui a frequência de divisão de região e menos ou nenhuma compactação pode evitar a penalidade de amplificação de gravação. Essa abordagem melhoraria consideravelmente a latência de gravação e a taxa de transferência. No entanto, juntamente com o número crescente de arquivos armazenados, haveria muitos leitores abertos em um único armazenamento, ainda mais do que o permitido pelo sistema operacional. Como resultado, muita memória seria consumida e o desempenho de leitura seria degradado.
Outra abordagem foi usar um modelo HBase + HDFS para armazenar os metadados e MOBs separadamente. Nesse modelo, um único arquivo é vinculado por uma entrada no HBase. Esta é uma solução do cliente e a transação é controlada pelo cliente - nenhuma memória do lado do HBase é consumida pelos MOBs. Essa abordagem funcionaria para objetos maiores que 50 MB, mas para MOBs, muitos arquivos pequenos levam ao uso ineficiente do HDFS, pois o tamanho de bloco padrão no HDFS é 128 MB.
Por exemplo, digamos que um NameNode tenha 48 GB de memória e cada arquivo tenha 100 KB com três réplicas. Cada arquivo ocupa mais de 300 bytes de memória, portanto, um NameNode com 48 GB de memória pode conter cerca de 160 milhões de arquivos, o que nos limitaria a armazenar apenas arquivos MOB de 16 TB no total.
Como melhoria, poderíamos ter reunido os pequenos arquivos MOB em maiores – ou seja, um arquivo pode ter várias entradas MOB – e armazenar o deslocamento e o comprimento na tabela HBase para leitura rápida. No entanto, é difícil manter a consistência dos dados e gerenciar MOBs excluídos e pequenos arquivos MOB em compactações.
Além disso, se fôssemos usar essa abordagem, teríamos que considerar novas políticas de segurança, perder as propriedades de atomicidade das gravações e potencialmente perder o backup e a recuperação de desastres fornecidos pela replicação e pelos instantâneos.
Projeto MOB HBase
No final, como a maioria das preocupações em torno do armazenamento de MOBs no HBase envolve a E/S criada por compactações, a chave era tirar os MOBs do gerenciamento por regiões normais para evitar divisões e compactações de região.
O design do HBase MOB é semelhante à abordagem HBase + HDFS porque armazenamos os metadados e os MOBs separadamente. No entanto, a diferença está em um design do lado do servidor:o memstore armazena em cache os MOBs antes de serem liberados no disco, os MOBs são gravados em um HFile chamado “arquivo MOB” em cada liberação e cada arquivo MOB possui várias entradas em vez de um único arquivo em HDFS para cada MOB. Este arquivo MOB é armazenado em uma região especial. Toda a leitura e gravação podem ser usadas pelas APIs atuais do HBase.
Escreva e leia
Cada MOB tem um limite:se o comprimento do valor de uma célula for maior que esse limite, essa célula é considerada uma célula MOB.
Quando as células MOB são atualizadas nas regiões, elas são gravadas no WAL e no memstore, assim como as células normais. Na liberação, os MOBs são liberados para arquivos MOB e os metadados e caminhos dos arquivos MOB são liberados para armazenar arquivos. A consistência de dados e os recursos de replicação do HBase são nativos desse design.
As edições MOB são maiores que o normal. Na sincronização, a E/S correspondente também é maior, o que pode retardar as operações de sincronização do WAL. Se houver outras regiões que compartilham o mesmo WAL, a latência de gravação dessas regiões pode ser afetada. No entanto, se a consistência e a não volatilidade dos dados forem necessárias, o WAL é obrigatório.
As células podem se mover entre arquivos armazenados e arquivos MOB nas compactações alterando o limite. O limite padrão é 100 KB.
Conforme ilustrado abaixo, as células que contêm os caminhos dos arquivos MOB são chamadas de células de referência . As tags são retidas nas células, para que possamos continuar contando com o mecanismo de segurança do HBase.
As células de referência possuem tags de referência que as diferenciam das células normais. Uma marca de referência implica uma célula MOB em um arquivo MOB e, portanto, é necessária uma resolução adicional na leitura.
Na leitura, o scanner de armazenamento abre scanners para memstore e armazena arquivos. Se uma célula de referência for atendida, o scanner lê o caminho do arquivo a partir do valor da célula e busca a mesma chave de linha desse arquivo. O cache de bloco pode ser ativado para os arquivos MOB em varredura, o que pode acelerar a busca.
Não é necessário abrir os leitores para todos os arquivos MOB; apenas um é necessário quando necessário. Essa leitura aleatória não é afetada pelo número de arquivos MOB. Portanto, não precisamos compactar os arquivos MOB repetidamente quando eles são grandes o suficiente.
O nome do arquivo MOB é legível e compreende três partes:o MD5 da chave de início, a data mais recente das células nesse arquivo MOB e um UUID. A primeira parte é a chave de início da região de onde este arquivo MOB é liberado. Normalmente, os MOBs têm um TTL definido pelo usuário, para que você possa localizar e excluir arquivos MOB expirados comparando a segunda parte com o TTL.
Instantâneo
Para ser mais amigável com o instantâneo, os arquivos MOB são armazenados em uma região fictícia especial, em que o instantâneo, a exportação/clone da tabela e o arquivo funcionam conforme o esperado.
Ao armazenar um instantâneo em uma tabela, cria-se a região MOB no instantâneo e adiciona-se os arquivos MOB existentes no manifesto. Ao restaurar o instantâneo, crie links de arquivo na região MOB.
Limpeza e compactações
Há duas situações em que os arquivos MOB devem ser excluídos:quando o arquivo MOB expirou e quando o arquivo MOB é muito pequeno e deve ser mesclado em arquivos maiores para melhorar a eficiência do HDFS.
O HBase MOB tem uma tarefa principal:verifica os arquivos MOB, encontra os expirados determinados pela data no nome do arquivo e os exclui. Assim, o espaço em disco é recuperado periodicamente pelo envelhecimento dos arquivos MOB expirados.
Os arquivos MOB podem ser relativamente pequenos em comparação com um bloco HDFS se você gravar linhas em que apenas algumas entradas se qualifiquem como MOBs; também, pode haver células deletadas. Você precisa descartar as células excluídas e mesclar os arquivos pequenos em maiores para melhorar a utilização do HDFS. As compactações MOB apenas compactam os arquivos pequenos e os arquivos grandes não são tocados, o que evita compactações repetidas para arquivos grandes.
Algumas outras coisas para manter em mente:
- Saiba quais células são excluídas. Em cada compactação principal do HBase, os marcadores de exclusão são gravados em um arquivo del antes de serem descartados.
- Na primeira etapa das compactações MOB, esses arquivos del são mesclados em arquivos maiores.
- Todos os pequenos arquivos MOB são selecionados. Se o número de arquivos pequenos for igual ao número de arquivos MOB existentes, essa compactação será considerada a principal e será chamada de compactação ALL_FILES.
- Esses arquivos selecionados são particionados pela chave de início e data no nome do arquivo. Os pequenos arquivos em cada partição são compactados com arquivos del para que as células excluídas possam ser descartadas; enquanto isso, um novo HFile com novas células de referência é gerado, o compactador confirma o novo arquivo MOB e, em seguida, carrega esse HFile em massa no HBase.
- Depois que as compactações em todas as partições forem concluídas, se uma compactação ALL_FILES estiver envolvida, os arquivos del serão arquivados.
O ciclo de vida dos arquivos MOB é ilustrado abaixo. Basicamente, eles são criados quando o memstore é liberado e excluídos pelo HFileCleaner do sistema de arquivos quando não são referenciados pelo instantâneo ou expirados no arquivo.
Conclusão
Em resumo, o novo design do HBase MOB move os MOBs para fora do caminho de E/S principal do HBase, mantendo a maioria dos recursos de segurança, compactação e captura instantânea. Ele atende às características das operações em MOB, torna a amplificação de escrita de MOBs mais previsível e mantém baixas latências tanto na leitura quanto na escrita.
Jincheng Du é engenheiro de software da Intel e colaborador do HBase.
Jon Hsieh é engenheiro de software na Cloudera e membro do HBase/PMC. Ele também é o fundador do Apache Flume e um committer no Apache Sqoop.