Diferencias entre HBase y Bigtable

Una forma de acceder a Bigtable es usar una versión personalizada del cliente de Apache HBase para Java. Por lo general, en el cliente personalizado se expone la misma API que en la instalación estándar de HBase. En esta página, se describen las diferencias entre el cliente de Cloud Bigtable de HBase para Java y una instalación estándar de HBase. Muchas de estas diferencias se relacionan con las tareas de administración que Bigtable maneja automáticamente.

El cliente de HBase de Cloud Bigtable para Java es para los clientes que migran a Bigtable desde HBase y quieren seguir usando la API de HBase. En todos los demás casos, los desarrolladores de Java deben usar el cliente de Cloud Bigtable para Java, que llama a las APIs de Bigtable.

Familias de columnas

Cuando creas una familia de columnas, no puedes configurar el tamaño de bloque ni el método de compresión con la shell de HBase o mediante la API de HBase. Bigtable administra la compresión y el tamaño de bloque por ti.

Además, si usas la shell de HBase para obtener información sobre una tabla, siempre informará que cada familia de columnas no usa compresión. En realidad, Bigtable utiliza métodos de compresión patentados para todos sus datos.

Se ignoran los siguientes parámetros de configuración de la familia de columnas, ya que Bigtable administra el almacenamiento subyacente por ti:

  • 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

Los parámetros de configuración VERSIONS, MIN_VERSIONS y TTL se convierten en políticas de recolección de elementos no utilizados de Bigtable.

Bigtable exige que los nombres de las familias de columnas sigan la expresión regular [_a-zA-Z0-9][-_.a-zA-Z0-9]*. Si importas datos a Bigtable desde HBase, es posible que primero debas cambiar los nombres de las familias para seguir este patrón.

Filas y celdas

  • No se puede definir una LCA para una fila individual. Las vistas autorizadas de Bigtable te permiten otorgar acceso a un subconjunto de los datos de una tabla, pero no se exponen a través de la API de HBase.
  • No se puede establecer la visibilidad de las celdas individuales.
  • Las etiquetas no son compatibles. No puedes usar la clase org.apache.hadoop.hbase.Tag para agregar metadatos a celdas individuales. Las etiquetas que agregues a una celda se descartan antes de que se escriba la celda.

Mutaciones y eliminaciones

  • Las operaciones Append en Bigtable son completamente atómicas tanto para lectores como para escritores. Los lectores nunca podrán leer una operación Append que se aplica de forma parcial.
  • Las operaciones Increment son atómicas, pero no se admite establecer un intervalo de tiempo en un Increment.
  • Un objeto RowMutations que pasas a Table#mutateRow() puede contener operaciones Put y Delete, o bien operaciones Append y Increment, pero no ambas. Los objetos RowMutations que contienen operaciones Append o Increment no se admiten en batch(), checkAndMutate() ni BufferedMutator.
  • Se admite borrar una versión específica de una columna específica según su marca de tiempo. Sin embargo, no se admiten los siguientes tipos de eliminaciones:

    • Borra solo la versión más reciente de una columna
    • Borra todos los valores de una fila que tengan una marca de tiempo específica
    • Borra todos los valores de una familia de columnas en una marca de tiempo específica o antes de ella

    Como resultado, no se admiten los siguientes métodos en la clase org.apache.hadoop.hbase.client.Delete: + new Delete(byte[] row, long timestamp) + addColumn(byte[] family, byte[] qualifier) + addFamily(byte[] family, long timestamp) + addFamilyVersion(byte[] family, long timestamp)

  • En HBase, borra las operaciones put de enmascaramiento, pero Bigtable no enmascara las operaciones put después de las eliminaciones cuando se envían solicitudes put luego de las solicitudes de eliminación. Esto significa que, en Bigtable, una solicitud de escritura enviada a una celda no se ve afectada por una solicitud de eliminación que se envió antes a la misma celda.

Solicitudes y análisis

Coprocesadores

Los coprocesadores no son compatibles. No puedes crear clases que implementen la interfaz org.apache.hadoop.hbase.coprocessor.

Filtros

En la siguiente tabla, se enumeran los filtros admitidos en el paquete org.apache.hadoop.hbase.filter. No se admiten todos los demás filtros de ese paquete y arrojan una UnsupportedOperationException.

