不信你看看,MySQL分庫分表沒有那么難
數據庫分庫分表估計很多伙伴都沒有實踐過,就是因為自己公司的業務不是很多,沒有那么多數據。假如有一天項目的人數上來了,你寫的系統支撐不住了,希望這篇文章帶給你一絲絲的思路。
這里寫目錄標題
前言
一、初始架構
二、用戶開始激增解決方案
三、保證查詢性能
四、配置讀寫分離來按需擴容
五、并發數據庫結構總結
前言
在面試過程中你是不是會經常遇到對于數據庫分庫分表你有什么方案??!
在平時看博客時你是不是也經常刷到MySQL如何分庫分表。
然而你是不是點進去看了不到10秒就直接退出窗口。
那是因為寫的文章不是什么水平切分,就是垂直切割,在一個自身所在的公司根本使用不到。
如果你只知道分庫分表但是不知道怎么弄的話,花個五分鐘看完你會收獲到不一樣的思路。
一、初始架構
公司的規模小,項目針對的用戶群體屬于小眾。日活就幾千、幾萬的用戶這樣的數據每天的數據庫單表增加一般不會超過10萬。并發更不沾邊了。
這種項目規模,我們就是認真、快速開發業務邏輯,提升用戶體驗,從而提升項目的用戶粘度并達到收納更多用戶的準備。
這個時候我們項目一臺16核32G的服務器就完全可以了,可以將數據庫單獨放一個服務器,也可以都放在一個服務器。
這個時候項目架構圖是這個樣子的。
二、用戶開始激增解決方案
在經歷了第一階段后,由于項目的用戶體驗度極高,項目又吸引了大量的用戶。
這時我們項目日活達到了百萬級別,注冊用戶也超過了千萬。這個數據是咔咔根據之前公司項目數據推算的。
這時每天單表數據新增達到了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_recode1、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,瞬間就把并發請求降低到了安全范圍了。
三、保證查詢性能
在上邊的數據庫架構會遇到一個問題,就是單表數據量還是很大,按照每年1億的數據,單表就會有2000W數據,還是太大了。
比如可以將播放記錄表拆分為100張表,然后分散到5臺數據庫服務器,這時單表的數據就只有100W,那查詢起來還不是灑灑水的啦!
在寫數據時就需要經過倆次路由,先對播放記錄ID取模數據庫數量,這時可以路由到一臺數據庫上,然后再對那臺數據庫上的表數量進行取模,最終就會路由到數據上的一個表里了。
通過這個步驟就可以讓每個表的數據都非常少,按照100張表,1億數據,落到每個表的數據就只有100W。
這時的系統架構是這個樣子的。
四、配置讀寫分離來按需擴容
以上的架構整體效果已經很不錯了,假設上邊分了100張表還是不滿足需求,可以通過用戶增量計算來配置合理的表。同時還可以保證單表內的SQL執行效率。
這時還會遇到一個問題,假如每臺服務器承載每秒2000的請求,其中就400是寫入,1600是查詢。
也就是說,增刪改查中增刪改的SQL才占到了20%的比例,80%的請求都是查詢。
安裝之前的推理,現在所有數據進行翻倍計算,每臺服務器并發達到了4000請求了。
那么其中800請求是寫入,3200請求是查詢,如果說安裝目前的情況來擴容,就只需要增加一臺數據庫服務器即可。但是就會涉及到表的遷移,因為需要遷移一部分表到新的數據庫上,那是很麻煩的事情了。
其實沒有這個必要的,可以使用讀寫分離來解決這個問題,也就是主從復制。
寫的時候走主庫,讀數據時走從庫,這樣就可以讓一個表的讀寫請求分開落到不同的數據庫上去執行。
這樣的設計后,我們在推算一下,假如寫入主庫的請求是400/s ,查詢從庫的請求是就是1800/s,只需要在主庫下配置倆臺從庫即可。
這時的架構是如下的。
實際的生產環境,讀請求的增長速度遠遠高于寫的請求,所以讀寫分離之后,大部分就是擴容從庫支撐更高的讀請求就可以了。
而且另外一個點,對同一個表,如果既寫數據,還讀數據,可能會牽扯到鎖沖突問題,無論讀還是寫性能都會有影響。
所以一旦讀寫分離之后,對主庫的表就僅僅是寫入,沒任何查詢會影響主庫。對從庫就僅僅是查詢了。
五、并發數據庫結構總結
關于并發場景下,數據庫層面的架構是需要進行精心的設計的。
并且在配置主復制時,也會有很多的問題來等著去解決。
本文就是從一個大的角度來梳理一個思路給大家,可以根據自己公司的業務和項目來考慮自己的系統如何分庫分表。
分庫分表的落地需要借助mycat或者其他數據庫中間件來實現。
這幾天就會再出一篇文章對于本文的一個實現,并且還有很多問題等著去解決。
例如:自增ID問題,主從復制數據不一致問題,在主從復制這塊很多問題,作為程序員的我們就是需要不停的打boos獲得最終的勝利。
堅持學習、堅持寫博、堅持分享是咔咔從業以來一直所秉持的信念。希望在諾大互聯網中咔咔的文章能帶給你一絲絲幫助。
MySQL 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。