Diferenças entre o HBase e o Bigtable

Uma maneira de acessar o Bigtable é usar uma versão personalizada do cliente Apache HBase para Java. Em geral, o cliente personalizado expõe a mesma API de uma instalação padrão do HBase. Nesta página, descrevemos as diferenças entre o cliente HBase do Cloud Bigtable para Java e uma instalação padrão do HBase. Muitas dessas diferenças estão relacionadas a tarefas de gerenciamento processadas automaticamente pelo Bigtable.

O cliente HBase do Cloud Bigtable para Java é destinado a clientes que estão migrando do HBase para o Bigtable e querem continuar usando a API HBase. Em todos os outros casos, os desenvolvedores de Java precisam usar o cliente do Cloud Bigtable para Java, que chama as APIs do Bigtable.

Grupos de colunas

Ao criar um grupo de colunas, não é possível configurar o tamanho do bloco ou o método de compactação, seja com o shell do HBase ou a API HBase. O Bigtable gerencia o tamanho e a compactação do bloco para você.

Além disso, quando usado para receber informações de uma tabela, o shell do HBase sempre informará que nenhum grupo de colunas usa a compactação. Na realidade, o Bigtable usa métodos de compactação exclusivos para todos os seus dados.

As seguintes configurações de grupo de colunas são ignoradas porque o Bigtable gerencia o armazenamento subjacente para você:

  • BLOCKCACHE
  • BLOCKSIZE
  • BLOOMFILTER
  • CACHE_BLOOMS_ON_WRITE
  • CACHE_DATA_IN_L1
  • CACHE_DATA_ON_WRITE
  • CACHE_INDEX_ON_WRITE
  • COMPRESS_TAGS
  • COMPRESSION
  • COMPRESSION_COMPACT
  • DATA_BLOCK_ENCODING
  • EVICT_BLOCKS_ON_CLOSE
  • IN_MEMORY
  • KEEP_DELETED_CELLS
  • PREFETCH_BLOCKS_ON_OPEN
  • REPLICATION_SCOPE

As configurações VERSIONS, MIN_VERSIONS e TTL são convertidas em políticas de coleta de lixo do Bigtable.

O Bigtable exige que os nomes dos grupos de colunas sigam a expressão regular [_a-zA-Z0-9][-_.a-zA-Z0-9]*. Se você estiver importando dados do HBase para o Bigtable, talvez seja necessário alterar os nomes das famílias para seguir esse padrão.

Linhas e células

  • Não é possível definir uma ACL para uma linha individual. As visualizações autorizadas do Bigtable permitem conceder acesso a um subconjunto dos dados de uma tabela, mas não são expostas pela API HBase.
  • Não é possível definir a visibilidade de células individuais.
  • Não há compatibilidade com tags. Não é possível usar a classe org.apache.hadoop.hbase.Tag para adicionar metadados a células individuais. Todas as tags adicionadas a uma célula são descartadas antes que ela seja gravada.

Mutações e exclusões

  • As operações Append no Bigtable são totalmente atômicas para leitores e gravadores. Os leitores nunca poderão ler uma operação Append parcialmente aplicada.
  • As operações Increment são atômicas, mas não é possível definir um período em um Increment.
  • Um objeto RowMutations que você transmite para Table#mutateRow() pode conter operações Put e Delete ou operações Append e Increment, mas não ambas. Objetos RowMutations que contêm operações Append ou Increment não são compatíveis com batch(), checkAndMutate() ou BufferedMutator.
  • É possível excluir uma versão específica de uma coluna com base no carimbo de data/hora. No entanto, os seguintes tipos de exclusão não são compatíveis:

    • Excluir apenas a versão mais recente de uma coluna
    • Excluir todos os valores em uma linha que têm um carimbo de data/hora específico
    • Excluir todos os valores em um grupo de colunas em um carimbo de data/hora específico ou antes dele

    Como resultado, os seguintes métodos na classe org.apache.hadoop.hbase.client.Delete não são compatíveis: + new Delete(byte[] row, long timestamp) + addColumn(byte[] family, byte[] qualifier) + addFamily(byte[] family, long timestamp) + addFamilyVersion(byte[] family, long timestamp)

  • No HBase, as exclusões ocultam puts, mas o Bigtable não oculta puts após a exclusão quando as solicitações de put são enviadas após as solicitações de exclusão. Isso significa que, no Bigtable, uma solicitação de gravação enviada a uma célula não é afetada por uma solicitação de exclusão enviada anteriormente para a mesma célula.

