數據庫垂直拆分 水平拆分

        當咱們使用讀寫分離、緩存後,數據庫的壓力仍是很大的時候,這就須要使用到數據庫拆分了。
        
        數據庫拆分簡單來講,就是指經過某種特定的條件,按照某個維度,將咱們存放在同一個數據庫中的數據分散存放到多個數據庫(主機)上面以達到分散單庫(主機)負載的效果。 
 
        切分模式: 垂直(縱向)拆分、水平拆分。
 
垂直拆分
 
        專庫專用
 
        一個數據庫由不少表的構成,每一個表對應着不一樣的業務,垂直切分是指 按照業務將表進行分類,分佈到不一樣的數據庫上面,這樣也就將數據或者說壓力分擔到不一樣的庫上面,以下圖:
        
優勢:
        1. 拆分後業務清晰,拆分規則明確。
        2. 系統之間整合或擴展容易。
        3. 數據維護簡單。
 
缺點:
        1. 部分業務表沒法join,只能經過接口方式解決,提升了系統複雜度。
        2. 受每種業務不一樣的限制存在單庫性能瓶頸,不易數據擴展跟性能提升。
        3. 事務處理複雜。
 
水平拆分
 
        垂直拆分後遇到單機瓶頸,可使用水平拆分。相對於垂直拆分的區別是:垂直拆分是把不一樣的表拆到不一樣的數據庫中,而水平拆分是把同一個表拆到不一樣的數據庫中。
 
         相對於垂直拆分,水平拆分不是將表的數據作分類,而是按照某個字段的某種規則來分散到多個庫之中,每一個表中包含一部分數據。簡單來講,咱們能夠將數據的水平切分理解爲是按照數據行的切分,就是將表中 的某些行切分到一個數據庫,而另外的某些行又切分到其餘的數據庫中,主要有分表,分庫兩種模式,如圖:
                 
 
        
優勢:
        1. 不存在單庫大數據,高併發的性能瓶頸。
        2. 對應用透明,應用端改造較少。     
        3. 按照合理拆分規則拆分,join操做基本避免跨庫。
        4. 提升了系統的穩定性跟負載能力。
 
缺點:
        1.  拆分規則難以抽象。
        2. 分片 事務一致性難以解決。
        3. 數據屢次擴展難度跟維護量極大。
        4. 跨庫join性能較差。
 
拆分的處理難點
 
兩張方式共同缺點
 
        1. 引入分佈式事務的問題。
        2. 跨節點Join 的問題。
        3. 跨節點合併排序分頁問題。
 
針對數據源管理,目前主要有兩種思路:
 
        A. 客戶端模式,在每一個應用程序模塊中配置管理本身須要的一個(或者多個)數據源,直接訪問各個 數據庫,在模塊內完成數據的整合。 
        優勢:相對簡單,無性能損耗。   
        缺點:不夠通用,數據庫鏈接的處理複雜,對業務不夠透明,處理複雜。
 
       B. 經過 中間代理層來統一管理全部的數據源,後端數據庫集羣對前端應用程序透明;   
        優勢:通用,對應用透明,改造少。   
        缺點:實現難度大,有二次轉發性能損失。
 
拆分原則
    
        1. 儘可能不拆分,架構是進化而來,不是一蹴而就。(SOA)
        2. 最大可能的找到最合適的切分維度。
        3. 因爲數據庫中間件對數據Join 實現的優劣難以把握,並且實現高性能難度極大,業務讀取  儘可能少使用多表Join -儘可能經過數據冗餘,分組避免數據垮庫多表join。
        4. 儘可能避免分佈式事務。
        5. 單表拆分到數據1000萬之內。
 
切分方案
    
        範圍、枚舉、時間、取模、哈希、指定等
 
案例分析
 
場景一
創建一個歷史his系統,將公司的一些歷史我的遊戲數據保存到這個his系統中,主要是寫入,還有部分查詢,讀寫比約爲1:4;因爲是全部數據的歷史存取,因此併發要求比較高; 
 
分析:
歷史數據
寫多都少
越近日期查詢越頻繁?
什麼業務數據?用戶遊戲數據
有沒有大規模分析查詢?
數據量多大?
保留多久?
機器資源有多少?
 
