【轉】基於內存資料庫的分散式資料庫架構

--------本文是同事在程序員發表的文章,記錄下來。

【摘要】 本文提出了一種通過引入內存資料庫層,建立兩層多分區分散式資料庫架構。此方案用於解決海量高並發系統的數據存儲和訪問問題,尤其適用於電子商務等數據模型複雜且業務複雜的互聯網站。

這些年互聯網站發展迅猛,為應對海量數據下的高並發訪問,產生了各種分散式架構設計思想,例如Key-Value引擎,數據分區等。而對於電子商務類網站,海量數據問題還有一個重要特點,就是數據結構化及數據之間的關聯,淘寶如此,阿里巴巴也是如此,這是與社區、視頻、 博客等互聯網站的顯著差異。

1. NoSQL 是靈丹妙藥嗎?

NoSQL、Key-Value 引擎如BigTable、Cassendra等在很多大型網站被採用,很好的解決了海量數據存儲和訪問問題。而對於電子商務類網站,Key-Value和NoSQL並不是解決此問題的靈丹妙藥。最多它們僅能用於一些數據模型較為簡單的應用。

原因有兩個方面:

1)數據模型複雜

淘寶和阿里巴巴的會員、寶貝、供求、訂單等核心實體數據模型複雜,屬性個數幾十到上百個。例如:會員(Member)就包含基本信息、聯繫、工商、賬戶等多個域的信息;另外,核心實體之間,外圍實體與核心實體之間還存在複雜的關聯。

2)業務複雜:

模型的複雜源於業務和邏輯的複雜。電子商務網站大量查詢場景是結構化查詢,例如:

在淘寶上查詢「賣家在江浙滬,價格在50-200元的男士T恤」,

在阿里巴巴上「列出某個會員所有待發貨的訂單」

這類查詢(當然,阿里巴)主要針對多個非主鍵欄位, 即便對於BigTable、Cassandra 這樣的基於Column的Key-Value資料庫,其簡單的Query API還無法勝任此類需求。 因此在阿里巴巴和淘寶,Oracle、MySQL 等關係資料庫將仍然扮演重要角色。

2. MySQL 集群

引入K-V引擎等非關係資料庫無非是要解決海量數據在高並發環境下的高效讀寫問題,最大程度在可靠的持久化(Durable)與高訪問性能 (Performance) 之間選擇一個平衡點。在高度結構化系統中,同樣的考慮驅使我們需要考慮另外的解決方案。

目前一種通行的做法是 MySQL 讀寫分離式集群,1個或少數Master寫,多數Slave讀,Master與Slave進行變更數據的同步。首先,這種方案經過大量的實踐,可靠且可行。

然而,直接向DB執行寫操作,仍然比較耗時(參見表1,表2),數據複製,也可能存在不一致延時的情形。是否還有更快的方案?

3. 內存型關係資料庫

可靠的持久化指數據存儲到磁碟等設備上。圖1展示了傳統磁碟資料庫的基本訪問模式。

圖1

拋開持久化的可靠性,即數據可以先不存儲到磁碟上(Disk),內存存儲的性能遠高於磁碟存儲。下表展示了針對Oracle和Altibase所做的性能對比,後者在插入和查詢上性能是Oracle的5-7倍。

資料庫

測試結果

TPS

Oracle

203秒

246條/秒

Altibase

28.32秒

1785條/秒

表1. Oracle、Altibase性能對比 -插入5萬條 7

資料庫

測試結果

TPS

Oracle

885秒

112條/秒

Altibase

170秒

588條/秒

表2 Oracle、Altibase性能對比 – 關聯查詢10萬條7

由此可見:Pm >>> Pd

(Pm - 內存資料庫讀寫性能, Pd - 磁碟資料庫讀寫性能)

結合前面分析的模型複雜性和業務複雜性原因,關係資料庫(RDBMS)必須採用。因此,這兩點考慮可以推導出另一個解決思路:內存型關係資料庫。

磁碟型關係資料庫

Key-Value引擎

內存型關係資料庫

功能 -結構化操作和查詢等

Y

N

Y

性能

表3. DB選型對比分析

這個方案里,我們可以將內存先看做一種「磁碟」,讀寫操作都針對內存資料庫進行,不再直接與磁碟資料庫交互,這較好的避免了單純MySQL 讀寫分離架構存在的時間延遲和一致性問題。如下圖所示:

圖2

4. 內存資料庫的持久化

數據最終還是要存儲到磁碟(Disk)上,內存資料庫中的數據變化需要複製到與磁碟資料庫上。這時,從內存向磁碟複製數據的過程可以看作原始寫操作的非同步操作,顯然,非同步操作使得前端的寫操作顯得更快。如下圖所示:

圖3

在事務型(OLTP)系統中,內存資料庫中在啟動時需要和磁碟資料庫保持一致。 因此,內存資料庫需要有相同的庫表定義;並且在第一啟動時,將所需庫表數據載入到內存資料庫中。

5. 內存資料庫集群化

