1. 程式人生 > 程式設計 >不要為了“分庫分表”而“分庫分表”

不要為了“分庫分表”而“分庫分表”

為什麼要進行分庫分表?

當資料庫的資料量過大,大到一定的程度,我們就可以進行分庫分表。那麼基於什麼原則,什麼方法進行拆分,這就是本篇所要講的。

為什麼要進行分庫分表?當資料庫大到一定程度的時候,我們採用優化硬體,優化表的結構,這種方法還是無法滿足的時候,就要進行分庫分表。

分庫分表是什麼?

隨著公司的業務快速發展,資料庫中的資料量猛增,訪問效能也變慢了,優化迫在眉睫。

分析下問題出現哪裡呢?關係型資料本身就比較容易形成系統瓶頸,單機儲存容量,連線數,處理能力都有限。當單表的資料量達到1000W或100G以後,由於查詢維度較多,即使新增從庫,優化索引,做很多操作時效能還是下降嚴重。

方法一:

通過提升伺服器硬體能力來提高資料處理能力,比如增加儲存容量,CPU等,這種方案成本很高,並且如果瓶頸在MySQL本身,那麼提高硬體也是很有限的。


方法二:

將資料分散在不同的資料庫中,使得單一資料庫的資料量變小來緩解單一資料庫的效能問題,從而達到提升資料庫效能的目的。

比如,將電商的資料庫分為若干個獨立的資料庫,並且對於大表也拆分為若干小表,從而解決資料庫的效能問題。就跟把雞蛋放在多個籃子裡是一樣的。



所以,分庫分表就是為瞭解決由於資料量過大而導致資料庫效能降低的問題,將原來獨立的資料庫拆分為若干資料庫,將資料庫大表拆分成若干資料表,使得單一資料庫,單一資料表的資料量變小,從而達到提升資料庫效能的目的。

分庫分表的方式

我們將電商作為其背景,現在有三個表,分別是賣家表,商品表,店鋪表。

垂直分表

我們平時逛淘寶等電商網站時,搜尋列表的頁面顯示商品的關鍵資訊,而點進去的頁面顯示商品的詳情資訊。這個商品資訊大表所包含的欄位有很多,所以我們將商品資訊中常用的欄位歸為一個表,商品資訊中不常用的欄位歸為一個表。

垂直分表的定義:將一個表按照欄位分為多表,每個表裡面都儲存其中一部分欄位。

他帶來的提升是:

1.為了避免IO爭搶並減少鎖表的機率,檢視詳情的使用者與商品資訊瀏覽互不影響。

2.充分發揮熱門資料(商品的基礎資訊)的操作效率,商品資訊的操作的高效率不會被商品描述的低效率所拖累。

為什麼大欄位效率低,比如商品表的描述資訊?:第一是由於資料量本身大,需要更長的讀取時間;第二是跨頁,頁是資料庫儲存單位,很多查詢及定位操作都是以頁為單位,單頁內的資料行越多資料庫整體效能越好,而大欄位佔用空間大,單頁記憶體儲行數小,因此IO效率低;第三,資料庫以行為單位將資料載入到記憶體中,這樣表中欄位較短且訪問評率交到,記憶體能載入更多的資料,命中率更高,減少了磁碟IO,從而提升了資料庫效能。

一般來說,當表的資料量很大時,可以將表按欄位切開,將熱門欄位和冷門欄位分開,放在不同的表中,避免發生IO爭搶。

垂直分庫

通過垂直分表效能得到一定程度的提升,但是還沒有達到要求,並且磁碟空間已經不夠了,因為資料庫始終限制在一臺伺服器上,庫內的垂直分表只解決了單一表資料量過大的問題,單沒有將表分佈到不同的伺服器上,因此每個表還是競爭同一個物理機的CPU,記憶體,網路IO,磁碟等物理資源。

所以,我們可以將賣家表,商品表,店鋪表分在不同的伺服器中。

垂直分庫是指按照業務將表進行分類,分佈在不同的資料庫中,每個庫可以放在不同的伺服器上,他的核心就是專庫專用。複製程式碼

水平分庫

經過垂直分庫,資料庫效能問題得到一定程度的解決,但是隨著業務量的增長,商品單褲儲存資料已經超出預估。粗略估計,目前有8w店鋪,每個店鋪平均150個不同規格的商品,再算上增長,那商品數量得往1500w上預估,而且商品庫屬於訪問非常頻繁的資源,單臺伺服器已經無法支撐。此時,該如何優化。

