HBase 和 Bigtable 的差異

存取 Bigtable 的其中一種方式,是使用自訂版本的 Apache HBase Java 用戶端。一般而言,自訂用戶端會公開相同的 API 做為 HBase 的標準安裝。本頁說明 Java 適用的 Cloud BigTable HBase 用戶端與標準 HBase 安裝之間的差異,其中許多差異與 Bigtable 自動處理的管理工作有關。

Cloud Bigtable HBase Java 用戶端適用於從 HBase 遷移至 Bigtable,且想繼續使用 HBase API 的客戶。在所有其他情況下,Java 開發人員應改用 Java 專用 Cloud Bigtable 用戶端,呼叫 Bigtable API。

資料欄系列

建立資料欄系列時,您無法使用 HBase 殼層或 HBase API 設定區塊大小或壓縮方法。Bigtable 會為您管理區塊大小和壓縮。

此外,如果您使用 HBase 殼層取得資料表相關資訊,HBase 殼層一律會回報每個資料欄系列均未使用壓縮。實際上,Bigtable 會使用專屬壓縮方法處理所有資料。

Bigtable 會為您管理基礎儲存空間,因此系統會忽略下列資料欄系列設定:

  • 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

VERSIONS、MIN_VERSIONS 和 TTL 設定會轉換為 Bigtable 垃圾收集政策。

Bigtable 規定資料欄系列名稱必須符合規則運算式 [_a-zA-Z0-9][-_.a-zA-Z0-9]*。如果您要從 HBase 將資料匯入 Bigtable,可能需要先變更系列名稱,以符合這個模式。

資料列與儲存格

  • 您無法為個別資料列定義 ACL。Bigtable 授權檢視表可讓您授予資料表部分資料的存取權,但不會透過 HBase API 公開。
  • 您無法設置單一儲存格的瀏覽權限。
  • 不支援標記。您無法使用 org.apache.hadoop.hbase.Tag 類別將中繼資料新增至個別儲存格。寫入儲存格之前,系統會捨棄您新增至儲存格的所有標記。

變異和刪除操作

  • 在 Bigtable 中,Append 作業對讀取者和寫入者來說都是完全不可分割的。讀取器永遠無法讀取部分套用的 Append 作業。
  • Increment 作業是不可分割的,但 Increment 不支援設定時間範圍。
  • 傳遞至 Table#mutateRow() 的 RowMutations 物件可包含 Put 和 Delete 作業,或 Append 和 Increment 作業,但不能同時包含兩者。batch()、checkAndMutate() 或 BufferedMutator 不支援包含 Append 或 Increment 作業的 RowMutations 物件。
  • 您可以根據時間戳記刪除特定資料欄的特定版本。不過,系統不支援下列刪除類型:

    • 僅刪除資料欄的最新版本
    • 刪除資料列中具有特定時間戳記的所有值
    • 刪除資料欄系列中,特定時間戳記或之前的全部值

    因此,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)

  • 在 HBase 中,刪除作業會遮蓋放置作業,但如果放置要求是在刪除要求之後傳送,Bigtable 不會在刪除作業後遮蓋放置作業 。也就是說,在 Bigtable 中,傳送至儲存格的寫入要求不會受到先前傳送至相同儲存格的刪除要求影響。

獲取及掃描

輔助處理器

不支援輔助處理器。您無法建立實作 org.apache.hadoop.hbase.coprocessor 介面的類別。

篩選器

下表列出 org.apache.hadoop.hbase.filter 套件支援的篩選器。該套件中的所有其他篩選器都不支援,且會擲回 UnsupportedOperationException。

