Differences between HBase and Bigtable
One way to access Bigtable is to use a customized version of the Apache HBase client for Java. In general, the customized client exposes the same API as a standard installation of HBase. This page describes the differences between the Cloud Bigtable HBase client for Java and a standard HBase installation. Many of these difference are related to management tasks that Bigtable handles automatically.
The Cloud Bigtable HBase client for Java is for customers who are migrating to Bigtable from HBase and want to continue using the HBase API. In all other cases, Java developers should instead use the Cloud Bigtable client for Java, which calls the Bigtable APIs.
Column families
When you create a column family, you cannot configure the block size or compression method, either with the HBase shell or through the HBase API. Bigtable manages the block size and compression for you.
In addition, if you use the HBase shell to get information about a table, the HBase shell will always report that each column family does not use compression. In reality, Bigtable uses proprietary compression methods for all of your data.
The following column family settings are ignored, because Bigtable manages the underlying storage for you:
BLOCKCACHEBLOCKSIZEBLOOMFILTERCACHE_BLOOMS_ON_WRITECACHE_DATA_IN_L1CACHE_DATA_ON_WRITECACHE_INDEX_ON_WRITECOMPRESS_TAGSCOMPRESSIONCOMPRESSION_COMPACTDATA_BLOCK_ENCODINGEVICT_BLOCKS_ON_CLOSEIN_MEMORYKEEP_DELETED_CELLSPREFETCH_BLOCKS_ON_OPENREPLICATION_SCOPE
The settings VERSIONS, MIN_VERSIONS, and TTL are converted to
Bigtable garbage collection
policies.
Bigtable requires that column family names follow the regular
expression [_a-zA-Z0-9][-_.a-zA-Z0-9]*. If you are importing
data into Bigtable from HBase, you might need to first change the
family names to follow this pattern.
Rows and cells
- You cannot define an ACL for an individual row. Bigtable authorized views let you grant access to a subset of a table's data, but they aren't exposed through the HBase API.
- You cannot set the visibility of individual cells.
- Tags are not supported. You cannot use the class
org.apache.hadoop.hbase.Tagto add metadata to individual cells. Any tags that you add to a cell are dropped before the cell is written.
Mutations and deletions
Appendoperations in Bigtable are fully atomic for both readers and writers. Readers will never be able to read a partially appliedAppendoperation.Incrementoperations are atomic, but setting a time range on anIncrementis not supported.- A
RowMutationsobject that you pass toTable#mutateRow()can contain eitherPutandDeleteoperations orAppendandIncrementoperations, but not both.RowMutationsobjects that containAppendorIncrementoperations aren't supported inbatch(),checkAndMutate(), orBufferedMutator. Deleting a specific version of a specific column based on its timestamp is supported. However, the following types of deletions are not supported:
- Deleting only the latest version of a column
- Deleting all values in a row that have a specific timestamp
- Deleting all values in a column family at or before a specific timestamp
As a result, the following methods in the class
org.apache.hadoop.hbase.client.Deleteare not supported: +new Delete(byte[] row, long timestamp)+addColumn(byte[] family, byte[] qualifier)+addFamily(byte[] family, long timestamp)+addFamilyVersion(byte[] family, long timestamp)In HBase, deletes mask puts, but Bigtable does not mask puts after deletes when put requests are sent after deletion requests. This means that in Bigtable, a write request sent to a cell is not affected by a previously sent delete request to the same cell.
Gets and scans
- Reverse scans let you read a range of rows backwards. For details, see Reverse scans.
- Unlike HBase, when you send a read request, Bigtable doesn't automatically filter out expired data that is marked for deletion in an upcoming garbage collection cycle. To avoid reading expired data, use a filter in the read request. For more information, see the Garbage collection overview.
- Limiting the number of values per row per column family is not supported. You
cannot call the method
org.apache.hadoop.hbase.client.Scan#setMaxResultsPerColumnFamily(int limit). - Partial results aren't supported. Rows are always returned whole. Calls to
the methods
org.apache.hadoop.hbase.client.Scan#setBatch(int batch)andorg.apache.hadoop.hbase.client.Scan#setAllowPartialResults(boolean allowPartialResults)are ignored. - On a synchronous
Table#getScanner(Scan)call,org.apache.hadoop.hbase.client.Scan#setCaching(int caching)controls how many rows the client fetches at a time.AsyncTable#getScanner()ignoressetCaching(). Calls to the methodorg.apache.hadoop.hbase.client.Scan#setMaxResultSize(long maxResultSize)are always ignored.
Coprocessors
Coprocessors are not supported. You cannot create classes that implement the
interface
org.apache.hadoop.hbase.coprocessor.
Filters
The following table lists the supported filters in the package
org.apache.hadoop.hbase.filter. All other filters
in that package aren't supported and throw an UnsupportedOperationException.
| Supported | Supported, with limitations |
|---|---|
|
|
ColumnCountGetFilterColumnPrefixFilterFilterListFirstKeyOnlyFilterFuzzyRowFilterMultipleColumnPrefixFilterPrefixFilter 1RandomRowFilterTimestampsFilter
|
ColumnPaginationFilter 2ColumnRangeFilter 3FamilyFilter 4KeyOnlyFilter 5MultiRowRangeFilter 6PageFilter 7QualifierFilter 8RowFilter 4SingleColumnValueExcludeFilter 3, 9, 10SingleColumnValueFilter 9, 10ValueFilter 9WhileMatchFilter 6, 11
|
In addition, the following differences affect Bigtable filters:
- Only the comparators
BinaryComparatorandRegexStringComparatorare supported. All other comparators aren't supported and throw anUnsupportedOperationException. - In filters that use the regular expression comparator
(
org.apache.hadoop.hbase.filter.RegexStringComparator), regular expressions use RE2 syntax, not Java syntax. - Custom filters are not supported. You cannot create classes that inherit from
org.apache.hadoop.hbase.filter.Filter. To use a Bigtable filter that has no HBase equivalent, wrap it in acom.google.cloud.bigtable.hbase.filter.BigtableFilter. - There is a size limit of 20 KB on filter expressions, and filters can't be nested more than 20 levels deep. As a workaround to reduce the size of a filter expression, use a supplementary column that stores the hash value of the filter criteria.
Timestamps
Bigtable stores timestamps in microseconds, while HBase stores timestamps in milliseconds. This distinction has implications when you use the HBase client library for Bigtable and you have data with reversed timestamps.
The client library converts between microseconds and milliseconds, but because that the largest HBase timestamp that Bigtable can store is Long.MAX_VALUE/1000, any value larger than that is converted to Long.MAX_VALUE/1000. As a result, large reversed timestamp values might not convert correctly.
Administration
This section describes how the Bigtable HBase client for Java
implements the org.apache.hadoop.hbase.client.Admin
interface. Because Bigtable handles most cluster and storage
management tasks automatically, many HBase administrative methods aren't
applicable. Any Admin method that isn't listed in this section as supported
or as having no effect isn't supported and throws an
UnsupportedOperationException.
Table management
The following Admin methods for managing tables and column families are
supported:
addColumnFamily(TableName tableName, ColumnFamilyDescriptor columnFamily)andaddColumnFamilyAsync(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), andcreateTableAsync(TableDescriptor desc, byte[][] splitKeys)deleteColumnFamily(TableName tableName, byte[] columnName)anddeleteColumnFamilyAsync(TableName tableName, byte[] columnName)(HBase 1.x:deleteColumn(TableName tableName, byte[] columnName))deleteTable(TableName tableName),deleteTableAsync(TableName tableName),deleteTables(Pattern pattern), anddeleteTables(String regex)disableTable(TableName tableName),disableTableAsync(TableName tableName),disableTables(Pattern pattern), anddisableTables(String regex)enableTable(TableName tableName),enableTableAsync(TableName tableName),enableTables(Pattern pattern), andenableTables(String regex)getAlterStatus(TableName tableName)andgetAlterStatus(byte[] tableName)getDescriptor(TableName tableName),getTableDescriptor(TableName tableName),getTableDescriptors(List<String> names), andgetTableDescriptorsByTableName(List<TableName> tableNames)isTableAvailable(TableName tableName)andisTableAvailable(TableName tableName, byte[][] splitKeys)isTableDisabled(TableName tableName)andisTableEnabled(TableName tableName)listTableDescriptors(),listTableDescriptors(List<TableName> tableNames),listTableDescriptors(Pattern pattern), andlistTableDescriptors(Pattern pattern, boolean includeSysTables)(HBase 1.x:listTables(),listTables(Pattern pattern),listTables(Pattern pattern, boolean includeSysTables),listTables(String regex), andlistTables(String regex, boolean includeSysTables))listTableNames(),listTableNames(Pattern pattern),listTableNames(Pattern pattern, boolean includeSysTables),listTableNames(String regex), andlistTableNames(String regex, boolean includeSysTables)modifyColumnFamily(TableName tableName, ColumnFamilyDescriptor columnFamily)andmodifyColumnFamilyAsync(TableName tableName, ColumnFamilyDescriptor columnFamily)(HBase 1.x:modifyColumn(TableName tableName, HColumnDescriptor column))modifyTable(TableDescriptor td),modifyTable(TableName tableName, TableDescriptor td),modifyTableAsync(TableDescriptor td), andmodifyTableAsync(TableName tableName, TableDescriptor td)tableExists(TableName tableName)truncateTable(TableName tableName, boolean preserveSplits)andtruncateTableAsync(TableName tableName, boolean preserveSplits)
The following supported table management methods behave differently on Bigtable or ignore certain parameters:
- Bigtable tables can't be disabled.
disableTable(),disableTableAsync(),disableTables(),enableTable(),enableTableAsync(), andenableTables()change the state of the table only in the client's memory (whichisTableDisabled()andisTableEnabled()read). modifyTable()andmodifyTableAsync()apply only changes to column families. Table-level attributes are ignored.truncateTable()andtruncateTableAsync()delete all of the data in the table. ThepreserveSplitsparameter is ignored.listTableDescriptors(),listTables(), andlistTableNames()overloads that accept anincludeSysTablesparameter ignoreincludeSysTables, because Bigtable doesn't have system tables.isTableAvailable(TableName tableName, byte[][] splitKeys)checks only whether the table exists and ignores thesplitKeysparameter.getAlterStatus()always returns(0, 0)because schema modifications in Bigtable are synchronous.
Tasks such as table compaction and splitting are handled automatically. As a result, the following methods have no effect:
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
HBase snapshot methods create and manage Bigtable
backups. Because backups are stored in a specific
cluster, if your instance has more than one cluster, you must set the
configuration property google.bigtable.snapshot.cluster.id to the cluster to
use. Backups that you create with snapshot() expire after the number of
seconds in the configuration property
google.bigtable.snapshot.default.ttl.secs (24 hours by default).
cloneSnapshot() restores from a backup to a new table.
The following snapshot methods are supported in 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)
In addition, AsyncAdmin supports listSnapshots(), listSnapshots(Pattern
pattern), and snapshot(SnapshotDescription snapshot). All other snapshot
methods—including restoreSnapshot(), deleteSnapshots(),
deleteTableSnapshots(), listTableSnapshots(), and cloneSnapshot(String
snapshotName, TableName tableName, boolean restoreAcl)—aren't supported and
throw an UnsupportedOperationException.
Region management
Bigtable uses tablets, which are similar to regions. The following methods for retrieving region information are supported, with differences from standard HBase:
getRegions(TableName tableName)andgetTableRegions(TableName tableName), as well as the methods in the interfaceorg.apache.hadoop.hbase.client.RegionLocator, return approximate boundaries based on a sample of row keys in the table. The server names in the returned regions aren't real servers.getRegionMetrics(ServerName serverName, TableName tableName)ignores theserverNameparameter and returns approximate region size metrics based on a sample of row keys in the table.
Because Bigtable manages your tablets automatically, the following methods have no effect:
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)
In HBase 1.x, compactRegionServer(ServerName sn, boolean major),
mergeRegions(byte[] encodedNameOfRegionA, byte[] encodedNameOfRegionB, boolean
forcible), move(byte[] encodedRegionName, byte[] destServerName), and
unassign(byte[] regionName, boolean force) also have no effect. Their HBase
2.x equivalents aren't supported and throw an UnsupportedOperationException.
Cluster status and connection
Bigtable handles cluster maintenance tasks automatically, so
maintenance methods in Admin throw an UnsupportedOperationException. Only
the following connection and status methods are supported:
close()has no effect.getClusterMetrics(),getClusterMetrics(EnumSet<Option> options), andgetClusterStatus()return placeholder values with empty server lists, andgetClusterMetrics(EnumSet<Option> options)ignores theoptionsparameter.getConfiguration()returns the clientConfigurationobject.getConnection()returns the clientConnectionobject.
Namespaces
Bigtable does not use namespaces. You can use row key prefixes to simulate namespaces.
By default, all namespace methods throw an UnsupportedOperationException.
However, if you set the configuration property
google.bigtable.namespace.warnings to true, the following methods log a
warning and have no effect (returning null or an empty result) instead of
throwing an exception:
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)
Even when google.bigtable.namespace.warnings is set to true,
listNamespaces() throws an UnsupportedOperationException.
Other administrative features
Bigtable doesn't support Admin methods in the following
categories, and calling them throws an UnsupportedOperationException:
- Locality groups: Bigtable doesn't let you specify locality groups for column families.
- Coprocessors and distributed procedures: Bigtable doesn't support coprocessors or distributed procedures.
- Quotas: To learn about Bigtable quotas, see Quotas and limits.
- Replication: Bigtable replicates data automatically between the clusters in an instance. For details, see Replication overview. To replicate from HBase to Bigtable, see Replicate from HBase to Bigtable.
- Access control: Bigtable uses IAM for access control.
- RegionServer groups: Bigtable manages servers automatically and doesn't expose RegionServer groups.