本文來自朋友圈算法
數據庫架構通常從簡單到複雜的過程數據庫
一、一主一從
由一臺主庫和一臺從庫組成,從庫只用做備份和容災,當主庫出現故障時,從庫就手動變成主庫
隨着壓力的增長,加上了memcached緩存
二、一主多從
經過添加多個從庫來分流查詢壓力服務器
三、隨着數據量的增長,讀寫壓力都迅速增長,架構
進行數據庫拆分,將數據存放到不一樣的數據庫服務器中memcached
數據庫拆分
通常能夠按兩個緯度來拆分數據:
(1)垂直拆分
按功能模塊拆分,多個數據庫之間的表結構不一樣
(2)水平拆分
將同一個表的數據進行分塊保存到不一樣的數據庫中,數據庫中的表結構相同性能
拆分規則
常見的拆分方式是對錶中某列值的範圍或者hash值拆分,好比ID在0-10000之間的用戶對應到數據庫A,ID在10000-20000這個範圍的對應到數據庫B
這種方法實現起來比較方便高效,可是不能知足後續的伸縮性要求,若是須要增長數據庫節點,必需調整算法或移動很大的數據集,比較難作到在不中止服務的前提下進行擴充數據庫節點索引
採用的拆分方法有:映射表
這種方法是指創建一個索引表,保存每一個用戶ID和數據庫ID的對應關係,每次讀寫用戶數據時先從這個表獲取對應數據庫,新用戶註冊後,在全部可用的數據庫中隨機挑選一個爲其創建索引
把索引表進行緩存,提升檢索性能事務
數據遷移
若是須要平衡各個節點的壓力,須要進行數據的遷移
例如要遷移用戶A的數據
(1)將A狀態置爲遷移數據中,這個狀態的用戶不能進行寫操做,並在頁面上進行提示
(2)而後將用戶A的數據所有複製到新增長的節點上
(3)更新映射表
(4)將用戶A的狀態置爲正常
(5)將原數據庫上的數據刪除hash
數據訪問過程
拆分帶來的問題(1)跨庫關聯查詢若是須要查詢的數據分佈於不一樣的數據庫,不便於經過JOIN的方式查詢得到好比要得到好友的最新照片,不能保證全部好友的數據都在同一個數據庫裏,須要經過屢次查詢,再進行聚合有些需求能夠經過保存多份數據來解決,例如用戶A、用戶B的數據庫分別是DB一、DB2,當A評論了B做品時先在B所在DB2中photo_comments表插入記錄,記錄B的哪一個做品被誰評論了什麼內容而後在A所在DB1中user_comments表插入記錄,記錄A給哪一個做者的哪一個做品發表過評論這樣能夠經過photo_comments獲得B的某張照片的全部評論,也能夠經過user_comments得到A發佈過的全部評論(2)不能保證數據的一致/完整性跨庫的數據沒有外鍵約束,也沒有事務保證,好比上面評論照片的例子,極可能出現成功插入photo_comments表,可是插入user_comments表時卻出錯了能夠在兩個庫上都開啓事務,而後先插入photo_comments,再插入user_comments,而後提交兩個事務,但不能徹底保證這個操做的原子性(3)自增ID增長了一個專門用來生成ID的數據庫,表結構很簡單,只有一個自增字段id例如要插入評論時,先在ID庫的photo_comments表裏插入一條空的記錄,以得到一個惟一的評論ID按期清理ID庫的數據,以保證獲取新ID的效率