方案1:按照日期每個月一個分片
帶來的問題:1.數據熱點問題(壓力不均勻)
 
方案2:按照用戶取模,  --by Jerome 就這個比較合適了
帶來的問題:後續擴容困難
 
方案3:按用戶ID範圍分片(1-1000萬=分片1,xxx)
帶來的問題:用戶活躍度沒法掌握,可能存在熱點問題
 
場景二
創建一個商城訂單系統,保存用戶訂單信息。
 
分析:
電商系統
一號店或京東類?淘寶或天貓?
實時性要求高
存在瞬時壓力
基本不存在大規模分析
數據規模?
機器資源有多少?
維度?商品?用戶?商戶?
 
方案1:按照用戶取模,
帶來的問題:後續擴容困難
 
方案2:按用戶ID範圍分片(1-1000萬=分片1,xxx)
帶來的問題:用戶活躍度沒法掌握,可能存在熱點問題
 
方案3:按省份地區或者商戶取模
數據分配不必定均勻
 
場景3
上海公積金,養老金,社保系統
 
分析:
社保系統
實時性要求不高
不存在瞬時壓力
大規模分析?
數據規模大
數據重要不可丟失
偏於查詢?
 
方案1:按照用戶取模,
帶來的問題:後續擴容困難
 
方案2:按用戶ID範圍分片(1-1000萬=分片1,xxx)
帶來的問題:用戶活躍度沒法掌握,可能存在熱點問題
 
方案3:按省份區縣地區枚舉
數據分配不必定均勻
 
 
 
        數據庫問題解決後,應用面對的新挑戰就是拆分應用等
 

參考
        Mycat在線視頻培訓【連接: http://pan.baidu.com/s/1nuR26rZ 密碼:1gr9 (2015)】
         大型網站系統與Java中間件實踐.pdf
 
 
垂直拆分
  垂直拆分就是要把表按模塊劃分到不一樣 數據庫表中(固然原則仍是不破壞第三範式),這種拆分在大型網站的演變過程當中是很常見的。當一個網站還在很小的時候,只有小量的人來開發和維護,各模塊和表都在一塊兒,當網站不斷豐富和壯大的時候,也會變成多個子系統來支撐,這時就有按模塊和功能把表劃分出來的需求。其實,相對於垂直切分更進一步的是服務化改造,說得簡單就是要把原來強耦合的系統拆分紅多個弱耦合的服務,經過服務間的調用來知足業務需求看,所以表拆出來後要經過服務的形式暴露出去,而不是直接調用不一樣模塊的表,淘寶在架構不斷演變過程,最重要的一環就是服務化改造,把用戶、交易、店鋪、寶貝這些核心的概念抽取成獨立的服務,也很是有利於進行局部的優化和治理,保障核心模塊的穩定性
  垂直拆分:單表大數據量依然存在性能瓶頸
   水平拆分
  上面談到垂直切分只是把表按模塊劃分到不一樣數據庫,但沒有解決單表大數據量的問題,而水平切分就是要把一個表按照某種規則把數據劃分到不一樣表或數據庫裏。例如像計費系統,經過按時間來劃分表就比較合適,由於系統都是處理某一時間段的數據。而像SaaS應用,經過按用戶維度來劃分數據比較合適,由於用戶與用戶之間的隔離的,通常不存在處理多個用戶數據的狀況,簡單的按user_id範圍來水平切分
  通俗理解:水平拆分行,行數據拆分到不一樣表中, 垂直拆分列,表數據拆分到不一樣表中
   垂直與水平聯合切分
  由上面可知垂直切分能更清晰化模塊劃分,區分治理,水平切分能解決大數據量性能瓶頸問題,所以經常就會把二者結合使用,這在大型網站裏是種常見的策略
  案例:
  以mysql爲例,簡單購物系統暫設涉及以下表:
  1.產品表(數據量10w,穩定)
  2.訂單表(數據量200w,且有增加趨勢)
  3.用戶表 (數據量100w,且有增加趨勢)
  以mysql爲例講述下水平拆分和垂直拆分,mysql能容忍的數量級在百萬靜態數據能夠到千萬
   垂直拆分:
  解決問題:
  表與表之間的io競爭
  不解決問題:
  單表中數據量增加出現的壓力
  方案:
  把產品表和用戶表放到一個 server
  訂單表單獨放到一個server上
   水平拆分:
  解決問題:
  單表中數據量增加出現的壓力
  不解決問題:
  表與表之間的io爭奪
  方案:
  用戶表經過性別拆分爲男用戶表和女用戶表
  訂單表經過已完成和完成中拆分爲已完成訂單和未完成訂單
  產品表 未完成訂單放一個server上
  已完成訂單表盒男用戶表放一個server上
  女用戶表放一個server上(女的愛購物)
 
 
 
 

