支援事務,還是不支援事務?這是一個問題

語言: CN / TW / HK

時序資料庫是過去幾年內需求成長最旺盛的一類資料庫。在傳統的OLTP關係型資料庫領域,已經有了不少標杆型的產品,如oracle, mysql, postgresql等等,因此關於這類資料庫,一些關鍵的設計決策已有公認的解決方案。然而與之不同的是,時序資料庫作為一類新興的資料庫,目前仍可以說是百花齊放,不同的資料庫產品在關鍵的設計決策上常常都會有區別。那麼究竟哪種設計是更合理更“正確”的呢?在許多問題上,目前尚沒有定論。

事務就是這樣一個典型的例子。很多人認為時序資料庫不需要支援事務,也因此,大部分時序資料庫產品並沒有支援事務;而在這方面,DolphinDB則是一個例外:DolphinDB是支援基本的事務的。那麼時序資料究竟需不需要支援事務呢?為什麼DolphinDB選擇支援事務呢?我們邀請到了DolphinDB智臾科技研發總監周信靜 來談一談他對於這個問題的看法。


Q1 很多人認為時序資料庫並不需要支援事務,或者說對事務的需求並不多,對此你怎麼看?

如果是簡單的應用,比如用時序資料庫來做一下監控視覺化,確實事務沒有太大的必要。但是在很多對資料一致性要求高的場景下,不支援事務的時序資料庫是沒法用的。事務有很多非常好用的特性,它能夠保證資料一致性,併發隔離,簡化運維,避免資料丟失,甚至有些應用程式依賴這種特性來完成功能。最關鍵的是,如果資料庫本身不支援事務,那麼使用者即便在應用層有這樣的需求也只能束手無策。總之,時序資料庫如果支援事務,不僅能處理很多簡單的應用場景,還能處理更加複雜高階的應用場景,何樂而不為?

 

Q2 支援事務對時序資料庫來說有著怎樣的意義或者利弊?

時序資料庫事務使得資料庫可以支援更多的高階時序資料庫應用場景,保證資料一致性,併發隔離,簡化運維,避免資料丟失。值得指出的是,由於時序資料庫需要提供持續不斷的高吞吐寫入,故效能對於時序資料庫異常重要,因此有人可能會認為事務會影響讀寫效能。針對這一問題,DolphinDB利用了時序資料庫批量寫入的特點,用兩階段提交協議實現了分散式事務,為寫入提供了高吞吐的事務支援,能很好地滿足寫入吞吐要求。換言之,我們的實現使得DolphinDB既支援了事務,又保證了寫入效能。除此之外,時序資料庫使用者往往希望在寫入量巨大的同時下還能夠執行大規模的資料分析,這要求讀寫不相互影響。為了解決這個問題DolphinDB在兩階段提交基礎上實現了MVCC 機制,提供了全域性快照讀的隔離級別,同時讀取不會影響寫入,寫入也不會影響讀取。談到支援事務的弊端,那麼對多數產品來說,一個弊端就是支援事務會使得資料庫的實現變得複雜很多,而這對於我們來說不是問題,因為我們有足夠強的工程能力去完成這個功能的實現。反之,如果選擇不支援事務,那麼對於需要支援事務的場景來說,實際上也只是把工程的複雜性轉移到了使用者頭上,這是我們不想看見的。

 

Q3 可以舉些例子說明支援事務在時序資料庫應用中的優勢嗎?

如果我們只是用於視覺化,一些簡單的統計,事務的確不重要。但是如果希望通過資料來決策,反控我們的交易,我們的裝置,就很重要。舉個金融領域的例子,股票市場的報價快照資料3秒鐘一批進入時序資料庫,同時因為資料量很大,我們往往會把資料進行分散式儲存在多臺資料節點上。交易程式從時序資料庫中讀取報價資料,根據模型做出交易決策。如果我們在交易決策的時候,一部分股票是3秒鐘前的資料,一部分股票是現在的資料,那麼交易決策很大可能是錯誤或者不是最優的,這不是金融客戶希望看到的。再舉個物聯網常見的例子,時序資料庫被用在工業控制演算法的一環裡,用來反向控制裝置的狀態,比如給裝置降升溫、降升壓等等。這種場景下大量感測器資料定期被寫入我們的資料庫,控制演算法從我們的資料庫中讀取感測器時序資料做控制決策,如果沒有事務的話,控制演算法看到一部分資料是舊的,一部分是新的,在這種不一致資料下做出的錯誤決策可能是災難性的,比如造成事故。因此支援事務在這些高階場景下是重要甚至是必須的。再舉一個例子,在沒有事務支援的時序資料庫中,如果發生了宕機,可能會造成資料的丟失和不一致,沒有辦法恢復。在DolphinDB中,資料節點宕機不會造成資料丟失,我們的事務和恢復機制保證資料寫入要麼完成要麼沒有完成,不會因為斷電宕機造成資料部分寫入部分丟失,這就大大解放了運維保障工作。

 

