1. 程式人生 > >大資料高併發之-Mysql分表與分庫使用場景以及設計方式

大資料高併發之-Mysql分表與分庫使用場景以及設計方式

場景:對於大型的網際網路應用來說,資料庫單表的記錄行數可能達到千萬級甚至是億級,並且資料庫面臨著極高的併發訪問。採用Master-Slave複製模式的MySQL架構,
只能夠對資料庫的讀進行擴充套件,而對資料庫的寫入操作還是集中在Master上,並且單個Master掛載的Slave也不可能無限制多,Slave的數量受到Master能力和負載的限制。
對於訪問極為頻繁且資料量巨大的單表來說,我們首先要做的就是減少單表的記錄條數,以便減少資料查詢所需要的時間,提高資料庫的吞吐,這就是所謂的分表!

一. 分表
在分表之前,首先需要選擇適當的分表策略,使得資料能夠較為均衡地分不到多張表中,並且不影響正常的查詢!
對於網際網路企業來說,大部分資料都是與使用者關聯的,因此,使用者id是最常用的分表字段。因為大部分查詢都需要帶上使用者id,這樣既不影響查詢,又能夠使資料較為均衡地
分佈到各個表中(當然,有的場景也可能會出現冷熱資料分佈不均衡的情況),如下圖:
分表操作


假設有一張表記錄用戶購買資訊的訂單表order,由於order表記錄條數太多,將被拆分成256張表。
拆分的記錄根據user_id%256取得對應的表進行儲存,前臺應用則根據對應的user_id%256,找到對應訂單儲存的表進行訪問。
這樣一來,user_id便成為一個必需的查詢條件,否則將會由於無法定位資料儲存的表而無法對資料進行訪問。
注:拆分後表的數量一般為2的n次方,就是上面拆分成256張表的由來!
假設order表結構如下:
在這裡插入圖片描述
那麼分表以後,假設user_id = 257,並且auction_id = 100,需要根據auction_id來查詢對應的訂單資訊,則對應的SQL語句如下:
在這裡插入圖片描述

其中,order_1是根據257%256計算得出,表示分表之後的第一張order表。
二. 分庫
場景:分表能夠解決單表資料量過大帶來的查詢效率下降的問題,但是,卻無法給資料庫的併發處理能力帶來質的提升。面對高併發的讀寫訪問,當資料庫master
伺服器無法承載寫操作壓力時,不管如何擴充套件slave伺服器,此時都沒有意義了。
因此,我們必須換一種思路,對資料庫進行拆分,從而提高資料庫寫入能力,這就是所謂的分庫!
與分表策略相似,分庫可以採用通過一個關鍵字取模的方式,來對資料訪問進行路由,如下圖所示:
在這裡插入圖片描述
還是之前的訂單表,假設user_id 欄位的值為258,將原有的單庫分為256個庫,那麼應用程式對資料庫的訪問請求將被路由到第二個庫(258%256 = 2)。

三. 分庫分表
場景:有時資料庫可能既面臨著高併發訪問的壓力,又需要面對海量資料的儲存問題,這時需要對資料庫既採用分表策略,又採用分庫策略,以便同時擴充套件系統的
併發處理能力,以及提升單表的查詢效能,這就是所謂的分庫分表。
分庫分表的策略比前面的僅分庫或者僅分表的策略要更為複雜,一種分庫分表的路由策略如下:
1. 中間變數 = user_id % (分庫數量 * 每個庫的表數量)
2. 庫 = 取整數 (中間變數 / 每個庫的表數量)
3. 表 = 中間變數 % 每個庫的表數量
同樣採用user_id作為路由欄位,首先使用user_id 對庫數量*每個庫表的數量取模,得到一箇中間變數;然後使用中間變數除以每個庫表的數量,取整,便得到
對應的庫;而中間變數對每個庫表的數量取模,即得到對應的表。
分庫分表策略詳細過程如下:
假設將原來的單庫單表order拆分成256個庫,每個庫包含1024個表,那麼按照前面所提到的路由策略,對於user_id=262145 的訪問,路由的計算過程如下:

  1. 中間變數 = 262145 % (256 * 1024) = 1
  2. 庫 = 取整 (1/1024) = 0
  3. 表 = 1 % 1024 = 1
    這就意味著,對於user_id=262145 的訂單記錄的查詢和修改,將被路由到第0個庫的第1個order_1表中執行!!!