《大型網站系統與Java中間件實踐》本書圍繞大型網站和支撐大型網站架構的 Java 中間件的實踐展開介紹。從分佈式系統的知識切入,讓讀者對分佈式系統有基本的瞭解;而後介紹大型網站隨着數據量、訪問量增加而發生的架構變遷;接着講述構建 Java 中間件的相關知識;以後的幾章都是根據筆者的經驗來介紹支撐大型網站架構的 Java 中間件系統的設計和實踐。本節爲你們介紹專庫專用,數據垂直拆分。php

AD:
51CTO 網+ 第十二期沙龍:大話數據之美_如何用數據驅動用戶體驗 html

2.2.7 讀寫分離後,數據庫又遇到瓶頸前端

經過讀寫分離以及在某些場景用分佈式存儲系統替換關係型數據庫的方式,可以下降主庫的壓力,解決數據存儲方面的問題。不過隨着業務的發展,咱們的主庫也會遇到瓶頸。咱們的網站演進到如今,交易、商品、用戶的數據還都在一個數據庫中。儘管採起了增長緩存、讀寫分離的方式,這個數據庫的壓力仍是在繼續增長,所以咱們須要去解決這個問題,咱們有數據垂直拆分和水平拆分兩種選擇。mysql

2.2.7.1 專庫專用,數據垂直拆分sql

垂直拆分的意思是把數據庫中不一樣的業務數據拆分到不一樣的數據庫中。結合如今的例子,就是把交易、商品、用戶的數據分開,如圖2-20 所示。數據庫

 

 

這樣的變化給咱們帶來的影響是什麼呢?應用須要配置多個數據源,這就增長了所需的配置,不過帶來的是每一個數據庫鏈接池的隔離。不一樣業務的數據從原來的一個數據庫中拆分到了多個數據庫中,那麼就須要考慮如何處理原來單機中跨業務的事務。一種辦法是使用分佈式事務,其性能要明顯低於以前的單機事務;而另外一種辦法就是去掉事務或者不去追求強事務支持,則原來在單庫中可使用的表關聯的查詢也就須要改變實現了。後端

對數據進行垂直拆分以後,解決了把全部業務數據放在一個數據庫中的壓力問題。而且也能夠根據不一樣業務的特色進行更多優化。瀏覽器

 

2.2.7.2 垂直拆分後的單機遇到瓶頸,數據水平拆分緩存

與數據垂直拆分對應的還有數據水平拆分。數據水平拆分就是把同一個表的數據拆到兩個數據庫中。產生數據水平拆分的緣由是某個業務的數據表的數據量或者更新量達到了單個數據庫的瓶頸,這時就能夠把這個表拆到兩個或者多個數據庫中。數據水平拆分與讀寫分離的區別是,讀寫分離解決的是讀壓力大的問題,對於數據量大或者更新量的狀況並不起做用。數據水平拆分與數據垂直拆分的區別是,垂直拆分是把不一樣的表拆到不一樣的數據庫中,而水平拆分是把同一個表拆到不一樣的數據庫中。例如,通過垂直拆分後,用戶表與交易表、商品表不在一個數據庫中了,若是數據量或者更新量太大,咱們能夠進一步把用戶表拆分到兩個數據庫中,它們擁有結構如出一轍的用戶表,並且每一個庫中的用戶表都只涵蓋了一部分的用戶,兩個數據庫的用戶合在一塊兒就至關於沒有拆分以前的用戶表。咱們先來簡單看一下引入數據水平拆分後的結構,如圖2-21 所示。服務器

