MySQL 分庫分表方案

數據庫分庫分表spring

前言

公司最近在搞服務分離,數據切分方面的東西,由於單張包裹表的數據量實在是太大,而且還在以天天60W的量增加。 以前瞭解過數據庫的分庫分表,讀過幾篇博文,但就只知道個模糊概念, 並且如今回想起來什麼都是模模糊糊的。sql

今天看了一下午的數據庫分庫分表,看了不少文章,如今作個總結,「摘抄」下來。(但更期待後期的實操) 會從如下幾個方面提及: 數據庫

第一部分:實際網站發展過程當中面臨的問題。 編程

第二部分:有哪幾種切分方式,垂直和水平的區別和適用面。服務器

第三部分:目前市面有的一些開源產品,技術,它們的優缺點是什麼。mybatis

第四部分:多是最重要的,爲何不建議水平分庫分表!?這能讓你能在規劃前期謹慎的對待,規避掉切分形成的問題。架構

名詞解釋

庫:database;表:table;分庫分表:sharding併發

數據庫架構演變

剛開始咱們只用單機數據庫就夠了,隨後面對愈來愈多的請求,咱們將數據庫的寫操做和讀操做進行分離, 使用多個從庫副本(Slaver Replication)負責讀,使用主庫(Master)負責寫, 從庫從主庫同步更新數據,保持數據一致。架構上就是數據庫主從同步。 從庫能夠水平擴展,因此更多的讀請求不成問題。框架

可是當用戶量級上來後,寫請求愈來愈多,該怎麼辦?加一個Master是不能解決問題的, 由於數據要保存一致性,寫操做須要2個master之間同步,至關因而重複了,並且更加複雜。maven

這時就須要用到分庫分表(sharding),對寫操做進行切分。

分庫分表前的問題

任何問題都是太大或者過小的問題,咱們這裏面對的數據量太大的問題。

用戶請求量太大

由於單服務器TPS,內存,IO都是有限的。 解決方法:分散請求到多個服務器上; 其實用戶請求和執行一個sql查詢是本質是同樣的,都是請求一個資源,只是用戶請求還會通過網關,路由,http服務器等。

單庫太大

單個數據庫處理能力有限;單庫所在服務器上磁盤空間不足;單庫上操做的IO瓶頸 解決方法:切分紅更多更小的庫

單表太大

CRUD都成問題;索引膨脹,查詢超時 解決方法:切分紅多個數據集更小的表。

分庫分表的方式方法

通常就是垂直切分和水平切分,這是一種結果集描述的切分方式,是物理空間上的切分。 咱們從面臨的問題,開始解決,闡述: 首先是用戶請求量太大,咱們就堆機器搞定(這不是本文重點)。

而後是單個庫太大,這時咱們要看是由於表多而致使數據多,仍是由於單張表裏面的數據多。 若是是由於表多而數據多,使用垂直切分,根據業務切分紅不一樣的庫。

若是是由於單張表的數據量太大,這時要用水平切分,即把表的數據按某種規則切分紅多張表,甚至多個庫上的多張表。 分庫分表的順序應該是先垂直分,後水平分。 由於垂直分更簡單,更符合咱們處理現實世界問題的方式。

垂直拆分

  1. 垂直分表

    也就是「大表拆小表」,基於列字段進行的。通常是表中的字段較多,將不經常使用的, 數據較大,長度較長(好比text類型字段)的拆分到「擴展表「。 通常是針對那種幾百列的大表,也避免查詢時,數據量太大形成的「跨頁」問題。

  2. 垂直分庫

    垂直分庫針對的是一個系統中的不一樣業務進行拆分,好比用戶User一個庫,商品Producet一個庫,訂單Order一個庫。 切分後,要放在多個服務器上,而不是一個服務器上。爲何? 咱們想象一下,一個購物網站對外提供服務,會有用戶,商品,訂單等的CRUD。沒拆分以前, 所有都是落到單一的庫上的,這會讓數據庫的單庫處理能力成爲瓶頸。按垂直分庫後,若是仍是放在一個數據庫服務器上, 隨着用戶量增大,這會讓單個數據庫的處理能力成爲瓶頸,還有單個服務器的磁盤空間,內存,tps等很是吃緊。 因此咱們要拆分到多個服務器上,這樣上面的問題都解決了,之後也不會面對單機資源問題。

    數據庫業務層面的拆分,和服務的「治理」,「降級」機制相似,也能對不一樣業務的數據分別的進行管理,維護,監控,擴展等。 數據庫每每最容易成爲應用系統的瓶頸,而數據庫自己屬於「有狀態」的,相對於Web和應用服務器來說,是比較難實現「橫向擴展」的。 數據庫的鏈接資源比較寶貴且單機處理能力也有限,在高併發場景下,垂直分庫必定程度上可以突破IO、鏈接數及單機硬件資源的瓶頸。

水平拆分

  1. 水平分表

    針對數據量巨大的單張表(好比訂單表),按照某種規則(RANGE,HASH取模等),切分到多張表裏面去。 可是這些表仍是在同一個庫中,因此庫級別的數據庫操做仍是有IO瓶頸。不建議採用。

  2. 水平分庫分表

    將單張表的數據切分到多個服務器上去,每一個服務器具備相應的庫與表,只是表中數據集合不一樣。 水平分庫分表可以有效的緩解單機和單庫的性能瓶頸和壓力,突破IO、鏈接數、硬件資源等的瓶頸。

  3. 水平分庫分表切分規則

    1. RANGE

      從0到10000一個表,10001到20000一個表;

    2. HASH取模

      一個商場系統,通常都是將用戶,訂單做爲主表,而後將和它們相關的做爲附表,這樣不會形成跨庫事務之類的問題。 取用戶id,而後hash取模,分配到不一樣的數據庫上。

    3. 地理區域

      好比按照華東,華南,華北這樣來區分業務,七牛雲應該就是如此。

    4. 時間

      按照時間切分,就是將6個月前,甚至一年前的數據切出去放到另外的一張表,由於隨着時間流逝,這些表的數據 被查詢的機率變小,因此不必和「熱數據」放在一塊兒,這個也是「冷熱數據分離」。

分庫分表後面臨的問題

事務支持

分庫分表後,就成了分佈式事務了。若是依賴數據庫自己的分佈式事務管理功能去執行事務,將付出高昂的性能代價; 若是由應用程序去協助控制,造成程序邏輯上的事務,又會形成編程方面的負擔。

多庫結果集合並(group by,order by)

TODO

跨庫join

TODO 分庫分表後表之間的關聯操做將受到限制,咱們沒法join位於不一樣分庫的表,也沒法join分表粒度不一樣的表, 結果本來一次查詢可以完成的業務,可能須要屢次查詢才能完成。 粗略的解決方法: 全局表:基礎數據,全部庫都拷貝一份。 字段冗餘:這樣有些字段就不用join去查詢了。 系統層組裝:分別查詢出全部,而後組裝起來,較複雜。

分庫分表方案產品

目前市面上的分庫分表中間件相對較多,其中基於代理方式的有MySQL Proxy和Amoeba, 基於Hibernate框架的是Hibernate Shards,基於jdbc的有當當sharding-jdbc, 基於mybatis的相似maven插件式的有蘑菇街的蘑菇街TSharding, 經過重寫spring的ibatis template類的Cobar Client。

相關文章
相關標籤/搜索