DolphinDB是如何實現事務的?

事務保證了ACID,即原子性(Atomicity),一致性(Consistency,隔離性(Isolation),永續性(Durability)。

  • DolphinDB通過WAL(Write Ahead Log)來保證事務的原子性和永續性,對資料的操作首先寫入到WAL(Write Ahead Log),若事務進行到一半發生錯誤(如宕機),在重啟時可以根據WAL將事務回滾(rollback),保證事務包含的操作要麼全部成功,要麼全部失敗。
  • DolphinDB通過兩階段提交協議(Two-phase commit, 2PC)來保證分散式事務的原子性以及叢集資料的一致性。對於分散式事務涉及到的所有節點,要麼全部節點上執行成功(commit),要麼全部失敗(rollback),不會出現部分成功部分失敗的情況。
  • DolphinDB通過多版本控制(Multiversion concurrency control, MVCC)來保證隔離性。讀和寫的併發事務相互隔離,讀取不會影響寫入,寫入也不會影響讀取。
  • DolphinDB通過Raft來保證叢集元資料的一致性。

 

2PC

在一個分散式事務中, 可能涉及多個數據節點,兩階段提交協議(Two-phase commit, 2PC)主要用於保證分散式事務的原子性,即要麼全部節點上執行成功(commit),要麼全部失敗(rollback),不會出現部分成功部分失敗的情況。


2PC中包含兩種角色:協調者(coordinator)和參與者(participant)。協調者決定事務的全域性狀態以及負責推進整個事務.2PC包含兩個階段:

  • Commit request (or voting) phase
    協調者向所有參與者分發事務內容以及傳送PREPARE資訊詢問是否可以提交. 參與者執行事務中包含的操作(但不會提交), 並根據執行的結果回覆YES或者NO。
  • Commit (or completion) phase
    協調者根據參與者的回覆來決定事務的狀態是COMMITABORT: 只有全部參與者回覆YES, 事務的狀態才會是COMMIT, 否則為ABORT. 然後協調者將事務的狀態(COMMIT/ABORT)傳送給所有的參與者, 參與者據此提交或終止該事務。

 

MVCC

多版本控制(Multiversion concurrency control, MVCC)是一種併發控制協議用以保證資料庫的資料一致性。如果沒有併發控制, 併發的讀和寫可能導致讀者讀取到寫入一半的資料,從而導致資料不一致。鎖(read-write lock)是一種常用的併發控制手段, 通過建立臨界區,使得併發的讀寫序列化,保證了併發下的正確性。但是這種方式會使得讀寫相互阻塞, 有一定的效能損失。

MVCC提供了快照級的隔離等級(snapshot isolation),其核心原則就是讀取不會影響寫入,寫入也不會影響讀取。MVCC維護了資料庫裡資料的多個版本,每一個事務看到的都是事務開始時資料的快照。當一個事務需要更新資料時,不會立即覆蓋原資料,而是為資料建立一個新的版本,在該事務提交之前,對資料的更改對於其他事務是不可見的(其看到的是老版本的資料)。


支援事務,還是不支援事務?這是一個問題。DolphinDB對此的回答是:支援。支援事務,能夠保證資料的一致性,能夠減少運維的複雜性,同時能夠大大擴充套件資料庫的應用場景。而針對事務對於效能的影響,DolphinDB使用兩階段提交協議和MVCC以及團隊強大的工程能力來保證效能。

總之,希望這篇文章能給大家帶來一些啟發,幫助大家思考事務對於時序資料庫的意義。謝謝閱讀!