嘗試水平分庫,將店鋪ID為單數和店鋪ID為雙數的商品資訊分表放在兩個庫中。

水平分庫是把同一個表的資料按一定規則拆到不同的資料庫中,每個庫可以放在不同的伺服器上。

他帶來的提升是:

解決了單庫大資料,高併發的效能瓶頸。

提高了系統的穩定性及可用性。(穩定性體現在IO衝突減少,鎖定減少,可用性指某個庫出問題,部分可用)

水平分表

水平分表是在同一個資料庫內,把同一個表的資料按一定的規則拆到多個表中。(對資料行拆分,不影響表結構)

他帶來的提升

優化單一表資料量過大而產生的效能問題。

避免IO爭搶而減少鎖表的機率。

小結:

本小結介紹了分庫分表的各種方式,他們分別是垂直分表,垂直分庫,水平分庫和水平分表。

垂直分表:可以吧一個寬表的欄位按訪問頻次,是否是大欄位的原則拆分為多個表,這樣既能使業務清晰,還能提升部分效能,拆分後,儘量從業務角度避免聯查,否則效能方面將得不償失。

垂直分庫:可以把多個表按業務耦合鬆緊歸類,分別存放在不同的庫,這些庫可以分佈在不同伺服器,從而使訪問壓力被多伺服器負載,大大提升效能,同事能提高整體架構的業務清晰度,不同的業務可根據自身情況定製優化方案,但是他需要解決跨庫帶來的所有複雜問題。

水平分庫:可以把一個表的資料(按資料行)分到多個不同的庫,每個庫只有這個表的部分資料,這些庫可以分佈在不同的伺服器上,從而使訪問壓力被多伺服器負載,大大提升效能,他不僅需要解決跨庫帶來的所有複雜問題,還要解決資料路由的問題(資料路由問題後邊介紹)。

水平分表:可以把一個表的資料(按資料行)分到同一個資料庫的多張表中,每個表只有這個表的部分資料,這樣做能小幅提升效能,他僅僅作為水平分庫的一個補充優化。

一般來說,在系統設計階段就應該根據業務耦合鬆緊來確定垂直分庫,垂直分表方案,在資料量及訪問壓力不是特別大的情況下,首先考慮快取,讀寫分離,索引技術等方案,若資料量極大,且持續增長,再考慮水平分庫水平分表方案。

分庫分錶帶來的問題

分庫分表能有效的緩解了單機和單庫帶來的效能瓶頸和壓力,突破網路IO,硬體資源,連線數的瓶頸,同時也帶來了一些問題。

事務一致性問題

由於分庫分表把資料分佈在不同的庫甚至不同伺服器,不可避免的帶來分散式事務問題。

比如一個請求要先請求資料庫A,再請求資料庫B,這兩個屬於同一個事務,多個庫會導致分散式事務問題。

跨節點關聯查詢

在沒有分庫前,我們可以很簡單的進行兩表的關聯查詢,但是分庫後,如果兩個表不在同一個資料庫,甚至不在同一臺伺服器上,無法進行關聯查詢。

可以將原關聯查詢分為兩次查詢,第一個查詢的結果找出關聯資料id,然後根據id發起第二次請求得到關聯資料,最後將獲得的資料進行拼裝。

跨節點分頁,排序函式

跨節點多庫進行查詢時,limit分頁,order by排序問題,就變得比較複雜,需要先在不同的分片節點中將資料進行排序並返回,然後將不同分片返回的結果集進行彙總和再次排序。

主鍵避重

在分庫分表環境中,由於表中資料同時存在不同資料庫中,主鍵值平時使用的自增長將無用武之地,某個庫生成的ID無法保證全域性唯一。因此需要單獨設計全域性主鍵,以便面跨庫主鍵重複問題。

公共表

實際應用場景中,引數表,資料字典表等都是資料量較小,變動少,而且屬於高頻聯合查詢的依賴表,但是其又沒有必要分庫分表,比如地理區域表也屬於此型別。

可以將這類表在每個資料庫都儲存一份,所有對公共表的更新操作都同時傳送到搜的分庫執行。

結語(重點)

如標題所示,我們不能為了分庫分表而分庫分表,首先我們需要知道分庫分表的誕生是因為資料庫的效能瓶頸導致的,也就是如果沒有效能瓶頸,沒必要使用分庫分表,畢竟技術是為了更好的服務於效能。其次,分庫分表也帶來了其他的問題,沒必要時系統變得臃腫,不便。

即,一切以業務為準,不能盲目追求技術的新穎,牛逼。

最後

關注偶哦,領取超多學習資料。