支援 有限地支援
  1. 在大多數情況下,PrefixFilter 會掃描 PrefixFilter 中的資料列。不過,如果 PrefixFilter 是 FilterList 的一部分,且具有運算子 MUST_PASS_ONE,Bigtable 就無法判斷隱含範圍,而是會從起始資料列到停止資料列執行未篩選的掃描。在這種情況下,請使用 PrefixFilter 搭配 BigtableExtendedScan 或篩選器組合,以達到最佳效能。
  2. 只有在使用資料欄限定詞做為資料欄偏移量時,才需要單一資料欄系列。
  3. 僅支援單一資料欄系列。
  4. 僅支援 EQUAL 運算子,以及 BinaryComparator 比較子或 RegexStringComparator 比較子。
  5. 不支援使用 new KeyOnlyFilter(true) 建構篩選器。
  6. 不得屬於使用 MUST_PASS_ONE 運算子的 FilterList。
  7. PageFilter 必須是頂層篩選器,或使用 MUST_PASS_ALL 運算子的頂層 FilterList 中的最後一個篩選器,這是預設行為。不支援在 FilterList 中使用 MUST_PASS_ONE 運算子的 PageFilter。
  8. 僅支援 BinaryComparator 比較運算子,或搭配 EQUAL 運算子的 RegexStringComparator 比較運算子。如果使用 EQUAL 以外的任何運算子,則僅支援單一資料欄系列。
  9. 僅支援下列比較運算子:
    • BinaryComparator
    • RegexStringComparator 不含旗標 (忽略旗標) 和 EQUAL 運算子
  10. 必須使用 Bigtable 條件篩選器,速度可能較慢。支援但不建議使用。
  11. 每次掃描僅支援一個 WhileMatchFilter。
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

此外,下列差異會影響 Bigtable 篩選器:

  • 僅支援比較運算子 BinaryComparator 和 RegexStringComparator。系統不支援所有其他比較運算子,並會擲回 UnsupportedOperationException。
  • 在採用規則運算式比較運算子 (org.apache.hadoop.hbase.filter.RegexStringComparator) 的篩選器中,規則運算式會使用 RE2 語法,而非 Java 語法。
  • 不支援自訂篩選器。您無法建立繼承自 org.apache.hadoop.hbase.filter.Filter 的類別。如要使用沒有 HBase 對等項目的 Bigtable 篩選器,請將其包裝在 com.google.cloud.bigtable.hbase.filter.BigtableFilter 中。
  • 篩選運算式的大小上限為 20 KB,且篩選器巢狀結構不得超過 20 層。如要縮減篩選運算式的大小,可以採用替代方案,使用儲存篩選條件雜湊值的補充資料欄。

時間戳記

Bigtable 會以微秒為單位儲存時間戳記,而 HBase 則是以毫秒為單位。當您使用 Bigtable 的 HBase 用戶端程式庫,且資料的時間戳記反轉時,這項差異就會產生影響。

用戶端程式庫會在微秒和毫秒之間轉換,但由於 Bigtable 可儲存的最大 HBase 時間戳記為 Long.MAX_VALUE/1000,因此任何大於該值的值都會轉換為 Long.MAX_VALUE/1000。因此,較大的反向時間戳記值可能無法正確轉換。

管理

本節說明 Java 適用的 Bigtable HBase 用戶端如何實作 org.apache.hadoop.hbase.client.Admin 介面。由於 Bigtable 會自動處理大部分的叢集和儲存空間管理工作,因此許多 HBase 管理方法並不適用。如果 Admin 方法未在本節中列為支援或無效,則不受支援,並會擲回 UnsupportedOperationException。

資料表管理

系統支援下列用於管理資料表和資料欄系列的 Admin 方法:

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

下列支援的資料表管理方法在 Bigtable 上的行為不同,或會忽略特定參數:

  • Bigtable 資料表無法停用。disableTable()、disableTableAsync()、disableTables()、enableTable()、enableTableAsync() 和 enableTables() 只會變更用戶端記憶體中的資料表狀態 (isTableDisabled() 和 isTableEnabled() 會讀取該狀態)。
  • modifyTable() 和 modifyTableAsync() 只會對資料欄系列套用變更。系統會忽略資料表層級屬性。
  • truncateTable() 和 truncateTableAsync() 會刪除資料表中的所有資料。系統會忽略 preserveSplits 參數。
  • 接受 includeSysTables 參數的 listTableDescriptors()、listTables() 和 listTableNames() 超載會忽略 includeSysTables,因為 Bigtable 沒有系統資料表。
  • isTableAvailable(TableName tableName, byte[][] splitKeys) 只會檢查資料表是否存在,並忽略 splitKeys 參數。
  • getAlterStatus() 一律會傳回 (0, 0),因為 Bigtable 中的結構定義修改作業是同步進行。

