HBase 版本介紹

在 HBase 中,一個{row,column,version}元組精確指定了一個 cell。可能有無限數量的單元格,其中行和列是相同的,但單元格地址僅在其版本維度上有所不同。

雖然行和列鍵以字節表示,但版本是使用長整數指定的。通常,這個long包含時間實例,如由java.util.Date.getTime() 或者 System.currentTimeMillis() 返回的時間實例,即:1970年1月1日UTC的當前時間和午夜之間的差值(以毫秒為單位)。

HBase 版本維度按遞減順序存儲,因此從存儲文件讀取時,會先查找最新的值。

在 HBase 中,cell 版本的語義有很多混淆。尤其是:

  • 如果對一個單元的多次寫入具有相同的版本,則只有最後一次寫入是可以讀取的。
  • 以非遞增版本順序編寫單元格是可以的。

下面我們描述 HBase 當前的版本維度是如何工作的。HBase 中的彎曲時間使得 HBase 中的版本或時間維度得到很好的閱讀。它在版本控制方面的細節比這裡提供的更多。

在撰寫本文時,文章中提到的限制覆蓋現有時間戳的值不再適用於HBase。本節基本上是 Bruno Dumon 撰寫的文章的簡介。

指定要存儲的HBase版本數量

為給定列存儲的最大版本數是列架構的一部分,並在創建表時通過 alter 命令 HColumnDescriptor.DEFAULT_VERSIONS 指定 。在 HBase 0.96 之前,保留的版本的默認數量是3,但在 0.96 以及新版本中已更改為1。

示例 - 修改一個列族的最大版本數量

本示例使用HBase Shell來保留列族中所有列的最多5個版本f1。你也可以使用HColumnDescriptor。

HBase 版本介紹

示例 - 修改列族的最小版本數

您還可以指定每列家族存儲的最低版本數。默認情況下,它被設置為0,這意味著該功能被禁用。下面的示例通過 HBase Shell 將在列族 f1 中的所有列的最小版本數設置為2。你也可以使用 HColumnDescriptor。


HBase 版本介紹

從 HBase 0.98.2 開始,您可以通過在 hbase-site.xml 中設置 hbase.column.max.version 為所有新創建列保留的最大版本數指定一個全局默認值。

版本和 HBase 操作

在下面的內容中,我們將瞭解每個核心 HBase 操作的版本維度的行為。

獲取/掃描(Get/Scan)

獲取在 Scans 之上實現。以下關於 Get 的討論同樣適用於 Scans。

默認情況下,即如果你沒有指定明確的版本,則在執行“get”操作時,會返回其版本值最大的單元格(可能是也可能不是最新版本,請參閱後面的內容)。默認行為可以通過以下方式進行修改:

  • 要返回多個版本,請參閱 Get.setMaxVersions()
  • 要返回除最新版本以外的其他版本,請參閱 Get.setTimeRange(),要檢索小於或等於給定值的最新版本,從而在某個時間點給出記錄的“最新”狀態,只需使用從0到所需版本的範圍,並將最大版本設置為1 。

默認獲取示例

以下獲取將只檢索行的當前版本:


HBase 版本介紹

版本化獲取示例

以下 Get 將返回該行的最後3個版本。


HBase 版本介紹

Put(寫)

在某個時間戳處進行Put(寫)操作總是會創建一個新版本的 cell。默認情況下,系統使用服務器的 currentTimeMillis,但您可以在每列級別上自己指定版本(等於長整數)。這意味著您可以分配過去或未來的時間,或將長時間值用於非時間目的。

要覆蓋現有值,請執行與要覆蓋的單元格中的行、列和版本完全相同的 put。

隱式版本示例:

HBase 會在當前時間隱式地對以下 Put 進行版本管理。


HBase 版本介紹

顯示版本示例:

以下 Put 具有明確設置的版本時間戳。


HBase 版本介紹

注意:版本時間戳由 HBase 內部使用,用於諸如生存時間計算之類的事情。通常最好避免自己設置時間戳。優先使用該行的單獨時間戳屬性,或者將時間戳記作為行鍵的一部分,或者同時使用兩者。