咱們來分析一下水平拆分後給業務應用帶來的影響。

首先,訪問用戶信息的應用系統須要解決SQL 路由的問題,由於如今用戶信息分在了兩個數據庫中,須要在進行數據庫操做時瞭解須要操做的數據在哪裏。

此外,主鍵的處理也會變得不一樣。原來依賴單個數據庫的一些機制須要變化,例如原來使用Oracle 的Sequence 或者MySQL 表上的自增字段的,如今不能簡單地繼續使用了。而且在不一樣的數據庫中也不能直接使用一些數據庫的限制來保證主鍵不重複了。

 

 

最後,因爲同一個業務的數據被拆分到了不一樣的數據庫中,所以一些查詢須要從兩個數據庫中取數據,若是數據量太大而須要分頁,就會比較難處理了。

不過,一旦咱們可以完成數據的水平拆分,咱們將可以很好地應對數據量及寫入量增加的狀況。具體如何完成數據水平拆分,在後面分布式數據訪問層的章節中咱們將進行更加詳細的介紹。

 

2.2.8 數據庫問題解決後,應用面對的新挑戰

2.2.8.1 拆分應用

前面所講的讀寫分離、分佈式存儲、數據垂直拆分和數據水平拆分都是在解決數據方面的問題。下面咱們來看看應用方面的變化。

以前解決了應用服務器從單機到多機的擴展,應用就能夠在必定範圍內水平擴展了。隨着業務的發展,應用的功能會愈來愈多,應用也會愈來愈大。咱們須要考慮如何不讓應用持續變大,這就須要把應用拆開,從一個應用變爲兩個甚至多個應用。咱們來看兩種方式。

第一種方式,根據業務的特性把應用拆開。在咱們的例子中,主要的業務功能分爲三大部分:交易、商品和用戶。咱們能夠把原來的一個應用拆成分別以交易和商品爲主的兩個應用,對於交易和商品都會有涉及用戶的地方,咱們讓這兩個系統本身完成涉及用戶的工做,而相似用戶註冊、登陸等基礎的用戶工做,能夠暫時交給兩系統之一來完成(注意,咱們在這裏主要是經過例子說明拆分的作法),如圖2-22 所示,這樣的拆分可使大的應用變小。

 

 

咱們還能夠按照用戶註冊、用戶登陸、用戶信息維護等再拆分,使之變成三個系統。不過,這樣拆分後在不一樣系統中會有一些類似的代碼,例如用戶相關的代碼。如何可以保證這部分代碼的一致以及如何對其複用是須要解決的問題。此外,按這樣的方式拆分出來的新系統之間通常沒有直接的相互調用。並且,新拆出來的應用可能會鏈接一樣的數據庫。

來看一個具體的例子,如圖2-23 所示。

咱們根據業務的不一樣功能拆分了幾個業務應用,並且這些業務應用之間不存在直接的調用,它們都依賴底層的數據庫、緩存、文件系統、搜索等。這樣的應用拆分確實可以解決當下的一些問題,不過也有一些缺點。  

 

 

2.2.8.2 走服務化的路

咱們再來看一下服務化的作法。圖2-24 是一個示意圖。從中能夠看到咱們把應用分爲了三層,處於最上端的是Web 系統,用於完成不一樣的業務功能;處於中間的是一些服務中心,不一樣的服務中心提供不一樣的業務服務;處於下層的則是業務的數據庫。固然,咱們在這個圖中省去了緩存等基礎的系統,所以能夠說是服務化系統結構的一個簡圖。

 

 