系統會自動處理資料表壓縮和分割等工作。因此,下列方法不會生效:

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

快照

HBase 快照方法會建立及管理 Bigtable 備份。由於備份會儲存在特定叢集,如果執行個體有多個叢集,您必須將設定屬性 google.bigtable.snapshot.cluster.id 設為要使用的叢集。使用 snapshot() 建立的備份,會在設定屬性 google.bigtable.snapshot.default.ttl.secs 中的秒數 (預設為 24 小時) 後過期。cloneSnapshot() 會將備份還原至新資料表。

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)

此外,AsyncAdmin 支援 listSnapshots()、listSnapshots(Pattern pattern) 和 snapshot(SnapshotDescription snapshot)。不支援所有其他快照方法,包括 restoreSnapshot()、deleteSnapshots()、deleteTableSnapshots()、listTableSnapshots() 和 cloneSnapshot(String snapshotName, TableName tableName, boolean restoreAcl),並會擲回 UnsupportedOperationException。

地區管理

Bigtable 使用子表,類似於區域。系統支援下列擷取區域資訊的方法,與標準 HBase 的差異如下:

  • getRegions(TableName tableName) 和 getTableRegions(TableName tableName),以及介面 org.apache.hadoop.hbase.client.RegionLocator 中的方法,會根據資料表中的資料列索引鍵樣本傳回近似邊界。傳回區域中的伺服器名稱並非實際伺服器。
  • getRegionMetrics(ServerName serverName, TableName tableName) 會忽略 serverName 參數,並根據資料表中的資料列索引鍵樣本,傳回近似的區域大小指標。

由於 Bigtable 會自動管理 tablet,因此下列方法不會生效:

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

在 HBase 1.x 中,compactRegionServer(ServerName sn, boolean major)、mergeRegions(byte[] encodedNameOfRegionA, byte[] encodedNameOfRegionB, boolean forcible)、move(byte[] encodedRegionName, byte[] destServerName) 和 unassign(byte[] regionName, boolean force) 也沒有任何作用。系統不支援 HBase 2.x 的對等項目,並會擲回 UnsupportedOperationException。

叢集狀態和連線

Bigtable 會自動處理叢集維護工作,因此 Admin 中的維護方法會擲回 UnsupportedOperationException。僅支援下列連線和狀態方法:

  • close() 沒有作用。
  • getClusterMetrics()、getClusterMetrics(EnumSet<Option> options) 和 getClusterStatus() 會傳回預留位置值,伺服器清單則為空白,且 getClusterMetrics(EnumSet<Option> options) 會忽略 options 參數。
  • getConfiguration() 會傳回用戶端 Configuration 物件。
  • getConnection() 會傳回用戶端 Connection 物件。

命名空間

Bigtable 不會使用命名空間。您可以使用資料列索引鍵前置字元模擬命名空間。

根據預設,所有命名空間方法都會擲回 UnsupportedOperationException。不過,如果將設定屬性 google.bigtable.namespace.warnings 設為 true,下列方法會記錄警告,且不會生效 (傳回 null 或空白結果),而非擲回例外狀況:

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

即使 google.bigtable.namespace.warnings 設為 true,listNamespaces() 也會擲回 UnsupportedOperationException。

其他管理功能

Bigtable 不支援下列類別中的 Admin 方法,呼叫這些方法會擲回 UnsupportedOperationException:

  • 位置群組:Bigtable 不允許您為資料欄系列指定位置群組。
  • 協同處理器和分散式程序:Bigtable 不支援協同處理器或分散式程序。
  • 配額:如要瞭解 Bigtable 配額,請參閱「配額與限制」。
  • 複製:Bigtable 會自動在執行個體中的叢集之間複製資料。詳情請參閱「複製總覽」。如要從 HBase 複製到 Bigtable,請參閱「從 HBase 複製到 Bigtable」。
  • 存取控管:Bigtable 使用 IAM 控管存取權。
  • RegionServer 群組:Bigtable 會自動管理伺服器,不會公開 RegionServer 群組。