MySQL数据库的读写分离、分库分表
一、讀寫分離
因為用戶的增多,數(shù)據(jù)的增多,單機的數(shù)據(jù)庫往往支撐不住快速發(fā)展的業(yè)務,所以數(shù)據(jù)庫集群就產(chǎn)生了!
讀寫分離顧名思義就是讀和寫分離了,對應到數(shù)據(jù)庫集群一般都是一主一從(一個主庫,一個從庫)或者一主多從(一個主庫,多個從庫),業(yè)務服務器把需要寫的操作都寫到主數(shù)據(jù)庫中,讀的操作都去從庫查詢。主庫會同步數(shù)據(jù)到從庫保證數(shù)據(jù)的一致性。
這種集群方式的本質(zhì)就是把訪問的壓力從主庫轉(zhuǎn)移到從庫,適合讀的請求較多的情況下。
在單機的情況下,一般我們做數(shù)據(jù)庫優(yōu)化都會加索引,但是加了索引對查詢有優(yōu)化,但是會影響寫入,因為寫入數(shù)據(jù)會更新索引。所以做了主從之后,我們可以單獨的針對從庫(讀庫)做索引上的優(yōu)化,而主庫(寫庫)可以減少索引而提高寫的效率。
看起來還是很簡單的,但是有兩點要注意:主從同步延遲、分配機制的考慮;
主從同步延遲
主庫有數(shù)據(jù)寫入之后,同時也寫入在binlog(二進制日志文件)中,從庫是通過binlog文件來同步數(shù)據(jù)的,這期間會有一定時間的延遲,可能是1秒,如果同時有大量數(shù)據(jù)寫入的話,時間可能更長。
所以為了解決主從同步延遲的問題有以下幾個方法:
1. 二次讀取:意思就是讀從庫沒讀到之后再去主庫讀一下
2.寫之后的馬上的讀操作訪問主庫
3.關鍵業(yè)務讀寫都由主庫承擔,非關鍵業(yè)務讀寫分離
二、分庫分表
主從集群也就是讀寫分離,其實只是分擔了訪問的壓力,但是存儲的壓力沒有解決。
分庫
假設數(shù)據(jù)庫中有兩張表分別是用戶表和訂單表。如果要分庫的話現(xiàn)在你需要買兩臺機子,搞兩個數(shù)據(jù)庫分別放在兩臺機子上,并且一個數(shù)據(jù)庫放用戶表,一個數(shù)據(jù)庫放訂單表。
這樣存儲壓力就分擔到兩個服務器上了,但是會帶來新的問題,所以東西變復雜了都會有新的問題產(chǎn)生。。
1. 聯(lián)表查詢
也就是join了,之前在一個數(shù)據(jù)庫里面可以用上join用一條sql語句就可以聯(lián)表查詢得到想要的結(jié)果,但是現(xiàn)在分為多個數(shù)據(jù)庫了,所以join用不上了。就比如現(xiàn)在要查注冊時間在2019年之后用戶的訂單信息,你就需要先去數(shù)據(jù)庫A中用戶表查詢注冊在2019年之后的信息,然后得到用戶id,再拿這些id去數(shù)據(jù)庫B訂單表中查找訂單信息,然后再拼接這些信息返回。所以等于得多寫一些代碼了。
2. 事務問題
搞數(shù)據(jù)庫基本上都離不開事務,但是現(xiàn)在不同的數(shù)據(jù)庫事務就不是以前那個簡單的本地事務了,而是分布式事務了,而引入分布式事務也提高了系統(tǒng)的復雜性。
分表
我們已經(jīng)做了分庫了,但是現(xiàn)在情況是我們一個表里面的數(shù)據(jù)太多了,就一不小心你的公司的產(chǎn)品火了,像抖音這種,所有用戶如果就存在一張表里吃不消,所以這時候得分表。分別又分垂直分表和水平分表。
1. 垂直分表
比如我們表有10列,現(xiàn)在一刀切下去,分成了兩張表,其中一張表3列,另一張表7列。
這個一刀切下去讓兩個表分別有幾列不是固定的,垂直分表適合表中存在不常用并且占用了大量空間的字段拆分出去。
就拿頭條的用戶信息,比如用戶表只有用戶id、昵稱、手機號、個人簡介這4個字段。但是手機號和個人簡介這種信息就屬于不太常用的,占用的空間也不小,個人簡介有些人寫了一坨。所以就把手機號和個人簡介這兩列拆分出去。
那垂直分表影響就是之前只要一個查詢的,現(xiàn)在需要兩次查詢才能拿到分表之前的完整用戶表信息。
2. 水平分表
比如現(xiàn)在用戶表有5000萬行數(shù)據(jù),我們切5刀,分成5個表,每個表1000萬行數(shù)據(jù)。
水平分表就適合用戶表行數(shù)很多的情況下,一般單表行數(shù)超過5000萬就得分表,如果單表的數(shù)據(jù)比較復雜那可能2000萬甚至1000萬就得分了,這個得看實際情況有些表很簡單可能一億行都不用分。所以當一個表行數(shù)超過千萬級別的時候關注一下,如果沒有性能問題就可以再等等看,不要急著分表,因為分表會是帶來很多問題。
水平分表的問題比垂直分表就更煩了。
要考慮怎么切,講的高級點就叫路由:
1. 按id(也就是范圍路由)
比如id 值1-999萬的放一張表,1000萬-1999萬放一張表,一次類推(也就是一段一段)。這個得試的,因為范圍分的大了,可能性能還有問題,范圍分的小了。。那表不得多死。
這種分法的好處就是容易切啊,簡單粗暴,以后新增的數(shù)據(jù)分表都不會影響到之前的數(shù)據(jù),之前的數(shù)據(jù)都不需要移動。
2. 哈希路由
就是取幾列哈希一下看看數(shù)據(jù)哪個庫,比如拿id來做哈希,1500取余8等于4,所以這條記錄就放在user_4這個表中,2011取余8等于3,所以這條記錄就放在user_3中。這種分法好處就是分的很均勻,基本上每個表的數(shù)據(jù)都差不多,但是以后新增數(shù)據(jù)又得分表了咋辦,以前的數(shù)據(jù)都得動,比較煩!
3.搞一張表來存儲路由關系
還是拿用戶表來說,就是弄一個路由表,里面存userId和表編號,表示這個userId是這張user表的的。這種方式也簡單,之后又要分表了之后改改路由表,遷移一部分數(shù)據(jù)。但是這種方法導致每次查詢都得查兩次,并且如果路由表太大了,那路由表又成為瓶頸了!
三、總結(jié)
技術沒有貴賤,不是用了分布式就牛逼,越復雜的系統(tǒng)維護的成本和難度越高,出現(xiàn)問題的幾率越大。這種架構(gòu)的演化往往都是被用戶所驅(qū)動的,可以說是"不得已而為之"。
基本上單機數(shù)據(jù)庫可以支撐10萬用戶量級別。所以一般情況下像數(shù)據(jù)庫吃不消就升級硬件,優(yōu)化數(shù)據(jù)庫配置、優(yōu)化代碼、引入redis等。只有在真的不行了才上這些更復雜的東西。
參考鏈接
1.面試官:說說Mysql讀寫分離,并且有哪些注意事項?
2. 面試官:說說Mysql數(shù)據(jù)庫分庫分表,并且會有哪些問題?
總結(jié)
以上是生活随笔為你收集整理的MySQL数据库的读写分离、分库分表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 秦姓女孩起名字(寻找一个美丽的名字——给
- 下一篇: 连平忠信径口村姓什么