數據庫分庫分表估計不少夥伴都沒有實踐過,就是由於本身公司的業務不是不少,沒有那麼多數據。假若有一天項目的人數上來了,你寫的系統支撐不住了,但願這篇文章帶給你一絲絲的思路。程序員
這裏寫目錄標題
前言
在面試過程當中你是否是會常常遇到對於數據庫分庫分表你有什麼方案啊!面試
在平時看博客時你是否是也常常刷到MySQL如何分庫分表。數據庫
然而你是否是點進去看了不到10秒就直接退出窗口。安全
那是由於寫的文章不是什麼水平切分,就是垂直切割,在一個自身所在的公司根本使用不到。服務器
若是你只知道分庫分表可是不知道怎麼弄的話,花個五分鐘看完你會收穫到不同的思路。網絡
1、初始架構
公司的規模小,項目針對的用戶羣體屬於小衆。日活就幾千、幾萬的用戶這樣的數據天天的數據庫單表增長通常不會超過10萬。併發更不沾邊了。架構
這種項目規模,咱們就是認真、快速開發業務邏輯,提高用戶體驗,從而提高項目的用戶粘度並達到收納更多用戶的準備。併發
這個時候咱們項目一臺16核32G的服務器就徹底能夠了,能夠將數據庫單獨放一個服務器,也能夠都放在一個服務器。性能
這個時候項目架構圖是這個樣子的。學習
2、用戶開始激增解決方案
在經歷了第一階段後,因爲項目的用戶體驗度極高,項目又吸引了大量的用戶。
這時咱們項目日活達到了百萬級別,註冊用戶也超過了千萬。這個數據是咔咔根據以前公司項目數據推算的。
這時天天單表數據新增達到了100萬,併發請求每秒也達到了上萬。這時單系統就扛不住了。
假設天天就固定新增100萬,每個月就是3000萬 ,一年就是接近5億數據。
數據庫以這種速度運行下去,數據到2000W到3000W還能勉強撐住,可是你會發現數據庫日誌會出現愈來愈多的慢查詢。
雖然說併發1W,可是咱們能夠部署個10臺機器或者20臺機器,平均每臺機器承擔500到1000的請求,仍是綽綽有餘的。
可是數據庫方面仍是用一臺服務器支撐着每秒上萬的請求,那麼你將會遇到如下問題。
- 數據庫所在的服務器磁盤IO、網絡帶寬、CPU負載、內存消耗都會很是高
- 單表數據已經很大,SQL性能已經已經出現下坡階段,加上數據庫服務器負載過高致使性能降低,會直接致使SQL性能更差
- 這個時候最明顯的感受,就是用戶獲取一個數據可能須要10s以上的時間纔會返回。
- 若是前期服務器配置不是很高的話,你就會面臨數據庫宕機的狀況
那麼這個時候咱們要怎麼對項目進行架構的優化呢!
根據大佬們的經驗是數據庫的鏈接數每秒控制在2000便可、那麼咱們1W併發的狀況下部署5臺機器,每臺機器都部署一個一樣結構的數據庫。
此時在5臺數據庫擁有一樣的數據庫。表名規則能夠這樣設置。
這時每一個project庫都有一個相同的表,好比db_project1有tb_play_recode一、db_project2有tb_play_recode2…
這樣就實現了一個基本的分庫分表的思路,從原來一臺數據庫服務器變成了5臺數據庫服務器,從原來一個庫變成了5個庫,原來的一張表變成了5張表。
這時咱們就須要藉助數據庫中間件來完成寫數據,例如mycat。
這個時候就須要使用播放記錄表的自增ID進行取模5,好比天天播放記錄新增100W數據。此時20W數據會落到db_project1的db_play_recode1,其它的四個庫分別也會落入20W數據。
查詢數據時就根據播放記錄的自增ID進行取模5,就能夠去對應的數據庫,從對應的表裏查詢數據便可。
實現了這個架構後,咱們在來分析一下。
原來播放記錄就一張表,如今變成了5張表,那麼每一個表就變成了1/5
按照原項目的推算,一年若有1億數據,每張表就只有2000w數據。
按照天天新增50W數據,每張表天天新增10W數據,這樣是否是就初步緩解了單表數據量過大影響系統性能問題了。
另外每秒1W的請求,這時每臺服務器平均就2000,瞬間就把併發請求下降到了安全範圍了。
3、保證查詢性能
在上邊的數據庫架構會遇到一個問題,就是單表數據量仍是很大,按照每一年1億的數據,單表就會有2000W數據,仍是太大了。
好比能夠將播放記錄表拆分爲100張表,而後分散到5臺數據庫服務器,這時單表的數據就只有100W,那查詢起來還不是灑灑水的啦!
在寫數據時就須要通過倆次路由,先對播放記錄ID取模數據庫數量,這時能夠路由到一臺數據庫上,而後再對那臺數據庫上的表數量進行取模,最終就會路由到數據上的一個表裏了。
經過這個步驟就可讓每一個表的數據都很是少,按照100張表,1億數據,落到每一個表的數據就只有100W。
這時的系統架構是這個樣子的。
4、配置讀寫分離來按需擴容
以上的架構總體效果已經很不錯了,假設上邊分了100張表仍是不知足需求,能夠經過用戶增量計算來配置合理的表。同時還能夠保證單表內的SQL執行效率。
這時還會遇到一個問題,假如每臺服務器承載每秒2000的請求,其中就400是寫入,1600是查詢。
也就是說,增刪改查中增刪改的SQL才佔到了20%的比例,80%的請求都是查詢。
安裝以前的推理,如今全部數據進行翻倍計算,每臺服務器併發達到了4000請求了。
那麼其中800請求是寫入,3200請求是查詢,若是說安裝目前的狀況來擴容,就只須要增長一臺數據庫服務器便可。可是就會涉及到表的遷移,由於須要遷移一部分表到新的數據庫上,那是很麻煩的事情了。
其實沒有這個必要的,可使用讀寫分離來解決這個問題,也就是主從複製。
寫的時候走主庫,讀數據時走從庫,這樣就可讓一個表的讀寫請求分開落到不一樣的數據庫上去執行。
這樣的設計後,咱們在推算一下,假如寫入主庫的請求是400/s ,查詢從庫的請求是就是1800/s,只須要在主庫下配置倆臺從庫便可。
這時的架構是以下的。
實際的生產環境,讀請求的增加速度遠遠高於寫的請求,因此讀寫分離以後,大部分就是擴容從庫支撐更高的讀請求就能夠了。
並且另一個點,對同一個表,若是既寫數據,還讀數據,可能會牽扯到鎖衝突問題,不管讀仍是寫性能都會有影響。
因此一旦讀寫分離以後,對主庫的表就僅僅是寫入,沒任何查詢會影響主庫。對從庫就僅僅是查詢了。
5、併發數據庫結構總結
關於併發場景下,數據庫層面的架構是須要進行精心的設計的。
而且在配置主複製時,也會有不少的問題來等着去解決。
本文就是從一個大的角度來梳理一個思路給你們,能夠根據本身公司的業務和項目來考慮本身的系統如何分庫分表。
分庫分表的落地須要藉助mycat或者其餘數據庫中間件來實現。
這幾天就會再出一篇文章對於本文的一個實現,而且還有不少問題等着去解決。
例如:自增ID問題,主從複製數據不一致問題,在主從複製這塊不少問題,做爲程序員的咱們就是須要不停的打boos得到最終的勝利。
堅持學習、堅持寫博、堅持分享是咔咔從業以來一直所秉持的信念。但願在諾大互聯網中咔咔的文章能帶給你一絲絲幫助。