在說分庫分表之前,先簡單介紹下網站架構,這樣有助於理解為何需要分庫分表這種技術。因為所有的技術,大多都是因為業務的需要而產生的.
1、網站發展的第一階段
大致架構如下,因為沒有多少用戶訪問,所以單台服務器都搞定所有的事情,上面跑着數據庫、資源站點、以及所有的業務站點.
2、網站發展的第二階段
這個時候訪問量開始增加,發現服務器的資源不夠用了,用戶體驗越來越差,所以,第一想法,升級服務器配置.ok,暫時解決了問題,站點又能提供穩定且高效的服務.
3、網站發展的第三階段
訪問量持續增加,這個時候升級服務器的配置所產生的代價太大,而且,就算繼續升級也無法解決本質的問題,所以開始考慮其它的方案!
很簡單,將業務和數據分離,將業務站點和數據庫和資源站點分開,如下架構:
這里需要注意:業務站點需要處理大量的業務邏輯,所以CPU的性能一定要高,文件服務器則需要大一點的硬盤,數據庫服務器則需要更快的硬盤和更大的內存.
ok,問題又解決了,站點又能提供穩定且高效的服務.
4、網站發展的第四階段
訪問量持續增加,單台應用服務器的IIS線程並發連接有限,而且隨着用戶的上升開始出現超時,異常,直至站點崩潰.所以必須解決這個問題.
ok,增加應用服務器,實現小集群(每次加一台),上nginx(關於nginx不了解請參考Nginx),做反向代理,分發用戶的請求到不同的應用服務器,如果涉及登陸做下Ip_Hash.
ok,問題又解決了,站點又能提供穩定且高效的服務.
5、網站發展的第五階段
訪問量持續增加,應用服務器也越來越多,數據庫的壓力越來越大,而且數據隨着用戶的上升爆發時的增加,數據庫面臨了性能瓶頸,因為單表數據的上升,所以必須分表,提升查詢的速度.所以必須開始動數據庫了.
第一步:實現數據庫的讀寫分離,主要是配置,網商有很多文章,自行參考
第二步:分庫分表
6、關於分庫分表常用的設計思路
按時間、按地區(IP)、按業務進行划分,無外乎這三種方式.下面簡單的介紹個例子,假設站點是個登陸站點,主要分為QQ登陸和微信登陸,站點需要記錄每次用戶的登陸的一些信息.
假設每天有10萬用戶登陸.做過單表10萬數據查詢的知道,不加索引的情況下,還是有點慢的.所以我們需要對這個登陸記錄表進行拆分.第一步按QQ登陸和微信登陸進行分庫,將通過QQ登陸的用戶登陸信息存儲到QQ登陸庫,微信同理,這樣每個庫每天承擔5萬的寫操作.
但是單表5萬記錄查詢還是有點慢,這個時候還可以進行細分,比如按用戶Id,進行拆封按用戶Id拆分一般有兩種(用戶Id算法):
(1)、如果Id是int整數(如SqlServer的自增Id),可以采用Id%10取余算法,找到目標表。采用這種算法,那么原先的單表被拆封成0~9十個表,每個表承擔5000的寫操作,這樣壓力瞬間就下來了
(2)、如果Id是Guid(長度固定,全大寫),獲取最后1個字母,找到目標表,采用這種算法,那么原先的單表被拆封成A-Z36個表,每個表承擔寫壓力就更小了.
上面兩個都可取,但是可以根據具體的業務酌情選擇.
目前為止,解決了單天的性能瓶頸,但是每天都有10萬數據進來,肯定是不行的,所以按照上面的思路每天的數據必須在當前被清空,因為不清空,隨着數據每天加10萬的操作,查詢到最后還是受不了.
所以必須寫個定時服務,每天在業務低峰期清除QQ登陸信息庫和微信登陸信息庫的數據,清楚的同時將它們遷移到對應QQ登陸信息歷史庫和微信登陸歷史庫中,關於歷史庫的構建就需要仔細考慮了.
考慮了幾種方案:
(1)、就兩個歷史庫(微信登陸歷史庫和QQ登陸歷史庫),直接Pass,每天10萬數據的遞增,不用一年就直接崩了.
(2)、按年分庫 月+日+用戶Id 進行分表 直接Pass,這個方案會產生大概3600個表
(3)、權衡考慮采用按年分庫 月+用戶Id 進行分表 如果用戶Id采用用戶Id算法的第一種,那么會產生大概120個表.
確定好歷史庫設計方案之后,將每天的登陸信息記錄同步到對應的歷史庫中.