大型WEB資料庫分佈祕籍。?

網站在Web 2.0時代,時常面臨迅速增加的訪問量(這是好事情),但是我們的應用如何滿足使用者的訪問需求,而且基本上我們看到的情況都是效能瓶頸都是在資料庫上,這 個不怪資料庫,畢竟要滿足很大訪問量確實對於任何一款資料庫都是很大的壓力,不論是商業資料庫Oracle、MS SQL Server、DB2之類,還是開源的MySQL、PostgreSQL,都是很大的挑戰,解決的方法很簡單,就是把資料分散在不同的資料庫上(可以是硬 件上 的,也可以是邏輯上的),本文就是主要討論如何資料庫分散儲存的的問題。

大型WEB資料庫分佈祕籍。

資料庫分佈基本介紹

目前主要分佈儲存的方式都是按照一定的方式進行切分,主要是垂直切分(縱向)和水平切分(橫向)兩種方式,當然,也有兩種結合的方式,達到更到的切分粒度。

1. 垂直切分(縱向)資料是資料庫切分按照網站業務、產品進行切分,比如使用者資料、部落格文章資料、照片資料、標籤資料、群組資料等等每個業務一個獨立的資料庫或者資料庫伺服器。

 2. 水平切分(橫向)資料是把所有資料當作一個大產品,但是把所有的平面資料按照某些Key(比如使用者名稱)分散在不同資料庫或者資料庫伺服器上,分散對資料訪問的壓力,這種方式也是本文主要要探討的。

資料庫詳細分佈介紹

 【一、基於雜湊的分佈方式 】
  1. 雜湊方式介紹
  基 於雜湊(Hash)的分佈儲存方式,主要是依賴主要Key和雜湊演算法,比如以使用者為主的應用主要的角色就是使用者,那麼做Key的就可以是使用者ID或者是用 戶名、郵件地址之類(該值必須在站點中隨處傳遞),使用這個唯一值作為Key,通過對這個Key進行雜湊演算法,把不同的使用者資料分散在不同的資料庫節點 (Node)上。
  我們通過簡單的例項來描述這個問題:比如有一個應用,Key是使用者ID,擁有10個數據庫節點,最簡單的雜湊演算法是我們 使用者ID數模以我們所有節點數,餘數就是對應的節點機器,演算法:所在節點 = 使用者ID % 總節點數,那麼,使用者ID為125的使用者所在節點:125 % 10 = 5,那麼應該在名字為5的節點上。同樣的,可以構造更為強大合理的Hash演算法來更均勻的分配使用者到不同的節點上。
  我們檢視一下采用雜湊分佈方式的資料結構圖:

大型WEB資料庫分佈祕籍。

【 二、基於全域性節點分配方式 】
1. 全域性節點分配方式介紹
  就是把所有Key資訊與資料庫節點之間的對映關係記錄下來,儲存到全域性表中,當需要訪問某個節點的時候,首先去全域性表中查詢,找到以後再定位到相應節點。全域性表的儲存方式一般兩種:
  (1) 採用節點資料庫本身(MySQL/PostgreSQL)儲存節點資訊,能夠遠端訪問,為了保證效能,同時配合使用 Heap(MEMORY) 記憶體表,或者是使用 Memcached 快取方式來快取,加速節點查詢
  (2) 採用 BDB(BerkeleyDB)、DBM/GDBM/NDBM 這類本地檔案資料庫,基於 key=>value 雜湊資料庫,查詢效能比較高,同時結合 APC、Memcached 之類的快取加速。
  第 一種儲存方式是容易查詢(包括遠端查詢),缺點是效能不太好(這個是所有關係型資料庫的通病);第二種方式的有點是本地查詢速度很快(特別是hash型數 據庫,時間複雜度是O(1),比較快),缺點是無法遠端使用,並且無法在多臺機器中間同步共享資料,存在資料一致的情況。
  我們來描述實施 大概結構:假如我們有10個數據庫節點,一個全域性資料庫用於儲存Key到節點的對映資訊,假設全域性資料庫有一個表叫做 AllNode ,包含兩個欄位,Key 和 NodeID,假設我們繼續按照上面的案例,使用者ID是Key,並且有一個使用者ID為125的使用者,它對應的節點,我們查詢表獲得:
   Key NodeID
   13 2
   148 5
   22 9
   125 6
  可以確認這個使用者ID為125的使用者,所在的節點是6,那麼就可以迅速定位到該節點,進行資料的處理。
  我們來檢視一下分佈儲存結構圖:

大型WEB資料庫分佈祕籍。

【 三、存在的問題 】
  現在我們來分析和解決一下我們上面兩種分佈儲存方式的存在的問題,便於在實際考慮架構的時候能夠避免或者是融合一些問題和缺點。
  1. 雜湊和全域性分配方式都存在問題
  (1) 雜湊方式擴容不是很方便,必須修改雜湊演算法,同時可能還需要對資料進行遷移,它的優點是從Key定位一個節點非常快,O(1)的時間複雜度,而且基本不需要查詢資料庫,節約響應時間。
  (2) 全域性分配方式存在的問題最明顯的是單點故障,全域性資料庫down掉將影響所有應用。另外一個問題是查詢量大,對每個Key節點的操作都必須經過全域性資料庫,壓力很大,優點是擴容方便,增加節點簡單。
  2. 分佈儲存帶來的搜尋和統計問題
  (1) 一般搜尋或統計都是對所有資料進行處理,但因為拆分以後,資料分散在不同節點機器上,無法進行全域性查詢和統計。解決方案一是對主要的基礎資料儲存在全域性表中,便於查詢和統計,但這類資料不宜太多,部分核心資料。
  (2) 採用站內搜尋引擎來索引和記錄全部資料,比如採用 Lucene 等開源索引系統進行所有資料的索引,便於搜尋。 對於統計操作可以採用後臺非實時統計,可採用遍歷所有節點的方式,但效率低下。
  3. 效能優化問題
  (1) 雜湊演算法,節點概率和分配等為了提高效能都可以使用編譯語言開發,做成lib或者是所有php擴充套件形式。
  (2) 對於採用 MySQL 的情況,可以採用自定義的資料庫連線池,採用 Apache Module 形式載入,能夠自由定製的採用各種連線方式。
  (3) 對於全域性資料或都頻繁訪問的資料,可以採用APC、Memcache、DBM、BDB、共享記憶體、檔案系統等各種方式進行快取,減少資料庫的訪問壓力。
  (4) 採用資料本身的強大處理機制,比如 MySQL5 的表分割槽或者是 MySQL5 的Cluster 。另外建議在實際架構中採用InnoDB表引擎作為主要儲存引擎,MyISAM作為一些日誌、統計資料等場合,不論在安全、可靠性、速度都有保障。

總結

  本文泛泛的分析了在網站專案(特別是Web2.0)中關於資料庫分佈儲存的一些方式方法,基本上上面提到的兩種分佈方案筆者都經過實驗或者是使用過類似成型 的專案,所以在實踐性方面是有保障的,至於在具體實施過程中,可以按照具體的應用和專案進行選擇性處理,這樣,讓你的網站速度飛快,使用者體驗一流。同時本 文有些概念和描述不一定準確,如果有不足之處,請諒解並且提出來,不勝感謝。另外,如果有更好的方案或者更完善的解決方式,非常希望能夠分享一下,本文更 希望起到拋磚引玉的作用。

相關問題答案