圖2-24 與以前的圖相比有幾個很重要的變化。首先,業務功能之間的訪問不只是單機內部的方法調用了,還引入了遠程的服務調用。其次,共享的代碼再也不是散落在不一樣的應用中了,這些實現被放在了各個服務中心。第三,數據庫的鏈接也發生了一些變化,咱們把與數據庫的交互工做放到了服務中心,讓前端的Web 應用更加註重與瀏覽器交互的工做,而沒必要過多關注業務邏輯的事情。鏈接數據庫的任務交給相應的業務服務中心了,這樣能夠下降數據庫的鏈接數。而服務中心不只把一些能夠共用的以前散落在各個業務的代碼集中了起來,而且可以使這些代碼獲得更好的維護。第四,經過服務化,不管是前端Web 應用仍是服務中心,均可以是由固定小團隊來維護的系統,這樣可以更好地保持穩定性,並能更好地控制系統自己的發展,何況穩定的服務中心平常發佈的次數也遠小於前端Web 應用,所以這個方式也減少了不穩定的風險。

要作到服務化還須要一些基礎組件的支撐,在後面服務框架的章節咱們會具體介紹。

 

 

經過某種特定的條件,將存放在同一個數據庫中的數據分散存放到多個數據庫上,實現分佈存儲,經過路由規則路由訪問特定的數據庫,這樣一來每次訪問面對的就不是單臺服務器了,而是N臺服務器,這樣就能夠下降單臺機器的負載壓力。提示:sqlserver 2005版本以後,能夠友好的支持「表分區」。

  垂直(縱向)拆分:是指按功能模塊拆分,好比分爲訂單庫、商品庫、用戶庫...這種方式多個數據庫之間的表結構不一樣。

  水平(橫向)拆分:將同一個表的數據進行分塊保存到不一樣的數據庫中,這些數據庫中的表結構徹底相同。

SQL Server:數據庫/數據表 拆分
▲(縱向拆分)

SQL Server:數據庫/數據表 拆分
▲(橫向拆分)

  1,實現原理:使用垂直拆分,主要要看應用類型是否合適這種拆分方式,如系統能夠分爲,訂單系統,商品管理系統,用戶管理系統業務系統比較明的,垂直拆分能很好的起到分散數據庫壓力的做用。業務模塊不明晰,耦合(表關聯)度比較高的系統不適合使用這種拆分方式。可是垂直拆分方式並不能完全解決全部壓力問題,例如 有一個5000w的訂單表,操做起來訂單庫的壓力仍然很大,如咱們須要在這個表中增長(insert)一條新的數據,insert完畢後,數據庫會針對這張表從新創建索引,5000w行數據創建索引的系統開銷仍是不容忽視的,反過來,假如咱們將這個表分紅100個table呢,從table_001一直到table_100,5000w行數據平均下來,每一個子表裏邊就只有50萬行數據,這時候咱們向一張只有50w行數據的table中insert數據後創建索引的時間就會呈數量級的降低,極大了提升了DB的運行時效率,提升了DB的併發量,這種拆分就是橫向拆分

  2,實現方法:垂直拆分,拆分方式實現起來比較簡單,根據表名訪問不一樣的數據庫就能夠了。橫向拆分的規則不少,這裏總結前人的幾點,

  (1)順序拆分:如能夠按訂單的日前按年份才分,2003年的放在db1中,2004年的db2,以此類推。固然也能夠按主鍵標準拆分。

  優勢:可部分遷移

  缺點:數據分佈不均,可能2003年的訂單有100W,2008年的有500W。

  (2)hash取模分: 對user_id進行hash(或者若是user_id是數值型的話直接使用user_id的值也可),而後用一個特定的數字,好比應用中須要將一個數據庫切分紅4個數據庫的話,咱們就用4這個數字對user_id的hash值進行取模運算,也就是user_id%4,這樣的話每次運算就有四種可能:結果爲1的時候對應DB1;結果爲2的時候對應DB2;結果爲3的時候對應DB3;結果爲0的時候對應DB4,這樣一來就很是均勻的將數據分配到4個DB中。

  優勢:數據分佈均勻

  缺點:數據遷移的時候麻煩;不能按照機器性能分攤數據 。

  (3)在認證庫中保存數據庫配置

  就是創建一個DB,這個DB單獨保存user_id到DB的映射關係,每次訪問數據庫的時候都要先查詢一次這個數據庫,以獲得具體的DB信息,而後才能進行咱們須要的查詢操做。

  優勢:靈活性強,一對一關係

  缺點:每次查詢以前都要多一次查詢,會形成必定的性能損失。

相關文章
相關標籤/搜索