HBase 事務性 (Transaction)

What is Transaction

先摘錄一段Wiki關於Transaction(事務)的釋義:

A transaction comprises a unit of work performed within a database management system (or similar system) against a database, and treated in a coherent and reliable way independent of other transactions. Transactions in a database environment have two main purposes:
1. To provide reliable units of work that allow correct recovery from failures and keep a database consistent even in cases of system failure, when execution stops (completely or partially) and many operations upon a database remain uncompleted, with unclear status.

2. To provide isolation between programs accessing a database concurrently. If this isolation is not provided, the program's outcome are possibly erroneous.
A database transaction, by definition, must be atomic, consistent, isolated and durable. Database practitioners often refer to these properties of database transactions using the acronym ACID.
Transactions provide an "all-or-nothing" proposition, stating that each work-unit performed in a database must either complete in its entirety or have no effect whatsoever. Further, the system must isolate each transaction from other transactions, results must conform to existing constraints in the database, and transactions that complete successfully must get written to durable storage.

其中,all-or-nothing很明確的表達了事務的本質:“要麼全成功,要麼什麼都沒發生過”。可以把它看作一個原子操作。



HBase Transaction

(注:這裏經過補充與修改,第一天就被轉載本博文這裏的描述不夠準確)

HBase的支持的事務很有限,0.94版本的新特性中有兩條:

[HBASE-3584] - Allow atomic put/delete in one call.

[HBASE-5229] - Provide basic building blocks for "multi-row" local transactions.

第一條,我引用NoSQLFan的解讀:

“0.94版本具備更完整的事務支持: 之前Hbase提供行級的事務,不過每次事務只能執行一個寫操作,比如連續地執行一系列Put,Delete操作,那麼這些操作是單獨一個個的事務,其整體並不是原子性執行的。而在0.94版本中,可以實現Put、Delete在同一個事務中一起原子性執行。”

具體怎麼用呢?有下面這一段Sample:

//Add API for atomic row mutations to HBase (currently Put and Delete).
Client API would look like this:
Delete d = new Delete(ROW);
Put p = new Put(ROW);
//...
AtomicRowMutation arm = new AtomicRowMutation(ROW);
arm.add(p);
arm.add(d);
myHtable.atomicMutation(arm);

可以看到,這裏的事務僅僅是針對某一行的一系列Put/Delete操作。不同行、不同表間一系列操作是無法放在一個事務中的。

第二條,我的個人理解,這次是多行一併的事務了!不過貌似是“同一Region中的多行”。因爲文中一句“ Global (cross region) transactions are not discussed here.

因此對一張多Region表來說,還是無法保證每次修改都能封裝爲一個事務。


What We Need

結合我之前的博文《HBase多條件查詢》,我們通常需要爲了查詢而建立多個索引表。

比如我Save一條player數據,主表(信息完整表)的rowKey是以ID構成,順序排列。

我如果需要按player的積分(Scores)排個TOP 10,我可能還需要用(Max - player.getScores) + ID建一張索引表。同理可能還有多個……

每當插入一條player記錄,我需要同時對這兩個rowKey進行put操作。

這,就已經超出了HBase支持的事務範疇(同一行的一系列操作事務)。

此處無事務會怎樣?比如我新增一個player,首先執行IDTbl.put,再執行ScoresTbl.put。

在執行第二步ScoresTbl.put時與HBase Cluster的網絡中斷了,此時ScoresTbl.put超時失敗,但IDTbl.put已經成功完成了。

如果僅僅在業務層做了RollBack,此時應該會執行IDTbl.delete,但是網絡中斷,delete操作一樣會失敗。

網絡恢復了!

最終,我們新增的這位Player登錄進來(因爲IDTbl.put中有他的記錄,所以可以成功登錄)。

在點擊“查看我的排名”按鈕時會觸發ScoresTbl.get操作,但ScoresTbl中沒有他的記錄,對後續操作會有不可預知的影響。

如果,我們有10幾張索引表……

因此,事務是必須的!


What Can We Do

爲了解決這種不同記錄、不同表間的事務問題,我看到兩個項目。

1、yahoo/omid


The Omid project provides transactional support for key-value stores using Snapshot Isolation. Omid stands for Optimistically transactional Management in Datastores. At this stage of the project, HBase is the only supported data-store.

使用方式可以參考項目中的:

從Sample中看,我認爲會與Spring Hadoop的hbaseTemplate有衝突,因爲hbaseTemplate一次只能獲得唯一的HTable實例……

2、Indexed Transactional HBase


描述更是簡單:Transactional and indexing extensions for hbase

不過從github代碼的更新記錄來看,貌似已經2年沒更新了,支持到0.90……


其他解決方案,我也會繼續尋找,也請有過HBase事務應用的大牛們留言指個方向。謝謝 ^_^

Author:Pirate Leo
blog:http://blog.csdn.net/pirateleo
email:[email protected]
轉載請註明出處,謝謝。
由於文中在發佈後難免會有勘誤或補充,推薦到本博客中閱讀本文。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章