Recebimentos e verificações

Coprocessadores

Coprocessadores não são compatíveis. Não é possível criar classes que implementam a interface org.apache.hadoop.hbase.coprocessor.

Filtros

A tabela a seguir lista os filtros compatíveis no pacote org.apache.hadoop.hbase.filter. Todos os outros filtros nesse pacote não são compatíveis e geram um UnsupportedOperationException.

Com suporte Compatível, com limitações
  1. Na maioria dos casos, PrefixFilter verifica se há linhas no PrefixFilter. No entanto, se PrefixFilter fizer parte de um FilterList e tiver o operador MUST_PASS_ONE, o Bigtable não poderá determinar o intervalo implícito e realizará uma verificação não filtrada da linha inicial para a linha de parada. Use PrefixFilter com BigtableExtendedScan ou uma combinação de filtros para otimizar a performance nesse caso.
  2. Requer um único grupo de colunas somente quando você usa um qualificador de coluna como o deslocamento de coluna.
  3. Compatível somente com um único grupo de colunas.
  4. Aceita apenas o operador EQUAL, com o comparador BinaryComparator ou RegexStringComparator.
  5. Não é possível criar o filtro com new KeyOnlyFilter(true).
  6. Não pode fazer parte de um FilterList que usa o operador MUST_PASS_ONE.
  7. Um PageFilter precisa ser o filtro de nível superior ou o último filtro em um FilterList de nível superior que usa o operador MUST_PASS_ALL, que é o comportamento padrão. Não há suporte para um PageFilter em um FilterList que usa o operador MUST_PASS_ONE.
  8. Aceita apenas o comparador BinaryComparator ou o comparador RegexStringComparator com o operador EQUAL. Se qualquer operador diferente de EQUAL for usado, apenas um grupo de colunas será compatível.
  9. É compatível apenas com os seguintes comparadores:
    • BinaryComparator
    • RegexStringComparator sem sinalizações (as sinalizações são ignoradas) e o operador EQUAL
  10. Depende do filtro de condição do Bigtable, que pode ser lento. Compatível, mas não recomendado.
  11. Somente um WhileMatchFilter é aceito por verificação.
ColumnCountGetFilter
ColumnPrefixFilter
FilterList
FirstKeyOnlyFilter
FuzzyRowFilter
MultipleColumnPrefixFilter
PrefixFilter 1
RandomRowFilter
TimestampsFilter
ColumnPaginationFilter 2
ColumnRangeFilter 3
FamilyFilter 4
KeyOnlyFilter 5
MultiRowRangeFilter 6
PageFilter 7
QualifierFilter 8
RowFilter 4
SingleColumnValueExcludeFilter 3, 9, 10
SingleColumnValueFilter 9, 10
ValueFilter 9
WhileMatchFilter 6, 11

Além disso, as seguintes diferenças afetam os filtros do Bigtable:

  • Somente os comparadores BinaryComparator e RegexStringComparator são compatíveis. Todos os outros comparadores não são compatíveis e geram um UnsupportedOperationException.
  • Em filtros que usam o comparador de expressões regulares (org.apache.hadoop.hbase.filter.RegexStringComparator), as expressões regulares usam a sintaxe RE2, não a sintaxe Java.
  • Filtros personalizados não são compatíveis. Não é possível criar classes que herdam de org.apache.hadoop.hbase.filter.Filter. Para usar um filtro do Bigtable que não tenha equivalente no HBase, envolva-o em um com.google.cloud.bigtable.hbase.filter.BigtableFilter.
  • Há um limite de tamanho de 20 KB em expressões de filtro, e os filtros não podem ser aninhados em mais de 20 níveis de profundidade. Como solução alternativa para reduzir o tamanho de uma expressão de filtro, use uma coluna complementar que armazene o valor de hash dos critérios de filtro.

Carimbos de data/hora

O Bigtable armazena carimbos de data/hora em microssegundos, enquanto o HBase armazena carimbos de data/hora em milissegundos. Essa distinção tem implicações quando você usa a biblioteca de cliente do HBase para o Bigtable e tem dados com carimbos de data/hora invertidos.

A biblioteca de cliente converte entre microssegundos e milissegundos, mas como o maior carimbo de data/hora do HBase que o Bigtable pode armazenar é Long.MAX_VALUE/1000, qualquer valor maior que esse será convertido em Long.MAX_VALUE/1000. Como resultado, valores grandes de carimbo de data/hora invertidos podem não ser convertidos corretamente.

Administração

Nesta seção, descrevemos como o cliente HBase do Bigtable para Java implementa a interface org.apache.hadoop.hbase.client.Admin. Como o Bigtable lida automaticamente com a maioria das tarefas de gerenciamento de cluster e armazenamento, muitos métodos administrativos do HBase não são aplicáveis. Qualquer método Admin que não esteja listado nesta seção como compatível ou que não tenha efeito não é compatível e gera uma UnsupportedOperationException.

Gerenciamento de tabelas

Os seguintes métodos Admin para gerenciar tabelas e grupos de colunas são compatíveis:

  • addColumnFamily(TableName tableName, ColumnFamilyDescriptor columnFamily) e addColumnFamilyAsync(TableName tableName, ColumnFamilyDescriptor columnFamily) (HBase 1.x: addColumn(TableName tableName, HColumnDescriptor column))
  • createTable(TableDescriptor desc), createTable(TableDescriptor desc, byte[][] splitKeys), createTable(TableDescriptor desc, byte[] startKey, byte[] endKey, int numRegions), createTableAsync(TableDescriptor desc) e createTableAsync(TableDescriptor desc, byte[][] splitKeys)
  • deleteColumnFamily(TableName tableName, byte[] columnName) e deleteColumnFamilyAsync(TableName tableName, byte[] columnName) (HBase 1.x: deleteColumn(TableName tableName, byte[] columnName))
  • deleteTable(TableName tableName), deleteTableAsync(TableName tableName), deleteTables(Pattern pattern) e deleteTables(String regex)
  • disableTable(TableName tableName), disableTableAsync(TableName tableName), disableTables(Pattern pattern) e disableTables(String regex)
  • enableTable(TableName tableName), enableTableAsync(TableName tableName), enableTables(Pattern pattern) e enableTables(String regex)
  • getAlterStatus(TableName tableName) e getAlterStatus(byte[] tableName)
  • getDescriptor(TableName tableName), getTableDescriptor(TableName tableName), getTableDescriptors(List<String> names) e getTableDescriptorsByTableName(List<TableName> tableNames)
  • isTableAvailable(TableName tableName) e isTableAvailable(TableName tableName, byte[][] splitKeys)
  • isTableDisabled(TableName tableName) e isTableEnabled(TableName tableName)
  • listTableDescriptors(), listTableDescriptors(List<TableName> tableNames), listTableDescriptors(Pattern pattern) e listTableDescriptors(Pattern pattern, boolean includeSysTables) (HBase 1.x: listTables(), listTables(Pattern pattern), listTables(Pattern pattern, boolean includeSysTables), listTables(String regex) e listTables(String regex, boolean includeSysTables))
  • listTableNames(), listTableNames(Pattern pattern), listTableNames(Pattern pattern, boolean includeSysTables), listTableNames(String regex) e listTableNames(String regex, boolean includeSysTables)
  • modifyColumnFamily(TableName tableName, ColumnFamilyDescriptor columnFamily) e modifyColumnFamilyAsync(TableName tableName, ColumnFamilyDescriptor columnFamily) (HBase 1.x: modifyColumn(TableName tableName, HColumnDescriptor column))
  • modifyTable(TableDescriptor td), modifyTable(TableName tableName, TableDescriptor td), modifyTableAsync(TableDescriptor td) e modifyTableAsync(TableName tableName, TableDescriptor td)
  • tableExists(TableName tableName)
  • truncateTable(TableName tableName, boolean preserveSplits) e truncateTableAsync(TableName tableName, boolean preserveSplits)

