MongoDB、Cassandra、HBase的事務設計策略
NoSQL數據庫(如MongoDB、Cassandra、Hbase、DynamoDB、Riak)讓應用程序開發變得更簡單。它們提供了相當靈活的數據模型和豐富的數據類型,而且與許多傳統數據庫系統相比,更易于安裝和配置。但缺少原子事務支持卻是一大退步。Daniel Abadi是耶魯大學的一名副教授,主要從事數據庫系統架構和實現研究。近日,他在一篇 文章 中剖析了NoSQL數據庫不支持原子事務的原因,并提供了兩種實現可擴展、事務型NoSQL數據庫的方案。
原子事務允許對數據庫中的不同數據項同時進行寫操作,這些操作要么全部執行,要么全部不執行。而且,結合恰當的并發控制機制,原子性可以確保并發及后續事務要么可以看到原子事務所有已完成的寫入,要么一個都看不到。缺少原子事務,應用程序開發人員就需要自己處理一組寫操作僅有部分成功的情況。
也許有人會認為,NoSQL數據庫比較新,還沒有時間實現原子事務支持。實際上,Cassandra的“批量更新”特性可以視為向這個方向前進了一小步。不過,NoSQL數據庫已經出現了將近十年,它們沒有實現事務支持顯然有更深層次的原因,那就是對可擴展性的關注。按照設計,大多數NoSQL系統都要能夠跨多臺不同的機器擴展,數據庫中的數據分布在不同的機器上。一個事務中的寫入操作可能會訪問多個分區(在多臺機器上)的數據,這就是“分布式事務”。在分布式事務中確保原子性需要參與事務的機器相互協作。每一臺機器都必須確定,事務在其它機器上能夠成功提交。而且,需要有一個協議,確保事務寫入操作涉及的機器在寫入數據狀態穩定之前都不會出現故障。這個協作過程不僅會消耗大量的資源,而且會增加數據庫請求延遲。更大的問題是,在協作過程完成之前,其它操作無法讀取該事務寫入的數據。并發事務延遲會導致其它與出現延遲的事務在時間上存在重疊的事務延遲,最終導致系統“阻塞 (cloggage)”。分布式事務所需的分布式協作會嚴重影響數據庫系統的性能,包括事務吞吐量和事務延遲。因此,大多數NoSQ系統都選擇了不支持事務。
MongoDB、Riak、Hbase和Cassandra都支持單個 鍵 的事務操作。這是因為單個鍵的所有信息都存儲在單臺機器上。因此,單個鍵的事務操作并不涉及上述復雜的分布式協作。由于分布式事務需要分布式協作,所以似乎必須在性能可擴展性和分布式事務支持之間進行權衡。事實上,許多NoSQL數據庫提供商都是基于這個假設,在構建可擴展系統時,為了防止服務器性能退化,放棄支持分布式原子事務。
Daniel指出,這是 完全錯誤 的。可擴展系統是可以支持高性能分布式原子事務的。他們最近發表了一篇 論文 ,提出了一種在可擴展系統中支持原子事務的、新的權衡策略,具體是在公平性、隔離性和吞吐量(FIT)三者之間進行取舍。其中,公平性是指任何事務的執行都不會因為其它事務被故意延遲,而隔離性可以確保相互沖突的事務可以看到其它事務的寫入操作。一個支持分布式原子事務的可擴展數據庫至少可以實現上述三個屬性中的兩個。FIT三者之間的取舍可以產生三種支持分布式原子事務的方案:
- 保證公平性和隔離性而犧牲吞吐量的系統;
- 保證公平性和吞吐量而犧牲隔離性的系統;
- 保證隔離性和吞吐量而犧牲公平性的系統。
換句話說,下面兩種方法都可以構建出具備高分布式事務吞吐量的可擴展系統。
放棄隔離性
如上所述,導致數據庫系統阻塞的根本原因是分布式協作。更確切地說,如果一個事務正在執行,那么其它需要訪問共享數據的事務必須等到分布式協作完成后才能進行。這種等待就是由強隔離性所保證的,因為它確保事務可以看到與它沖突的事務。如果放棄隔離性,那么其它事務就看不到其它事務的操作,也就不必等待分布式協作完成就可以執行和提交。而且,有一類數據庫約束可以確保分布式數據庫在事務弱隔離情況下的正確性。更多信息可以閱讀Peter Bailis的文章《 多分區原子讀(RAMP) 》。
放棄公平性
分布式協作同隔離機制在時間上存在重疊。所以,可以通過重新設定分布式協作的順序最小化兩者之間的時間重疊,從而減輕二者之間的相互影響。以此為基礎構建的系統放棄了公平性,可以選擇最合適的時間進行分布式協作,Daniel將這樣的系統稱為 “隔離性-吞吐量”系統 。比如,可以在事務之外進行協作,協作所需的時間不會增加并發事務的執行時間。
G-Store 就是一個很好的“隔離性-吞吐量”系統示例。它支持多鍵事務,并將事務范圍限制為應用程序動態定義的鍵集,即KeyGroup。該鍵集可以隨需創建和銷毀。當應用程序定義了一個KeyGroup,G-Store會將相應的鍵值對全部復制到一個領導節點上,該鍵集上的所有事務都會在該領導節點上執行。因此,G-Store事務并不需要在事務執行期間執行分布式提交協議。這里的關鍵是,G-Store仍然必須執行分布式協作,但協作過程在事務執行之前完成 ——在需要考慮事務隔離性之前。一旦協作過程完成,事務很快就會完成,共享數據的并發事務就不需要等待分布式協作。這樣,G-Store就實現了高吞吐量和強隔離性。
因此,實現高吞吐量分布式事務的關鍵是按照上述方法在時間上將分布式協作同隔離機制分開。