我們先來看一下業務的乙個發展情況,由我們最開始的單錶,發展到單錶分表,在因為資料量得增加我們不得不到了分庫分表。當然這些都是符合乙個大公司的發展方向的。很少會有業務一開始就會設計為分庫分表,雖說這樣會減少後續的坑,但部分公司剛開始都是以業務為主。直到業務發展到單錶無法支撐時,才會自然而然的去考慮分表甚至分庫的事情。
首先我們先來說一下什麼樣的情況下適合分表?
當某張表的資料量已經達到千萬甚至上億,同時日增資料量在 2% 以上。
當然這些數字並不是絕對的,最重要的還是對這張表的寫入和查詢都已經影響到正常業務執行,比如查詢速度明顯下降,資料庫整體 io 居高不下等。而談到分表時我們著重討論的還是水平分表;
也就是將一張大表資料通過某種路由演算法將資料盡可能的均勻分配到 n 張小表中。
而分表策略也有好幾種,分別適用不同的場景。
1.按照範圍劃分,比如我們可以將某張表的建立時間按照日期劃分存為月表;也可以將某張表的主鍵按照範圍劃分,比如 【1~10000】在一張表, 【10001~20000】在一張表,以此類推。這樣的分表適合需要對資料做歸檔處理,比如系統預設只提供近三個月歷史資料的查詢功能,這樣也方便操作;只需要把三月之前的資料單獨移走備份儲存即可)。
這個方案有好處也有弊端:
·好處:自帶水平擴充套件,不需要過多干預。
·缺點:可能會出現資料不均勻的情況(比如某個月請求暴增)。
按照日期這樣的範圍分表固然簡單,但適用範圍還是比較窄;畢竟我們大部分的資料查詢都不想帶上時間。
比如某個使用者想查詢他產生的所有訂單資訊,這是很常見的需求。
2.於是我們分表的維度就得改改,分表演算法可以採用主流的 hash+mod 的組合。
這是乙個經典的演算法,大名鼎鼎的 hashmap 也是這樣來儲存資料。
假設我們這裡將原有的一張大表訂單資訊分為 64 張分表:
這裡的 hash 便是將我們需要分表的字段進行一次雜湊運算,使得經過雜湊的資料盡可能的均勻並且不重複。
當然如果本身這個字段就是乙個整形並且不重複也可以省略這個步驟,直接進行 mod 得到分表下標即可。
3.range 和 hash 是否可以混用。
分表規則弄好後其實只是完成了分表的第一步,真正麻煩的是資料遷移,或者說是如何做到對業務影響最小的資料遷移。
除非是一開始就做了分表,所以資料遷移這一步驟肯定是跑不掉的。
一旦分表上線後所有的資料寫入、查詢都是針對於分表的,所以原有大表內的資料必須得遷移到分表裡,不然對業務的影響極大。
我估算了對一張 2 億左右的表進行遷移,自己寫的遷移程式,大概需要花 4~5 天的時間才能完成遷移。
意味著這段時間內,以前的資料對使用者是不可見的,顯然這樣業務不能接受。
於是我又做了乙個相容處理:分表改造上線後,所有新產生的資料寫入分表,但對歷史資料的操作還走老表,這樣就少了資料遷移這一步驟。
只是需要在運算元據之前做一次路由判斷,當新資料產生的足夠多時(我們是兩個月時間),幾乎所有的操作都是針對於分表,再從庫啟動資料遷移,資料遷移完畢後將原有的路由判斷去掉。
最後所有的資料都從分表產生和寫入。 至此整個分表操作完成。
同時分表之後還需要相容其他業務;比如原有的報表業務、分頁查詢等,現在來看看我們是如何處理的。
mysql 分庫分表實戰 MySQL分庫分表實戰
為什麼要分庫分表 在大型 中,當使用者量以及使用者產生的業務資料量達到單庫單錶效能極限時,為了支撐業務可持續發展,對於重要的核心業務必然要進行分庫分表來儲存業務資料。對於非核心業務產生的大量資料,例如爬蟲爬取的資訊,論壇產生的資料等,可以考慮把資料儲存在像mongodb這樣的nosql儲存裡面,這些...
分庫分表實戰問題
1.分庫分表中水平拆分和垂直拆分的區別?水平拆分 將表資料拆分到不同的資料資料庫中。垂直拆分 把乙個大表拆成多個小表。字段進行拆分。分表 是指的是把表資料拆分到多張表裡面。range分發 每個月生成乙個新錶。如果訪問新的資料還好,但是訪問舊的資料就麻煩一些。hash分發 平均分配,但是擴容的話會比較...
企業Shell實戰 MySQL分庫分表備份指令碼
企業 shell 實戰 mysql分庫分表備份 今天是2015年的最後一天,大家都開心的跨年,而我還在苦逼的呵呵 省略 此處內容來自老男孩教育oldboy以及老男孩26期王續精彩分享整理而來 為表示感謝,特整理此篇博文分享給大家!root db02 scripts cat server script...