Admitido Compatible, con limitaciones
  1. En la mayoría de los casos, PrefixFilter analiza las filas de PrefixFilter. Sin embargo, si PrefixFilter es parte de un FilterList y tiene el operador MUST_PASS_ONE, Bigtable no puede determinar el rango implícito y realiza un análisis sin filtrar desde la fila de inicio hasta la última. Usa PrefixFilter con BigtableExtendedScan o una combinación de filtros para optimizar el rendimiento en este caso.
  2. Requiere una sola familia de columnas solo cuando usas un calificador de columna como el desplazamiento de columna.
  3. Admite solo con una familia de columnas.
  4. Solo admite el operador EQUAL, con el comparador BinaryComparator o el comparador RegexStringComparator.
  5. No se admite la construcción del filtro con new KeyOnlyFilter(true).
  6. No puede formar parte de un FilterList que use el operador MUST_PASS_ONE.
  7. Un PageFilter debe ser el filtro de nivel superior o el último filtro en un FilterList de nivel superior que use el operador MUST_PASS_ALL, que es el comportamiento predeterminado. No se admite un PageFilter en un FilterList que use el operador MUST_PASS_ONE.
  8. Solo admite el comparador BinaryComparator o el comparador RegexStringComparator con el operador EQUAL. Si se usa cualquier operador que no sea EQUAL, solo se admite una familia de columnas.
  9. Admite solo los siguientes comparadores:
    • BinaryComparator
    • RegexStringComparator sin marcas (se ignoran las marcas) y el operador EQUAL
  10. Depende del filtro de condición de Bigtable, que puede ser lento. Se admite, pero no se recomienda.
  11. Solo se admite un WhileMatchFilter por análisis.
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

Además, las siguientes diferencias afectan a los filtros de Bigtable:

  • Solo se admiten los comparadores BinaryComparator y RegexStringComparator. No se admiten todos los demás comparadores y arrojan una UnsupportedOperationException.
  • En los filtros que usan el comparador de expresiones regulares (org.apache.hadoop.hbase.filter.RegexStringComparator), las expresiones regulares usan la sintaxis RE2, no la sintaxis de Java.
  • No se admiten los filtros personalizados. No puedes crear clases heredadas de org.apache.hadoop.hbase.filter.Filter. Para usar un filtro de Bigtable que no tenga un equivalente en HBase, arrópalo en un com.google.cloud.bigtable.hbase.filter.BigtableFilter.
  • Existe un límite de tamaño de 20 KB para las expresiones de filtro, y los filtros no se pueden anidar en más de 20 niveles de profundidad. Como solución alternativa para reducir el tamaño de una expresión de filtro, usa una columna complementaria que almacene el valor de hash de los criterios de filtro.

Marcas de tiempo

Bigtable almacena las marcas de tiempo en microsegundos, mientras que HBase las almacena en milisegundos. Esta distinción tiene repercusiones cuando usas la biblioteca cliente de HBase para Bigtable y hay datos con marcas de tiempo invertidas.

La biblioteca cliente convierte entre microsegundos y milisegundos, pero debido a que la marca de tiempo más grande de HBase que puede almacenar Bigtable es Long.MAX_VALUE/1000, cualquier valor mayor que ese se convierte en Long.MAX_VALUE/1000. Como resultado, es posible que los valores grandes de marca de tiempo invertidas no se conviertan de manera correcta.

Administración

En esta sección, se describe cómo el cliente de Bigtable HBase para Java implementa la interfaz org.apache.hadoop.hbase.client.Admin. Debido a que Bigtable controla la mayoría de las tareas de administración de clústeres y almacenamiento de forma automática, muchos métodos administrativos de HBase no son aplicables. Cualquier método Admin que no aparezca en esta sección como compatible o que no tenga efecto no es compatible y arroja una UnsupportedOperationException.

Administración de tablas

Se admiten los siguientes métodos de Admin para administrar tablas y familias de columnas:

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

Los siguientes métodos de administración de tablas admitidos se comportan de manera diferente en Bigtable o ignoran ciertos parámetros:

  • Las tablas de Bigtable no se pueden inhabilitar. disableTable(), disableTableAsync(), disableTables(), enableTable(), enableTableAsync() y enableTables() cambian el estado de la tabla solo en la memoria del cliente (que leen isTableDisabled() y isTableEnabled()).
  • modifyTable() y modifyTableAsync() solo aplican cambios a las familias de columnas. Se ignoran los atributos a nivel de la tabla.
  • truncateTable() y truncateTableAsync() borran todos los datos de la tabla. Se ignora el parámetro preserveSplits.
  • Las sobrecargas de listTableDescriptors(), listTables() y listTableNames() que aceptan un parámetro includeSysTables ignoran includeSysTables, porque Bigtable no tiene tablas del sistema.
  • isTableAvailable(TableName tableName, byte[][] splitKeys) solo verifica si la tabla existe y, además, ignora el parámetro splitKeys.
  • getAlterStatus() siempre devuelve (0, 0) porque las modificaciones del esquema en Bigtable son síncronas.

