資料庫架構的演變
轉載地址:http://www.cnblogs.com/aigongsi/archive/2012/11/23/2784773.html
總結一下資料庫架構演變及背後的思路。
單主機
最開始網站一般都是由典型的LAMP架構演變而來的,一般都是一臺linux主機,一臺apache伺服器,php執行環境以及mysql伺服器,一般情況下,這些都在一臺虛擬主機上,簡稱單主機模式。
單主機模式缺點:
1 web伺服器和mysql伺服器公用一臺主機,共享硬體資源,可能存在某一方資源徵用太大,導致整個應用產生瓶頸
2 當業務增長之後,沒有辦法做到橫向擴充套件。
3 容錯性太差,一旦主機存在問題,整個應用不可用
獨立主機
隨著業務的發展,可以把mysql伺服器和web伺服器主機分開,分別部署,就是獨立主機模式。獨立主機模式下,web伺服器和mysql不再共享硬體資源,分別部署。沒有把雞蛋放在一個籃子裡面,增加了容錯性。如果只是mysql伺服器故障,那麼對於web上不訪問伺服器的應用是不會受到影響的。而且web伺服器可以做到橫向擴充套件,如果web伺服器效能不夠,可以增加多臺web伺服器,進行負載均衡,分散web伺服器的壓力。
獨立主機模式的缺點:
1 可擴充套件性問題:雖然web伺服器可以做到橫向擴充套件,但是mysql伺服器是沒有辦法做到橫向擴充套件的。
2 可用性問題:mysql伺服器存在單點問題,一旦mysql伺服器宕機,對影響的影響很大
3 效能問題:單臺mysql伺服器能夠支撐的服務是有限的。
讀寫分離
隨著業務的不斷髮展,資料庫的壓力會越來越大,單資料庫慢慢的就不能滿足需求了,一些網站對資料實時性要求不高,就會慢慢發展讀寫分離模式,對於普通的查詢請求,分配到讀庫(也可以說是備庫),對於修改請求,在主庫上完成。對於讀庫,由於是無狀態的,可以做到橫向擴充套件。對於寫庫,還只能是單臺主機這種模式其實有限制的,要根據業務的型別來考慮。主庫的資料是最新的,但是同步到讀庫會有時延,所以應用必須能夠容忍短暫的不一致性。對於一致性要求非常高的場景是不適合的。
這種模式的存在的問題:
1 可擴充套件性:雖然讀庫可以做到橫向擴充套件,但是寫庫還不行
2 可用性:寫庫成為單點,一旦故障,影響所有的寫操作業務
業務垂直拆分
隨著業務的發展,一臺寫庫顯然不能夠滿足高併發的情況,但是考慮到寫庫是有狀態的,不能簡單的橫向擴充套件,假設有兩臺寫庫,那麼隨機更新一臺的資料,就會導致另一方資料存在問題。出現一種資料兩個不同版本,顯然是無法接受的。在寫庫上,可以考慮按照業務來垂直進行分庫。由於我們這裡討論的是資料庫架構,對於web層來說,其實也是可以按照業務垂直拆分的。在按照業務垂直拆分以後,系統在效能上有了很高的提升,只需要把業務上分成垂直部分,分的越細,系統的整體擴充套件能力就越強。
這種模式下,存在以下幾個問題
1 可用性:假設一個完整的業務流程P訪問的資料庫被拆分為A、B、C、D、E 五個庫,假設每個寫庫可用性為99%,那麼這個業務流程P的可用性就為99%*99%*99%*99%*99%=95%,庫拆分的越多,對系統的整體可用性挑戰就越大。
2 效能:由於垂直業務庫每個庫的負載可能不一樣,假設交易庫負載很高,一個交易寫庫肯定不能夠滿足需求,這個情況下,交易庫成為整個系統的瓶頸。
3 可擴充套件性:單個節點的可擴充套件性沒有得到改善,交易庫不能單獨進行擴充套件。
單業務庫水平、垂直拆分
在上一種情況,假設交易庫是整個系統的瓶頸,需要對交易庫進行單獨的擴充套件。可以考慮交易的水平拆分或者垂直拆分,有可能同時進行兩種方式拆分。
水平拆分一般根據業務無關的關鍵字進行拆分,橫向擴充套件性比較好,但是對於查詢的挑戰比較大
垂直拆分一般根據業務來拆分,但是可能導致資料不均勻以及拆分不夠靈活。對於查詢來說,相對比較友好
拿交易庫舉個例子,可以先交易的型別進行業務上的垂直分庫,在按照訂單號進行水平分庫。
假設可以分成M*N個庫,那麼單個庫的故障會影響1/M*N 的交易,但是假設每個庫可用性為99% ,那麼交易資料庫故障概率為 (99%)的(M+N)次方,如果資料庫拆分的越多,發生單個數據庫故障概率就越高。
這種方式存在的問題:
1 雖然單個節點故障影響的使用者很少,但是整體可用會降低。
2 資料庫管理上帶來複雜的挑戰,假設交易庫表結構變更,需要執行M×N次指令碼變更。
3 由於發生單個數據庫故障的概率比較高,dba會很苦逼的,估計經常性要救火
4 開發和測試起來會非常苦逼,開發和測試成本會變高,查詢非常複雜。
5 單個節點如果發生故障,沒有失敗檢測並且切換機制
6 分庫還不能在水平方向做到無限擴充套件,我們的演算法是事先分配M個庫,如果新增一個庫基本上不可行
隨機分庫
對於第六個問題,在水平方向的無線擴充套件,可以考慮一種機制,在insert資料的時候,申請一個數據庫編號,然後把資料庫的編號作為一個欄位儲存或者在把這個編號新增到已經欄位上。
例如假設我們申請insert資料庫,得到一個數據庫編號為1000,那麼我們可以構造出來一個訂單號為1000_tradeno,訂單號前面是分庫編號,訂單號後面是實際tradeno,這樣解決了水平無線擴充套件的問題。這種就是隨機分庫模式。但是這一種方式的侷限性很大,
隨機分庫的缺點:
1 分庫演算法和業務耦合在一起,比較適合特定的場景,適用範圍比較窄
2 對於insert操作,比較容易,對於update操作,必須有分庫編號,也就是說,只能根據特定的欄位來進行更新
3 不適合批量查詢的場景,查詢功能限制比較大,這也是分庫帶來的問題
單資料庫備份以及失敗切換
對於單個數據庫,如果發生故障,會影響業務,但是能否在發生故障的時候進行切換。雖然可以實現,但是會存在一定的問題,需要特定場景進行特定的分析。這一塊比較複雜,說起來可以在寫一篇文章,就簡單的介紹一下
以上就是總結的資料庫的架構演變,資料庫的演變需要很多基礎技術做支撐,主要包括
1 強大的分散式資料庫的管理中介軟體,主要遮蔽底層的資料庫路由以及資料管理功能
2 強大的資料運維團隊以及監控體系,能夠檢測出每個節點的資料庫狀態
3 強大的資料庫管理管理團隊,能夠維護這麼的資料庫叢集
4 強大的業務架構能力和技術架構能力,能夠掌控這麼複雜的業務場景。