Os seguintes métodos de gerenciamento de tabelas compatíveis se comportam de maneira diferente no Bigtable ou ignoram determinados parâmetros:

  • Não é possível desativar as tabelas do Bigtable. disableTable(), disableTableAsync(), disableTables(), enableTable(), enableTableAsync() e enableTables() mudam o estado da tabela apenas na memória do cliente (que isTableDisabled() e isTableEnabled() leem).
  • modifyTable() e modifyTableAsync() aplicam apenas mudanças a grupos de colunas. Os atributos no nível da tabela são ignorados.
  • truncateTable() e truncateTableAsync() excluem todos os dados da tabela. O parâmetro preserveSplits é ignorado.
  • As sobrecargas listTableDescriptors(), listTables() e listTableNames() que aceitam um parâmetro includeSysTables ignoram includeSysTables, porque o Bigtable não tem tabelas do sistema.
  • isTableAvailable(TableName tableName, byte[][] splitKeys) verifica apenas se a tabela existe e ignora o parâmetro splitKeys.
  • getAlterStatus() sempre retorna (0, 0) porque as modificações de esquema no Bigtable são síncronas.

Tarefas como compactação e divisão de tabelas são processadas automaticamente. Como resultado, os seguintes métodos não têm efeito:

  • compact(TableName tableName)
  • compact(TableName tableName, byte[] columnFamily)
  • majorCompact(TableName tableName)
  • majorCompact(TableName tableName, byte[] columnFamily)
  • split(TableName tableName)
  • split(TableName tableName, byte[] splitPoint)

Snapshots

Os métodos de snapshot do HBase criam e gerenciam backups do Bigtable. Como os backups são armazenados em um cluster específico, se a instância tiver mais de um cluster, será necessário definir a propriedade de configuração google.bigtable.snapshot.cluster.id para o cluster a ser usado. Os backups criados com snapshot() expiram após o número de segundos na propriedade de configuração google.bigtable.snapshot.default.ttl.secs (24 horas por padrão). O cloneSnapshot() restaura de um backup para uma nova tabela.

Os seguintes métodos de snapshot são compatíveis com Admin:

  • cloneSnapshot(byte[] snapshotName, TableName tableName)
  • cloneSnapshot(String snapshotName, TableName tableName)
  • deleteSnapshot(byte[] snapshotName)
  • deleteSnapshot(String snapshotName)
  • snapshot(byte[] snapshotName, TableName tableName)
  • snapshot(String snapshotName, TableName tableName)

Além disso, o AsyncAdmin é compatível com listSnapshots(), listSnapshots(Pattern pattern) e snapshot(SnapshotDescription snapshot). Todos os outros métodos de snapshot, incluindo restoreSnapshot(), deleteSnapshots(), deleteTableSnapshots(), listTableSnapshots() e cloneSnapshot(String snapshotName, TableName tableName, boolean restoreAcl), não são compatíveis e geram um UnsupportedOperationException.

Gerenciamento de regiões