Las tareas como la compactación y la división de tablas se controlan automáticamente. Como resultado, los siguientes métodos no tienen ningún efecto:

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

Instantáneas

Los métodos de instantáneas de HBase crean y administran copias de seguridad de Bigtable. Debido a que las copias de seguridad se almacenan en un clúster específico, si tu instancia tiene más de un clúster, debes establecer la propiedad de configuración google.bigtable.snapshot.cluster.id en el clúster que se usará. Las copias de seguridad que creas con snapshot() vencen después de la cantidad de segundos en la propiedad de configuración google.bigtable.snapshot.default.ttl.secs (24 horas de forma predeterminada). cloneSnapshot() restablece desde una copia de seguridad a una tabla nueva.

Los siguientes métodos de instantáneas son compatibles con 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)

Además, AsyncAdmin admite listSnapshots(), listSnapshots(Pattern pattern) y snapshot(SnapshotDescription snapshot). No se admiten todos los demás métodos de instantánea, incluidos restoreSnapshot(), deleteSnapshots(), deleteTableSnapshots(), listTableSnapshots() y cloneSnapshot(String snapshotName, TableName tableName, boolean restoreAcl), y arrojan un UnsupportedOperationException.

Administración de regiones

Bigtable usa tablets, que son similares a las regiones. Se admiten los siguientes métodos para recuperar información de la región, con diferencias con respecto a HBase estándar:

  • getRegions(TableName tableName) y getTableRegions(TableName tableName), así como los métodos de la interfaz org.apache.hadoop.hbase.client.RegionLocator, devuelven límites aproximados basados en una muestra de claves de fila de la tabla. Los nombres de los servidores en las regiones que se muestran no son servidores reales.
  • getRegionMetrics(ServerName serverName, TableName tableName) ignora el parámetro serverName y devuelve métricas aproximadas del tamaño de la región en función de una muestra de claves de fila de la tabla.

Debido a que Bigtable administra tus tablets automáticamente, los siguientes métodos no tienen efecto:

  • 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)

En HBase 1.x, compactRegionServer(ServerName sn, boolean major), mergeRegions(byte[] encodedNameOfRegionA, byte[] encodedNameOfRegionB, boolean forcible), move(byte[] encodedRegionName, byte[] destServerName) y unassign(byte[] regionName, boolean force) tampoco tienen efecto. Sus equivalentes de HBase 2.x no son compatibles y arrojan una UnsupportedOperationException.

Estado y conexión del clúster

Bigtable controla las tareas de mantenimiento del clúster de forma automática, por lo que los métodos de mantenimiento en Admin arrojan una UnsupportedOperationException. Solo se admiten los siguientes métodos de conexión y estado:

  • close() no tiene ningún efecto.
  • getClusterMetrics(), getClusterMetrics(EnumSet<Option> options) y getClusterStatus() devuelven valores de marcador de posición con listas de servidores vacías, y getClusterMetrics(EnumSet<Option> options) ignora el parámetro options.
  • getConfiguration() devuelve el objeto Configuration del cliente.
  • getConnection() devuelve el objeto Connection del cliente.

Espacios de nombres

Bigtable no usa espacios de nombres. Puedes usar los prefijos de clave de fila para simular los espacios de nombres.

De forma predeterminada, todos los métodos de espacio de nombres arrojan un UnsupportedOperationException. Sin embargo, si estableces la propiedad de configuración google.bigtable.namespace.warnings en true, los siguientes métodos registran una advertencia y no tienen efecto (devuelven null o un resultado vacío) en lugar de arrojar una excepción:

  • 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)

Incluso cuando google.bigtable.namespace.warnings se establece en true, listNamespaces() arroja un UnsupportedOperationException.

Otras funciones administrativas

Bigtable no admite métodos Admin en las siguientes categorías, y llamarlos arroja un UnsupportedOperationException:

  • Grupos de localidad: Bigtable no te permite especificar grupos de localidad para las familias de columnas.
  • Coprocesadores y procedimientos distribuidos: Bigtable no admite coprocesadores ni procedimientos distribuidos.
  • Cuotas: Para obtener información sobre las cuotas de Bigtable, consulta Cuotas y límites.
  • Replicación: Bigtable replica los datos automáticamente entre los clústeres de una instancia. Para obtener más información, consulta Descripción general de la replicación. Para replicar de HBase a Bigtable, consulta Replica de HBase a Bigtable.
  • Control de acceso: Bigtable usa IAM para el control de acceso.
  • Grupos de RegionServer: Bigtable administra los servidores de forma automática y no expone los grupos de RegionServer.