當數據庫性能出現問題的時候,首先須要找出瓶頸,是否進行了必要的優化,如:表和字段是否建的合理,索引是否建的好,sql語句有無優化等等。mysql
隨着站點規模愈來愈大,數據庫壓力愈來愈大,即便作了優化也還會出現性能問題,這時咱們就須要對數據庫進行擴展解決性能問題。算法
數據庫擴展的幾種方式: 經常使用方法sql
注:有些人習慣把分片稱做分區,分區能夠分爲兩種,邏輯分區和物理分區(分片),請參考:戳這裏數據庫
數據拆分經常使用算法:服務器
###** 分區(Partition)** 這裏的分區是指邏輯分區(Partition),MySql 有Range,List,Hash,Key 分區方法:戳這裏分佈式
當單表數據超過必定量時,r\w會變得很慢,read須要遍歷大量數據,write須要時間創建索引;咱們能夠經過把這些數據分散到多個表中來提升效率,這樣只涉及到部分數據而不是全部,最經常使用的分表方式應該是哈希。性能
注:分表或分區後咱們就不能用數據庫自增id啦~優化
例如:創建所須要的N個表,表名:user_0 ... user_N-1加密
經過id進行哈希算法找到該id所在表名:.net
小結:邏輯分區是數據庫提供的功能,不用對應用和業務作任何改變就能實現。哈希分表實現簡單,只須要修改少許代碼就能實現。對單表進行分表後,可以大大提升咱們讀寫的效率。
讀寫分離須要配置主從複製來實現,sql到達主仍是從能夠本身寫code,也能夠用代理:mysql proxy
通常站點的讀操做比寫操做更加密集,查詢量暴增的時候單臺服務器沒法處理這麼多讀操做,咱們須要增長額外的服務器來支撐,使用主從方式,主作寫操做,從作讀操做,經過主從複製達到數據一致性,這樣讀操做壓力會被分散。mysql使用單線程把主機數據複製到從機上實現數據一致性,因此須要對主從進行配置。
小結:使用讀寫分離後,很容易經過增長服務器來提升讀性能,還能夠對主從服務器作高可用。(作主從以前咱們還能夠嘗試使用cache來提升讀性能)
##分區或分片(Share Nothing)
對於寫操做頻繁的站點來講,使用主從複製和讀寫分離效果並不明顯,好比主服務器80%的時間都在寫數據,那麼也將花費更多的時間來同步數據,也會形成數據延遲的發生,而select查詢只有20%時間處理,這時候增長從服務器也是沒有效果的。對寫操做這麼頻繁的狀況,應該對寫操做也進行分散。
拆分原則通常是把有關聯關係的表拆分到一塊兒,這樣select join的時候不會跨節點。拆分以後,咱們繼續作讀寫分離:
對數據庫作了垂直切分和讀寫分離能夠解決大部分站點的問題,然而當主數據庫寫操做壓力再次達到極限,再次作垂直切分意義也不大了,還有可能會有反效果。
事實上,在考慮水平切分以前,咱們通常會對數據庫進行分表,它們思路是同樣的:
這種方案解決了問題的同時也帶來了其餘問題,增長了很大的複雜度,不只要改代碼,還須要在夜深人靜的夜晚,關閉站點,對數據進行計算和遷移,若是關閉時間太長或中間出了事故,用戶和老闆都會抱怨。若是在項目一開始就使用了分表,那麼再進行水平切分就很是容易了,由於數據已是切分好了的,因此有些業務能夠考慮在一開始就這麼作。
有時單一的擴展方式知足不了咱們的需求,能夠用多種方式進行組合。
##垂直分區+水平分區
##分片帶來的問題
分片優秀的中間件:mycat 國人開發,社區活躍
如不是必要,不要優先考慮分片策略,解決其帶來的問題耗時耗人力難度又大,可能得不償失。可使用優秀的數據庫中間件,難度也挺大的。
##總結 大多站點基本上都經歷了從簡單的讀寫分離到垂直分區,再到水平分區的過程,網上關於分區說的不少的一句話是「不要爲了分區而分區」,根據實際狀況選擇不一樣的解決方案纔是最明智的。垂直和水平分區,是一種數據規劃方式,能夠集中在一臺服務器上的多個庫中,也能夠是分散在多個服務器上的多個庫中。