O Bigtable usa blocos, que são semelhantes a regiões. Os métodos a seguir para recuperar informações de região são compatíveis, com diferenças em relação ao HBase padrão:

  • getRegions(TableName tableName) e getTableRegions(TableName tableName), assim como os métodos na interface org.apache.hadoop.hbase.client.RegionLocator, retornam limites aproximados com base em uma amostra de chaves de linha na tabela. Os nomes de servidor nas regiões retornadas não são servidores reais.
  • getRegionMetrics(ServerName serverName, TableName tableName) ignora o parâmetro serverName e retorna métricas aproximadas de tamanho de região com base em uma amostra de chaves de linha na tabela.

Como o Bigtable gerencia os tablets automaticamente, os métodos a seguir não têm efeito:

  • assign(byte[] regionName)
  • compactRegion(byte[] regionName)
  • compactRegion(byte[] regionName, byte[] columnFamily)
  • flushRegion(byte[] regionName)
  • majorCompactRegion(byte[] regionName)
  • majorCompactRegion(byte[] regionName, byte[] columnFamily)
  • splitRegion(byte[] regionName)
  • splitRegion(byte[] regionName, byte[] splitPoint)

No HBase 1.x, compactRegionServer(ServerName sn, boolean major), mergeRegions(byte[] encodedNameOfRegionA, byte[] encodedNameOfRegionB, boolean forcible), move(byte[] encodedRegionName, byte[] destServerName) e unassign(byte[] regionName, boolean force) também não têm efeito. Os equivalentes do HBase 2.x não são compatíveis e geram um UnsupportedOperationException.

Status e conexão do cluster

O Bigtable lida com as tarefas de manutenção de cluster automaticamente. Portanto, os métodos de manutenção em Admin geram um UnsupportedOperationException. Somente os seguintes métodos de conexão e status são compatíveis:

  • close() não tem efeito.
  • getClusterMetrics(), getClusterMetrics(EnumSet<Option> options) e getClusterStatus() retornam valores de marcador com listas de servidores vazias, e getClusterMetrics(EnumSet<Option> options) ignora o parâmetro options.
  • getConfiguration() retorna o objeto Configuration do cliente.
  • getConnection() retorna o objeto Connection do cliente.

Namespaces

O Bigtable não usa namespaces. Use os prefixos de chave de linha para simular namespaces.

Por padrão, todos os métodos de namespace geram um UnsupportedOperationException. No entanto, se você definir a propriedade de configuração google.bigtable.namespace.warnings como true, os métodos a seguir vão registrar um aviso e não terão efeito (retornando null ou um resultado vazio) em vez de gerar uma exceção:

  • createNamespace(NamespaceDescriptor descriptor)
  • deleteNamespace(String name)
  • deleteNamespaceAsync(String name)
  • getNamespaceDescriptor(String name)
  • listNamespaceDescriptors()
  • listTableDescriptorsByNamespace(byte[] name)
  • listTableDescriptorsByNamespace(String name)
  • listTableNamesByNamespace(String name)
  • modifyNamespace(NamespaceDescriptor descriptor)

Mesmo quando google.bigtable.namespace.warnings está definido como true, listNamespaces() gera um UnsupportedOperationException.

Outros recursos administrativos

O Bigtable não é compatível com os métodos Admin nas seguintes categorias, e chamá-los gera um UnsupportedOperationException:

  • Grupos de localidade: o Bigtable não permite especificar grupos de localidade para grupos de colunas.
  • Coprocessadores e procedimentos distribuídos: o Bigtable não é compatível com coprocessadores ou procedimentos distribuídos.
  • Cotas: para saber mais sobre as cotas do Bigtable, consulte Cotas e limites.
  • Replicação: o Bigtable replica dados automaticamente entre os clusters em uma instância. Para mais detalhes, consulte Visão geral da replicação. Para replicar do HBase para o Bigtable, consulte Replicar do HBase para o Bigtable.
  • Controle de acesso: o Bigtable usa o IAM para controle de acesso.
  • Grupos RegionServer: o Bigtable gerencia servidores automaticamente e não expõe grupos RegionServer.