目前,經典的MySQL集群,通過讀寫分離,水平切分,實現海量數據存儲。為應對海量數據存儲,內存資料庫同樣需要做集群。垂直和水平切分策略,可用性策略與MySQL集群架構設計基本相同。如下圖所示,其中 Ameoba 是分散式資料庫代理,它進行數據路由等控制。

唯一的不同是,由於內存資料庫的高性能,可以不再進行讀寫分離設計。

圖4

6. 混合分區(Hybrid Shard)

接第4節的分析,內存數據最終仍需要持久化到磁碟。這裡需要一種混合分區(Hybrid Shard)來解決。即原來一個MySQL節點承擔的一個水平分區,將由一個內存資料庫節點和一個MySQL節點共同組成。

H-Shard = MDB + MySQL.

這種資料庫架構將形成由兩級資料庫(2LDB),混合分區構成的集群。的如下圖所示:

圖5

7. 內存資料庫選型

常見的內存資料庫產品包括商業版和免費版兩類。商業版如:Altibase,Timesten,Berkley DB等。他們在電信,金融,證券等高性能計算應用中運用較為廣泛。商業版功能強大,然而,價格比較昂貴,不適合目前「廉價PC+免費軟體」的架構搭建思想。

筆者曾就職與中國移動系統提供商,其中計費、運營等系統就運用Timesten提供高性能運算,但還主要用於高頻度小數據計算,如計費批價,優惠計算,信控等,採用單節點模式使用。

開源領域產品主要有H2,HsqlDB,Derby等。在混合分區架構中,內存資料庫將承擔OLTP的職責,因此除了讀寫性能外,功能的完備,事務等都需要作為優先評估的因素。

8. 新架構的挑戰

通過引入內存資料庫作為中間持久層,再加入分散式架構以支撐海量數據訪問,這種架構設計頗具挑戰。最先而易見的情況就是新架構的複雜度,正如大規模MySQL集群架構誕生初始一樣。

我們以 H2 ,一個開源的高性能內存資料庫為例說明:

1) 整合 Ameoba 與 H2

Ameoba 是分散式資料庫代理,它與 MySQL 整合已經在阿里巴巴核心業務中成功運用。如果僅將資料庫節點看作一個存儲,MySQL Node 和 H2 Node 並無本質區別。JDBC驅動,DB切分,路由,皆由Ameoba 統一負責。

2) 非同步持久化

每個邏輯混合分區= H2 + MySQL,誰來完成H2 中的數據變更非同步寫入 MySQL?

比較好的方案是內存資料庫提供實時增量的複製器(Replicator) ,例如:基於聯機日誌複製的雙機熱備機制。AltiBase 等產品就提供了此功能。

3)高可用性

內存資料庫一旦崩潰,數據不復存在。因此首先要做到數據快速非同步寫入MySQL作持久化存儲。同時要有健壯的容錯和Failover機制,保證一個H2節點崩潰,同一邏輯分區中的替補H2節點立即頂替工作。

一種方案是分散式資料庫代理如 Ameoba 來解決,例如:每個Shard,H2至少設2個節點,採用Primary-Secondary模式,如圖6所示:

圖6

另一種方案是前面提到的內存資料庫實時複製功能。

雖然有些內存DB如H2自身能支持內存,磁碟兩級存儲,但其自身提供的磁碟存儲和訪問方案可靠性不如 MySQL。因此,使用內存式Primary-Secondary 模式更為可行。

4)分散式事務

資料庫切分架構帶來分散式事務問題,對一些事務要求較高的場景,這頗具挑戰。Ameoba 目前還在解決中。Ameoba + H2組合面臨同樣的挑戰。

目前一種比較一致意見和做法就是冷處理——盡量不用事務。 一致性問題根據業務的特點,採用數據訂正來解決;個別業務使用補償事務。因為目前大部分應用,即便是核心業務,對事務的要求也不高。

9. 進一步思考

1) 多種數據切分模式

在一個大型互聯網站,不同的應用和數據需要做不同的處理。在總體垂直切分模式基礎上,選擇數據量大的功能進行水平切分,例如:供求、訂單、交易記錄。

2)數據緩存(Data Cache)

雖然內存資料庫層(MDB)能更高效支撐交易型資料庫,特別是應對結構化應用及複雜查詢服務,但對高頻度的查詢(Query)和實體查找(Find),Key-Value緩存仍然是一項必要的設計。Cache能提供更高的查詢速度,並減少對MDB的訪問壓力,特別是讀寫密集的高並發場景。因為這個架構中,內存資料庫仍然作為一種存儲Store,而不是Cache。

圖7

上圖展示了,MDB層之上還需要DCL層來提供高性能緩存服務。

10. 總結

本文提出了一種通過引入內存資料庫層,並建立兩層,多分區的分散式資料庫架構。此方案用於解決海量高並發系統的高性能數據存儲和訪問問題,尤其是電子商務類等業務複雜的互聯網站。其核心思想是:

1)高性能:是通過內存資料庫提供高性能關係資料庫存取服務,這是此架構的最主要目標;

2)持久化:通過兩級資料庫及非同步寫完成持久化;

3)海量數據支撐:通過垂直和水平分區實現海量數據的支撐;

4)高可用性:在Ameoba基礎上,通過主備節點進一步實現MDB的高可用性;二級磁碟資料庫可以實現數據的快速恢復。

【參考資料】

1. 阿里巴巴 Ameoba分散式資料庫設計和實踐

2. 岳旭強, 《淘寶網架構師岳旭強的年度展望》, http://www.infoq.com/cn

3. 廣東移動BOSS2.0分散式資料庫架構方案,計費系統設計和實踐.

4. Cassandra,http://cassandra.apache.org/

5. Oracle, Timesten 官方文檔, http://www.oracle.com/timesten/index.html

6. Fenng,《Oracle 內存資料庫-TimesTen》, http://www.dbanotes.net/database/oracle_timesten.html

7. 張澄,包文菖,《內存資料庫在BSS賬務處理中的應用》,《計費&OSS世界》,http://database.51cto.com/art/200612/36973.htm

8. Titan,《常用內存資料庫介紹》,http://titan.iteye.com/blog/364345

9. Ricky Ho, 《NoSQL的模式》,程序員2010-1;《NoSQL 資料庫的查詢處理》,程序員2010-2

問題:

這個模型是有很多可用場景的,樓主關於電子商務網站與SNS博客等網站的分析是很合理的,NOSQL在很多電子商務的場景下應用有局限,我們在搞國際交易的時候確實也遇到,特別是很多運營類的活動場景中,業務邏輯糾結的很。

以下有幾個的疑問探討下:

1) 高性能:是通過內存資料庫提供高性能關係資料庫存取服務,這是此架構的最主要目標;

~~~~RMDB的工作讓Ameoba 這個分散式資料庫代理在處理了。我認為最終的瓶頸會是AMEOBA,AMEOBA就是一個中心,擴展性怎麼樣,維護成本怎麼樣?為了實現切分和路由,很多數據還是依賴DB類的設備吧?

2) 持久化:通過兩級資料庫及非同步寫完成持久化;

~~~~~兩級資料庫的數據一致性怎麼保證?是最終一致性嗎?同一個數據會複製幾片?數據冗餘策略可調嗎?不同的應用場景對CPA的需求是不同,有些場景對數據一致性要求嚴一些,比如交易過程。

3) 海量數據支撐:通過垂直和水平分區實現海量數據的支撐;

~~~~~如果需要通過拆分來實現數據擴展,那麼海量的級別還是有很多約束的;加一台機器是不是要停機?重新分配拆分策略時所有機器的數據是不是要REOLAD?

4)高可用性:在Ameoba基礎上,通過主備節點進一步實現MDB的高可用性;二級磁碟資料庫可以實現數據的快速恢復。

~~~~~主備節點之間非同步方式實現 數據同步嗎?以後擴展數據或重新拆分數據的時候,主備節點都要重新劃分數據,會不會需要停機?備機只有主機宕機的時候才啟用吧?讀請求還是無法分散到備機上。平時備機的利用率是否有辦法提升?

回答:

Q1.數據路由層的運維成本。路由的實現方式?

Q2.數據節點層的運維成本。

A1.路由層跟普通的java應用部署類似,是一個多台pc組成的集群,路由軟體的升級、機器的維護都跟集群維護類似,可以單個單個的處理,而且擴展非常方便。

路由的實現不是查路由表,不需要保存到資料庫里,而是用簡單的哈希演算法來路由。

這樣路由層的每個節點就沒有持久化的數據,也就是無狀態的。

A2.數據節點間的切換和維護有路由層擋在前面,所以對應用來說數據節點層的運維幾乎是透明的。

我們現在採用的是一種簡化了的一致哈希演算法,所以增加數據節點的時候,對數據的遷移很少。

Q3.對一致性要求高的場景,雙層數據結構能支持嗎?

Q4.備機能否利用起來分擔部分讀的壓力。

A3.不能,要保證一致性就要事務,數據就要同時寫,不能非同步寫,要事務就架構複雜而且還會有很大延時,幾乎沒有什麼寫業務能忍受這樣的延時。

A4.不能,數據從主機到備機是有延時的,秒級到分鐘級不等,幾乎沒有什麼業務能忍受這樣的延時。

當然也有業務能忍受,就是類似中文站和國際站的【數據管家】業務,數據都是報表類型的,每天夜間生成,白天提供只讀服務,這樣的業務完全可以用備機來分擔部分壓力,甚至主備之間直接做負載均衡。


推薦閱讀:

Android開發轉型公司技術負責人是一種怎樣的體驗
《紫微斗數資料》紫微斗數的架構
攜程圖片服務架構
《架構即未來》(壹拾陸)
架構模式與煎餅果子

TAG:資料庫 | 架構 | 內存資料庫 | 分散式 | 分散式資料庫 |