刪除(delete)

有三種不同類型的內部刪除標記。並添加另一個掃描 HBase:Prefix Delete Marker。

  • 刪除(Delete):針對特定版本的列。
  • 刪除列(Delete column):適用於所有版本的列。
  • 刪除系列(Delete family):針對特定 ColumnFamily 的所有列

當刪除整行時,HBase 將在內部為每個 ColumnFamily(即不是每個單獨的列)創建一個邏輯刪除。

通過創建 tombstone 標記來刪除作品。例如,假設我們想要刪除一行。為此,您可以指定一個版本,或者默認情況下使用該 currentTimeMillis。這意味著刪除版本小於或等於此版本的所有單元格。HBase 從不修改數據,例如刪除不會立即刪除(或標記為已刪除)存儲文件中對應於刪除條件的條目。相反,所謂的 tombstone 被寫入,這將掩蓋已刪除的值。當 HBase 進行重大壓縮時,tombstone 將被處理以實際移除不能用的值以及 tombstone 本身。如果您在刪除行時指定的版本大於行中任何值的版本,則可以考慮刪除整行。

除非在列族中設置了 KEEP_DELETED_CELLS 選項,否則刪除標記在存儲區的下一個主要壓縮過程中被清除。如果要將刪除保留為可配置的時間量,可以通過hbase-site.xml 中的 hbase.hstore.time.to.purge.deletes 屬性設置刪除 TTL 。如果 hbase.hstore.time.to.purge.deletes 未設置或設置為 0,則將在下一次主要壓縮過程中清除所有刪除標記,包括將來使用時間戳的標記。否則,將保留在將來具有時間戳的刪除標記,直到在由標記時間戳表示的時間加上hbase.hstore.time.to.purge.deletes 的值(以毫秒為單位)之後發生的主要壓縮為止。

HBase-2.0.0中的可選新版本和刪除行為

在 hbase-2.0.0 中,操作員可以通過將列描述符屬性 NEW_VERSION_BEHAVIOR 設置為 true 來指定備用版本和刪除處理(若要在列族描述符上設置屬性,您必須首先禁用表,然後改變列族描述符)。

“新版本行為”解除了以下列出的侷限性,取消了以下所列的限制,即如果在同一位置,Delete 總是會超過一個Put(即相同的行,列族,限定符和時間戳),而不管哪一個先到達。版本記帳也會因為刪除版本考慮到版本總數而發生變化。這是為了確保在重大壓縮情況下不會改變結果。

運行這個新配置目前的成本;我們將每個比較的 Cell MVCC 因素考慮在內,因此我們消耗更多的 CPU,這是減速所取決於的,在測試中,我們已經看到0%到25%的降級。

如果正在複製,建議您使用新的串行復制功能運行,因為現在突變到達的順序是因子。

HBase目前的侷限性

以下限制在 hbase-2.0.0 中解決。請參閱上面的“HBase-2.0.0 中的可選新版本和刪除行為”部分。

刪除標記Put

刪除掩碼放入,甚至在輸入刪除後發生。請記住,刪除操作會寫入邏輯刪除,只有在下一次主要壓縮運行後才會消失。假設你刪除了所有的⇐ T 的內容,然後你做了一個帶有時間戳 ⇐ T 的新放。這種情況下,即使在刪除後發生,也會被刪除 tombstone 屏蔽。執行投入不會失敗,但是當你做出投注時,你會注意到投注沒有任何效果。重大壓縮後,它將再次開始工作。如果您使用不斷增加的版本進行新的放置,則這些問題不應該是一個問題。但即使您不在乎時間,也可能發生這種情況:只需刪除並立即放置在對方之後,並且有可能在同一毫秒內發生。

主要的壓縮改變了查詢結果

在 t1,t2 和 t3 中創建三個單元格版本,最大版本設置為 2。因此,獲取所有版本時,只會返回 t2 和 t3 的值。但是如果在 t2 或 t3 刪除版本,則 t1 中的版本將再次出現。顯然,一旦主要的壓實運行後,這種行為將不會是這樣了。


分享到:


相關文章: