分散式可擴充套件資料庫架構
資料庫叢集
oracle叢集
Oracle RAC是業界最流行的產品。其架構的最大特點是共享儲存架構(Shared-disk),整個RAC叢集是建立在一個共享的儲存裝置之上的,節點之間採用 高速網路互連。在 Oracle RAC 環境中,每個 Oracle 資料塊都被賦予一個(且只有一個)“主”Oracle RAC 節點。該 Oracle RAC 節點的全域性快取服務 (GCS) 負責管理對這些資料塊集的訪問。當其中一個 Oracle 節點需要訪問某個 Oracle 資料塊時,它必須首先與該資料塊協商。然後,該主節點的 GCS 或者指示請求的 Oracle 節點從磁碟中獲取該資料塊,或者指示該Oracle 資料塊的當前持有者將被請求的資料塊傳送到請求節點。Oracle 嘗試跨所有 RAC 節點統一分發該資料塊的所有權。在 Oracle RAC 環境中,資料塊大致相等的所有節點都將被指定為主節點。(如果 Oracle RAC 節點數是 Oracle 資料塊數的約數,則所有 RAC 節點都是具有同樣數量的資料塊的主節點。)
mysql叢集
MySQL cluster和Oracle RAC完全不同,它採用Shared-nothing架構。整個叢集由管理節點(ndb_mgmd),處理節點(mysqld)和儲存節點(ndbd)組 成,不存在一個共享的儲存裝置。MySQL cluster主要利用了NDB儲存引擎來實現,NDB儲存引擎是一個記憶體式儲存引擎,要求資料必須全部載入到記憶體之中。資料被自動分佈在叢集中的不同存 儲節點上,每個儲存節點只儲存完整資料的一個分片(fragment)。同時,使用者可以設定同一份資料儲存在多個不同的儲存節點上,以保證單點故障不會造成資料丟失。
MySQL cluster的優點在於其是一個分散式的資料庫叢集,處理節點和儲存節點都可以線性增加,整個叢集沒有單點故障,可用性和擴充套件性都可以做到很高,更適合 OLTP應用。但是它的問題在於:1.NDB儲存引擎必須要求資料全部載入到記憶體之中,限制比較大,但是目前NDB新版本對此做了改進,允許只在記憶體中加 載索引資料,資料可以儲存在磁碟上。2.目前的MySQL cluster的效能還不理想,因為資料是按照主鍵hash分佈到不同的儲存節點上,如果應用不是通過主鍵去獲取資料的話,必須在所有的儲存節點上掃描, 返回結果到處理節點上去處理。而且,寫操作需要同時寫多份資料到不同的儲存節點上,對節點間的網路要求很高。
分散式資料庫拆分
資料庫分片
Sharding 不是一個某個特定資料庫軟體附屬的功能,而是在具體技術細節之上的抽象處理,是水平擴充套件(Scale Out,亦或橫向擴充套件、向外擴充套件)的解決方案,其主要目的是為突破單節點資料庫伺服器的 I/O 能力限制,解決資料庫擴充套件性問題。
- 把熱度高的資料劃分開來,使用配置剛好的硬體,提高訪問速度,增強使用者體驗
- 把不同的使用者的資料根據使用者的id放到不同的資料庫中,不同使用者對應的交易資料也跟著到不同的資料庫;之後可以把交易完成和正在交易的資料庫分開。
-
一個全國經濟資訊系統,可以按照不同地區把不同資料放到不同資料庫中,隨著時間增加資料也會越來越大,到時還可以工具年份在重新劃分資料庫。
- 一個大中型的電子商的電子商務網站一定會遇到資料量巨大的問題,可以根據使用者物件或者使用和被使用的資料進行分片。這樣避免了在一個庫中資料膨脹而帶來的瓶頸。
- 在資料庫分片時最好分到不同的伺服器中,或者不同的儲存中,避免磁碟競爭
資料庫分片存在比較大問題就是人查詢或者統計涉及到跨庫就比較麻煩。特別是join時如果涉及到多個節點,將非常困難,應該儘量避免。
資料庫水平分片
讀寫分離
讀寫分離架構利用了資料庫的複製技術,將讀和寫分佈在不同的處理節點上,從而達到提高可用性和擴充套件性的目的。
讀寫分離簡單的說是把對資料庫讀和寫的操作分開對應不同的資料庫伺服器,這樣能有效地減輕資料庫壓力,也能減輕io壓力。主資料庫提供寫操作,從資料庫提供讀操作,其實在很多系統中,主要是讀的操作。當主資料庫進行寫操作時,資料要同步到從的資料庫,這樣才能有效保證資料庫完整性。Quest SharePlex就是比較牛的同步資料工具,聽說比oracle本身的流複製還好,mysql也有自己的同步資料技術。mysql只要是通過二進位制日誌來複制資料。通過日誌在從資料庫重複主資料庫的操作達到複製資料目的。這個複製比較好的就是通過非同步方法,把資料同步到從資料庫。
主資料庫同步到從資料庫後,從資料庫一般由多臺資料庫組成這樣才能達到減輕壓力的目的。讀的操作怎麼樣分配到從資料庫上?應該根據伺服器的壓力把讀的操作分配到伺服器,而不是簡單的隨機分配。mysql提供了MySQL-Proxy實現讀寫分離操作。不過MySQL-Proxy好像很久不更新了。oracle可以通過F5有效分配讀從資料庫的壓力。
上面說的資料庫同步複製,都是在從同一種資料庫中,如果我要把oracle的資料同步到mysql中,其實要實現這種方案的理由很簡單,mysql免費,oracle太貴。好像Quest SharePlex也實現不了改功能吧。好像現在市面還沒有這個工具吧。那樣應該怎麼實現資料同步?其實我們可以考慮自己開發一套同步資料元件,通過訊息,實現非同步複製資料。其實這個實現起來要考慮很多方面問題,高併發的問題,失敗記錄等。其實這種方法也可以同步資料到memcache中。聽說oracle的Stream也能實現,不過沒有試過。
上圖是ebay讀寫分離的結構圖,通過Share Plex 近乎實時的複製資料到其他資料庫節點,再通過F5特定的模組檢查資料庫狀態,並進行負載均衡,IO 成功的做到了分佈,讀寫分離,而且極大的提高了可用性。目前讀寫分離技術比較多,比較有名的為amoeba,有興趣的同學可以研究下。
資料庫快取
讀寫分離現在應用非常廣泛,特別是時國內外大型網站,都使用的非常多,很多都是自己研發快取系統,淘寶還開源了Tair系統,有興趣的可以研究下。比較有名的是memcached使用memcached最好的可能算facebook了。通過memcached分擔讀的操作,把常用的物件資料儲存到memcached中,當有讀操作過來時先訪問memcached如果memcached沒有該資料再從資料庫獲取,同時把資料放到memcached中,下次訪問就可以直接訪問memcached了。
有一次在和一個朋友聊天時他們正在著手線上文件系統架構設計,由於文件訪問壓力非常大,每次請求資料庫也非常大,由於大量的的文件資料在服務端和客戶端傳輸,會經常造成網路堵塞。我建議他可以把文件分片,減少一次性大檔案傳輸。再根據文件熱度把一些文件保持到快取中。其實文件也好,資料庫也好,很多方法只要根據業務要求也可以達到異曲同工的之效。