本節書摘來自異步社群出版社《解讀nosql》一書中的第2章,第2.5節,作者: 【美】dan mccreary(丹•麥克雷) , ann kelly(安•凱利),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
兼顧性能和一緻性的事務控制在分布式計算環境下是很重要的。通常會在兩種事務控制模型中選擇其一使用:acid用于rdbms,base用在很多nosql系統。即使資料庫事務隻有很少一部分需要事務完整性,但了解rdbms和nosql系統能夠采用這些事務控制政策也是很重要的。這兩種模型的差別在于應用開發人員所付出的努力和事務控制所發生的位置(層級)。
讓我們從一個簡單的銀行業務案例來展現一個可靠的事務。如今,許多人都有兩個銀行賬戶:儲蓄賬戶和支票賬戶。如果你想将一些資金從一個賬戶轉賬到另一個賬戶,銀行在網站上會有轉賬頁面,進行如圖2-7所示的一個資金轉賬流程。

圖2-7 這一系列原子步驟将資金從一個賬戶轉賬到另一個賬戶。第一步從儲蓄賬戶扣除所要轉賬的金額。第二步将相等的轉賬金額增加到支票賬戶。由于事務應該是可靠的,是以所有步驟要麼都執行要麼都不執行。在事務步驟之間,任何顯示賬戶總額由于交易金額而減少的報表都不應該被允許運作
當點選了網頁上的轉賬按鈕,兩個獨立的操作必須共同執行。首先從儲蓄賬戶中扣除轉賬金額,然後再加到支票賬戶中。事務管理是確定這兩個操作作為一個整體一起發生或者一起不發生的過程。如果計算機在第一個步驟完成後而第二個步驟還沒開始時崩潰了,你要損失1 000美元,你當然會對銀行産生極大不滿。
傳統的商業資料庫都以在金融事務方面的穩定和可靠而聞名。這不僅因為它們已經存在了相當長的時間,且一直不斷地進行着優化,還因為它使得程式員通過在事務開始和結束的地方進行聲明就可以很容易地保障關鍵事務的可靠性。這些聲明被稱作啟動事務(open transaction)和結束事務(end transaction)。通過添加它們,開發者能夠獲得高可靠的事務支援。如果兩個原子操作中的一個沒有完成,那麼所有操作都會被復原至它們最初的狀态。
系統同樣確定了不會有任何賬戶報表在操作進行到一半時生成。如果你在事務過程中執行生成賬戶餘額報表,它将不會顯示先有1 000數額的減少然後再增加1 000。如果報表在事務的第一個步驟進行時開始生成,它将會被阻塞,直到整個事務完成。
在傳統的rdbms中,事務管理的複雜性由資料庫層負責解決。應用開發者隻需要處理在整個事務失敗時,如何通知正确的元件或者不停重試直到事務完成。應用開發者并不需要知道如何撤銷一個事務的各種部分,因為這已經成為了資料庫内建的一部分。
由于可靠的事務對于大多數應用系統是很重要的,接下來的兩小節将深入研究rdbms的事務控制——acid和nosql系統的事務控制——base。
rdbms的事務控制通過原子性、一緻性、隔離性和持久性(acid)屬性來保證事務是可靠的。接下來将對每一個屬性進行定義。
原子性——在銀行交易的例子中,我們提到過從儲蓄賬戶到支票賬戶的現金轉移的過程要麼一起發生要麼都不發生。如果用技術術語來形容就是原子性,它來自于希臘語的“不可分”。如果系統聲明支援原子性事務,那麼它必須考慮所有失敗的情況:磁盤故障、網絡故障、硬體故障或者單純的程式錯誤。即使是在單個cpu之上測試原子性事務也是很困難的。
一緻性——在銀行交易的例子中,我們在兩個相關賬戶之間進行資金轉移,而總賬戶餘額從未改變,這是一緻性的原則。那意味着資料庫不能在支票賬戶餘額增加之前顯示儲蓄賬戶餘額減少。資料庫負責在原子操作持續的時間内阻塞所有報表。當資料庫基于同樣的記錄同時運作很多原子性事務和報表時,會影響系統的速度。
隔離性——隔離性指的是其他事務對該事務的每一部分的執行都不知情。例如,增加金額的事務并不知道從賬戶扣除金額的事務。
持久性——持久性指的是這樣一個事實,一旦事務的所有方面完成,它将是永久性的。一旦轉賬的按鈕被選中,你将可以消費你的支票賬戶中的資金。如果銀行系統在那天晚上崩潰了,他們需要用備份錄音帶恢複資料庫,那麼必須用某些方法確定轉賬記錄也被恢複。這通常意味着銀行必須在一個獨立的計算機系統中保留一份事務日志,當備份恢複完成後,根據事務日志重新執行一遍所有事務。
如果你認為處理這些規則的軟體一定很複雜,那麼你是正确的。确實非常複雜,這也是關系型資料庫非常昂貴的原因之一。如果你自己正在編寫一個資料庫,那麼有些必需的軟體子產品的數量很容易增至2倍或是3倍。這也是新資料庫産品經常在第一個釋出版中不支援資料庫級别的事務管理的原因,而是在産品成熟後才會加入。
許多rdbms将事務發生的範圍限制在單個cpu之内。如果考慮這種情況:你的儲蓄賬戶的資訊存儲在紐約的一台計算機裡,你的支票賬戶資訊存儲在舊金山的一台計算機裡,那麼複雜程度将會增加,因為這種情況有更多的失效點并且需要阻塞的基于這兩個系統的報表系統的數量也會增加。
盡管支援acid的事務很複雜,但還是有一些著名的、公認的政策來實作。它們都是基于鎖定資源,并預留出額外副本的資源,然後執行事務,如果一切都沒問題,再釋放資源。如果事務的任何一部分出錯,有争議的資源必須回到它的初始狀态。設計上的挑戰在于搭建支援這些事務的系統,使得應用可以個更容易地使用事務并且保證資料庫的運作速度和響應能力。
acid系統關注資料的一緻性和完整性,且高于其他考量。暫時阻塞報表的機制是為了確定系統傳回可靠準确的資訊的一種合理的妥協。acid系統可以說是悲觀的,因為它們必須考慮計算環境裡所有可能的失效模式。有時acid系統似乎服從墨菲定律——會出錯的事總會出錯——并且必須仔細測試保證事務完整性。
acid系統高度關注資料完整性,nosql卻是基于base準則考慮一系列稍有不同的限制。如果在等待另一個事務完成前阻塞事務對你來說是不可接受的妥協,會怎麼樣?如果你有一個接受客戶訂單的網站,有時acid系統不一定是你想要的。
假如你的網站是運作在遍布世界各地的計算機上,會怎樣?芝加哥的計算機負責管理庫存,而負責儲存産品照片的圖像資料庫在弗吉尼亞,計算稅收的程式在西雅圖運作,賬戶系統在亞特蘭大。如果一旦其中一個站點當機會怎麼樣?你是否應該告訴客戶等你在20分鐘内解決問題後再回來?除非你是想将客戶拱手相讓給競争對手。使用acid系統處理到達的每一個訂單現實嗎?讓我們看看另一種選擇。
使用“購物車”和“結賬台”概念的網站對于事務處理有不同的側重。在幾分鐘内報表不一緻與無法下訂單相比是不那麼重要的,因為如果阻塞一個訂單,就損失了一個客戶。這種情況下,可以使用base來替代acid。下面是base的一些概念。
基本可用是指允許系統暫時不一緻,這樣事務就容易管理。在base系統中,資訊和服務能力是“基本可用的”。
軟狀态是指為了降低消耗的資源,可以暫時允許一些不準确的地方和資料的變換。
最終一緻性意味着在最後,當所有服務邏輯執行完成後,系統最後将回到一個一緻的狀态。
與rdbms關注一緻性不同,base系統關注可用性。base系統顯著的特點是它們的首要目标是要保證在短時間内,即使有不同步的風險,也要允許新資料能夠被存儲。nosql系統放寬了規則并允許即使不是所有資料庫都是同步的,也能運作報表。base系統不被認為是悲觀的,因為它們并不會關心某個過程背後的細節。它們是樂觀的,因為它們假設最後所有系統都會同步而變得一緻。
base系統傾向于更加簡單和迅速,因為它們不必編寫處理鎖定和釋放資源的代碼。它們的任務是保證流程運轉并稍後處理出錯的部分。base系統非常适合支援網上商店,填滿購物車和下訂單才是它們的主要優先功能。
在nosql運動之前,大多數資料庫專家認為acid系統是唯一能夠商用的事務類型。nosql系統是高度去中心化的,并且acid提供的保障有時不是必須的,是以nosql采用了base和一些更為寬松的方法。圖2-8顯示了一個準确的、有點幽默的acid和base哲學之間的對比。
圖2-8 acid與base——了解其中的利弊。該圖比較了應用于嚴格的金融賬戶規則的傳統rdbms的acid事務與nosql系統更加寬松的base方法。當要求所有報表必須始終保持一緻性和可信性,rdbms acid系統是理想的選擇。當把永遠不阻塞寫事務作為高優先級任務時,nosqlbase系統是合适的選擇。業務需求将決定是傳統的rdbms還是nosql系統适合你的應用
最後還要提醒讀者:acid和base并沒有一個嚴格界限,它們取決與組織和系統決定在哪裡和如何架構這個系統的場景。它們可能允許在某些關鍵領域采取嚴格的acid事務,其他領域标準稍微放松一些。一些資料庫系統通過改變配置檔案或者使用不同的api提供了雙重選擇。系統管理者和應用開發者可以一起在考慮了業務的需要之後,實作正确的選項。
當你為了處理海量資料而進行擴充并将系統架構從集中式遷移到分布式系統時,事務是重要的。但是有時你管理的資料超過了目前系統能夠管理的規模,那就需要采取資料庫分片來保證新系統運作并減少當機時間。