資料庫的垂直拆分和水平拆分
當我們使用讀寫分離、快取後,資料庫的壓力還是很大的時候,這就需要使用到資料庫拆分了。
資料庫拆分簡單來說,就是指通過某種特定的條件,按照某個維度,將我們存放在同一個資料庫中的資料分散存放到多個數據庫(主機)上面以達到分散單庫(主機)負載的效果。
切分模式: 垂直(縱向)拆分、水平拆分。
垂直拆分
專庫專用
一個數據庫由很多表的構成,每個表對應著不同的業務,垂直切分是指按照業務將表進行分類,分佈到不同的資料庫上面,這樣也就將資料或者說壓力分擔到不同的庫上面,如下圖:
優點:
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:按省份區縣地區列舉
資料分配不一定均勻