MySQL-分库分表初探
文章目錄
- 生猛干貨
- 官方文檔
- 主從復制 解決不了 主節點DB寫的的壓力
- 常見的分庫分表的方式
- 分庫
- 分表
- DB分片前的準備
- 如何選擇分區鍵 ,盡量避免跨分片查詢
- 如何存儲無需分片的表
- 如何在節點上部署分片
- 如何分配分片中的數據
- 如何生成全局唯一ID
- 使用oneProxyp 分庫分表演示
- 目標效果
- oneProxyp
- 簡介
- 下載安裝使用
- 搞定MySQL
生猛干貨
帶你搞定MySQL實戰,輕松對應海量業務處理及高并發需求,從容應對大場面試
官方文檔
https://dev.mysql.com/doc/
如果英文不好的話,可以參考 searchdoc 翻譯的中文版本
http://www.searchdoc.cn/rdbms/mysql/dev.mysql.com/doc/refman/5.7/en/index.com.coder114.cn.html
主從復制 解決不了 主節點DB寫的的壓力
我們前面的 主從復制 構建的高可用的架構中,主要解決的是 主節點 讀的壓力。 (通常情況下,一個系統中的讀請求占據絕大部分)
那主節點的 寫請求呢? — 主從復制高可用架構解決不了了。。。。。
當然了,你可以增加硬件配置,這里我們不討論。我們這里要討論的是 通過分庫分表 來解決 主節點 寫的壓力。
常見的分庫分表的方式
有個MySQL的集群哈
分庫
兩種方式,如下
-
方式一: 把一個實例中的多個數據庫拆分到不同的實例
假設我們是個電商系統, DB集群中有 訂單、用戶、促銷 三個數據庫。
當然了,如果你的情況是: 訂單節點的寫入壓力比較大,你這樣拆也解決不了問題。
那就需要第二種方式了
- 方式二: 把一個庫中的表分離到不同的數據庫中 。
原來寫的壓力 都在 一個節點上,這樣才到不同的數據庫上,原來一個節點的寫壓力,就被分散到了3個節點上。
如果 隨著業務的發展,訂單的DB 寫壓力 又扛不住了呢? -----------> 那只有終極大招-----> 分表
分表
分表 : 就是對一個庫中的相關表 進行水平拆分到不同實例的數據庫中。
這一塊很復雜,坑太多。。。。。 一句話,能不分就不分。
舉個訂單的表的分表后的例子。
DB分片前的準備
如何選擇分區鍵 ,盡量避免跨分片查詢
-
分區鍵要能盡量避免跨分片查詢的發生 ,
舉個例子,博客系統 ,如果我們按照博客id hash進行分片,那么這個blog_id 會分配到各個節點上,那么查詢某個用戶的博客, 不得不去所有的數據庫上去查詢。 但如果按照user_id分呢? 那只要查詢一個數據庫就可以了。 就避免了跨分區的查詢
-
分區鍵要盡可能的使各個分配片中數據平均
分片的目的,是為了降低數據庫的寫負載,如果分片不均勻,大部分數據都寫到一個節點上了,這個節點很累,其他節點閑的沒事兒,那么這個分片還有啥意義???
比較好的方式,如果 分完以后,你的查詢能包含這個分區鍵,那就非常好了。
如何存儲無需分片的表
一個庫中,大部分的表,是沒有必要分片的,只有幾個寫入非常頻繁的表,才需要分片。
那不用分片的如何存儲呢?
-
每個分片中存儲一份相同的數據
這種方法通常用于: 表本身數據量不大,而且不怎么變更的表,比如字典表。 查詢也經常關聯這種表,每個分片都有的話,這樣的話 就不用跨分片查詢了,提高查詢效率。
當然了,缺點要維護多個分片的一致性,避免不一致導致查詢出錯。
-
使用額外的節點統一存儲
需要查詢的話,由應用來分別查詢,然后組合了。 效率不如第一種,但好在不用去維護數據一致性。
如何在節點上部署分片
-
方式一: 每個分片使用單一的數據庫,并且數據庫名也相同
-
方式二: 將多個分片表存儲在一個數據庫中,并在表名上加入分片號后綴
這個是對表進行編號 -
方式三: 在一個節點中部署多個數據庫,每個數據庫包含一個分片
這個是對數據庫進行編號
-
其他方式。。。。
如何分配分片中的數據
數據如何分布,對查詢的性能,影響很大。
這個平均包括 : 數據分部平均,第二 并發訪問也要平均
-
方式一: 按照分區鍵的hash值取模來分配分片數據
先hash再取模, 并不是所有的分區鍵都是數字,所以最好hash一下
如果是自增id為主鍵,也可以不用hash, 直接取模就行。
舉個例子 10個分片, 101 這個該存在哪個分片呢 ?
101 % 10 = 1 ----> 第一個分分片 。
-
方式二: 按照分區鍵的范圍來分配數據
舉個例子 10個分片 ,第一個分片存 1 - 100 ,第二個 101 -199 依次類推
那101 放哪里呢 ----> 第二個分片
常用于 分區鍵為 日期類型或者數值類型的場景。
優點: 很容易知道放哪里
缺點: 容易造成數據的分配不平均 ,從而導致訪問也不平均。比如一個 在線題庫,以 課程id作為分區鍵來分區, 但是Java這個課,大家都愛選這個,導致運行一段時間后,java課程的那個分片,壓力特別大,所以前期設計要充分考量。
-
方式三:利用分區鍵和分片的映射表來分配分片數據
使用第三種方式,方便控制
需要建立一張 分區鍵和分片的映射表, 先通過查詢映射表 來查詢具體的分區。
這個表的壓力比較大, 記得做緩存。
如何生成全局唯一ID
這個可能是最關鍵的了
-
方式一: 單節點的話,可以采用auto_increament_increament和 auto_increament_offset 參數
-
方式二: 分片的話 ,也可以用 可以采用auto_increament_increament和 auto_increament_offset 參數
auto_increament_increament 和 分片數目相同
比如 6個節點, auto_increament_increament 就要設置為6 ,auto_increament_offset 分別設置為 1到 6 ,每個節點相同表的自增id ,不沖突。
但這個只適用于 一個節點 只有一套分片表的情況。
-
方式二:全局節點
弄個全局表 ,但這個表有可能成為瓶頸,所以引入第三種
-
方式三: 使用redis代替全局節點,Redis緩存服務器中創建全局ID
-
其他方式。。。。
使用oneProxyp 分庫分表演示
目標效果
解釋下
原來在一個節點中存儲了 訂單表 + 訂單商品表 + 分類表
經過分庫分表后
兩個節點
節點1 : 存儲 訂單表 01 + 訂單商品表 01 + 分類表 (每個節點數據一致,冗余)
節點1 : 存儲 訂單表 02 + 訂單商品表 02 + 分類表 (每個節點數據一致,冗余)
oneProxyp
簡介
OneProxy 中間件是具備透明讀寫分離、分庫分表功能的數據庫中間件,輕松構建分布式數據庫集群,支持Oracle/MySQL等多種數據庫
下載安裝使用
帶后續使用的話補充,這里有個思路即可。
鏈接:https://pan.baidu.com/s/15kdQ-Q2u1sT063A-Qa2tdg
提取碼:pbp9
搞定MySQL
總結
以上是生活随笔為你收集整理的MySQL-分库分表初探的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL-count(*) 和 not
- 下一篇: MySQL-数据库监控初探