如何解決分佈式系統數據事務一致性問題web
(HBase加Solr)數據庫
摘要:對於全部的分佈式系統,我想事務一致性問題是極其很是重要的問題,由於它直接影響到系統的可用性。本文如下所述所要解決的問題是:對於入HBase和Solr的過程,如何保證HBase中寫入的數據與Solr中寫入的數據徹底一致。編程
關鍵詞:HBase, Solr, 分佈式, 事務, 系統架構, 大數據緩存
做者:王安琪(博客:http://www.cnblogs.com/wgp13x/)網絡
Java 中有三種能夠的事務模型,分別稱做本地事務模型(Local Transaction Model),編程式事務模型(Programmatic Transaction Model),和聲明式事務模型(Declarative Transaction Model)。事務要求包含原子性(Atomicity),一致性(Consistency),獨立性(Isolation),和持久性(Durability)。架構
《大型網站系統與Java中間件實踐》一書中分享了一些解決分步式系統一致性問題的方案構思與實踐,如在第六章中談到的消息中間件。下表展示瞭解決一致性方案與傳統方式的對比。框架
傳統方式是,我作完了,發你消息。解決一致性的方案的意思就是,我先發你消息,我作完了再跟你確認我作完了。這是改進後的有事務的消息中間件。異步
由於在非XA 環境中,消息隊列的插入過程獨立於數據庫更新操做,ACID 準則中的原子性和獨立性不能獲得保證,從而總體上數據完整性受到損害。使用X/Open 的XA 接口,咱們便可以作到協調多個資源,保證維持ACID 準則。分佈式
在《淘寶技術這十年》這本書裏也提到這麼一段描寫「用戶在銀行的網關付錢後,銀行須要通知到支付寶,但銀行的系統不必定能發出通知;若是通知發出了,不必定能通知到;若是通知到了,不必定不重複通知一遍。這個情況在支付寶持續了很長時間,很是痛苦。支付寶從淘寶剝離出來的時候,淘寶和支付寶之間的通訊也面臨一樣的問題,那是2005年的事情,支付寶的架構師魯肅提出用MQ(Message Queue)的方式來解決這個問題,我負責淘寶這邊讀取消息的模塊。但咱們發現消息數量上來以後,經常形成擁堵,消息的順序也會出錯,在系統掛掉的時候,消息也會丟掉,這樣很是不保險。而後魯肅提出作一個系統框架上的解決方案,把要發出的通知存放到數據庫中,若是實時發送失敗,再用一個時間程序來週期性地發送這些通知,系統記錄下消息的中間狀態和時間戳,這樣保證消息必定能發出,也必定能通知到,且通知帶有時間順序,這些通知甚至能夠實現事務性的操做。」性能
一致性更是能夠分爲強一致性和弱一致性兩種,弱一致性能夠容許某一時間間隔內的偶爾不一致,強一致性的要求要高不少。在實際中,弱一致性每每就能達到業務要求,甚至某些銀行系統都只要求弱一致性便可,容許不一致性的窗口存在,只要不形成損失便可。
對於每一種分佈式系統,其組織方式各不相同,實現形式也各有千秋,業務要求更是變幻無窮,所以要因地制宜的實施一致性方案。表6-5提出的解決辦法是要求處理方在完成業務操做後主動發送給消息中間件這一結果,然後消息中間件確認後再作處理,這樣是能夠保證事務性。但對於表6-5提出的解決辦法,在入HBase和Solr的流程中並不能適用。由於爲了保證數據寫入Solr的性能,入Solr使用的是Concurrent....方式,然而此種方式並不會返回是否入Solr成功,所以這種異步特性不是表6-5中方案所能解決的。
在此,咱們對於HBase加Solr這種分佈式系統,通過種種構思-推翻-再構思-再推翻,終於成功,特設計了以下事務一致性解決方案。
圖1 HBase加Solr分佈式系統事務一致性解決方案(寫入數據)
從圖1時序圖中能夠看出,其思想與表6-5方案仍是一致的,但實現手法則徹底不一樣。它的本質便是:須要確認數據處理成功後,方可證明數據同步。關鍵在於,如何確認數據處理成功,靠HBase返回?靠Solr返回?不行。那只有作個緩存,先把沒確認的存着,等後期有時間了挨個確認。這裏的MySQL就起到了方案所述的緩存的做用。咱們先把數據寫入到MySQL緩存起來,寫入時數據狀態爲0,說明尚未提交HBase和Solr,每間隔3秒咱們使用「入庫線程」取狀態爲0的數據,提交到HBase和Solr中,並將數據狀態更新爲2,以此說明此數據已經入了庫。若是沒有「覈查線程」作數據一致性檢查,則數據一致性沒法保證。有可能存在這樣一種狀況:HBase裏數據寫入成功了,Solr裏出於某種緣由沒有寫入成功(Solr異常了或網絡不通了等等)。若是此不一致性好久沒有被發現,那麼就會在HBase中出現一些根本沒法取得的飄浮數據。我們的「覈查線程」能夠保證HBase中和Solr裏的數據是一致的。
如今咱們已經作到了寫入數據操做的事務一致性,同理的還有,刪除數據操做的事務一致性,更新數據操做的事務一致性,均可以以這種思想實現。
圖2 HBase加Solr分佈式系統事務一致性解決方案(刪除數據)
從圖2中能夠看出,刪除數據先從Solr中刪除,再從HBase中刪除,一樣的,若是發生某種不可預見的異常,HBase中也會出現一些根本沒法取得的飄浮數據,這種狀況不多見,然而一旦發生,我們的「覈查線程」能夠保證HBase中和Solr裏的數據是一致的。
圖3 HBase加Solr分佈式系統事務一致性解決方案(更新數據)
更新數據的一致性解決方案要稍微複雜一些,由於對HBase和Solr中數據覈查某一數據是否已經正確更新是很難作到的。你能夠將HBase中的數據一個個地取出來與更新數據進行比較,查看是否已經正確更新;但你沒有辦法將更新數據全部的字段去Solr中查,是否更新到Solr。所以咱們設計的方案是:先對要更新的RowKey-數據生成一個新的newRowKey,再將HBase和Solr中的原始數據進行刪除,而後將更新後的數據添加入HBase和Solr中,這樣就是完成了一次更新數據的操做,將更新分紅了刪除與添加兩步進行操做,覈查此數據是否已經正確更新也所以有跡可尋,此時只須要搜索HBase和Solr中有newRowKey便可證實數據已經更新成功。
在這裏,咱們引用一下《支付寶數據平臺》中的海狗系統的架構設計。海狗系統(ARSC)——準實時搜索查詢,它提供千億級別數據實時查詢和全文檢索、支持天天10億+級別的數據更新。它的實時性能夠保證明時搜索延遲3s、查詢和插入TPS > 1.5WTPS。數據容量線性擴展,Schema擴展基於HBase列式無限擴張,基於ZK動態感知節點狀態自動容災。下圖即簡單代表了其流程。
粗看不起眼,琢磨一下便知其是考慮到了HBase和Solr的數據一致性的。在HBase中的MQ表就是起到上面咱們的設計方案中的MySQL的做用。在d步驟中,才批量刪除處理過的數據,MQ表是留憑證用的。HBase在高性能處理方面仍是要遠遠優於MySQL,若是能夠,咱們設計方案中的MySQL也能夠用HBase取代。
作個總結:不管是咱們設計方案,仍是其餘相似的分佈式系統事務性解決方案,其的本質思想是同樣的,即是:作個緩存,先把沒確認的存着,等後期有時間了挨個確認。
「既然計算是異步的,那麼反饋也應該是異步的,你徹底可讓SendMail將發送結果寫入數據庫,並生成報表,而後讓應用程序按期對報告中發送失敗的郵件執行再次發送。這裏須要假設失敗的狀況並非不少。」在《構建高性能web站點》第17章分佈式計算-異布計算中對此類問題的解決方法,也是構成咱們解決HBase和Solr分佈式系統事務一致性問題的重要指導,感謝做者郭欣。固然也感謝《大型網站系統與Java中間件實踐》的做者曾憲傑、《構建高性能web站點》的做者郭欣。更感謝分享海狗系統設計的蔣傑(花名:平原君),以及衆多樂於分享技術的人們。
看這些書,以爲系統架構方面的技術真的是很是龐大,佩服阿里的那羣將數據從小作到大的問題解決者。千里之行,始於足下。