程式設計師面試題之資料庫讀寫分離

Mysql作為現代最受歡迎的關係型資料庫,幾乎是每個後臺程式設計師都必須掌握的一個技能。後臺面試中,Mysql也經常出現,除了常見的事務、索引之外,Mysql的一些部署與應用也經常出現,今天我們來看到一個Mysql常見的技術——讀寫分離。

程式設計師面試題之資料庫讀寫分離

問:

Mysql讀寫分離解決了什麼問題?

Mysql讀寫分離如何實現?

Mysql讀寫分離會引入哪些新的問題,如何解決?

為什麼需要讀寫分離

我們都知道單臺機器的效能是有限的,每臺機器可以維護的連線數是優先的,CPU的算力是有限的,每臺機器的記憶體也是有限的,那麼,隨著業務的增長,資料日益增多,我們必然會面對這樣一個問題,部署Mysql的機器會越來越成為系統的瓶頸。

對於這個問題,我們有兩種解決思路,第一個是把資料庫進行拆分,不同的業務拆分到不同的資料庫,或者同一個業務按照一定的維度進行拆分,也就是我們常說的分庫分表。

另外一個思路,由於大部分網際網路應用都是讀多寫少的,所以,我們能否不拆分資料庫,讓同一份資料複製到多臺機器上,不同業務到不同的機器上進行資料讀取。這就是我們常常說的讀寫分離。

程式設計師面試題之資料庫讀寫分離

通常,我們都是兩種手段一併使用的。

讀寫分離如何實現

首先是資料同步問題,主機是如何把資料從主機同步到從機的。一般,我們都是透過Mysql的主從同步進行實現,當然,也有一些大廠會自研相關的中介軟體進行解決。Mysql的主從同步主要是利用Binlog的回放機制,將主機上的binlog檔案同步到從數機器上進行回放。

第二個是程式的路由問題,寫的時候寫主機,讀的時候什麼時候讀取主機,什麼時候讀取從機。

最簡單的方法,就是交給程式去實現,由程式碼自己去決定是讀機還是從機。優點是簡單,開發方便,並且非常靈活,不同的業務可以自主選擇是否讀取從機。缺點是開發需要理解每次資料讀取是訪問哪個資料庫,如果遇到不靠譜的程式設計師,有時候真是一種災難。另外,如果遇到緊急情況,例如主機故障需要另外選擇主機的時候,可能需要修改所有業務機器的配置,才能完成主機的切換。

程式設計師面試題之資料庫讀寫分離

第二個是使用資料庫中介軟體,由中介軟體去決定如何路由。中介軟體對外遮蔽了多種細節,對業務來說,就跟直接連線資料庫一樣,降低了開發的難度。即使是資料庫主機發生變化,只需要操作資料庫中介軟體。當然,有得必有失,新增的中介軟體勢必會增加系統的複雜度,中介軟體的效能與穩定性也是一個考驗,多路由一個系統也會造成延遲的增加。

讀寫分離會帶來什麼問題?

無論是採用哪一種讀寫分離的方案,都會面臨這樣的一個問題,剛剛更新的資料,立馬在從庫進行查詢,可能會查詢到髒資料,因為主從同步是需要時間的。設想,如果使用者在支付完訂單之後,回到訂單頁面,看到訂單還是未支付,是有怎麼樣的感受?

為了解決主從同步延遲的問題,一般我們可以採用下面的解決方案:

強制讀主庫,

對於使用者讀取訂單、支付等重要的資訊,強制讀取主庫資訊,不讀從庫。從庫,留給一些對實時性要求不高的場景讀取,例如後臺非同步任務、庫存系統校驗訂單狀態等等。

程式設計師面試題之資料庫讀寫分離

快取標記方案,

因為主從同步延遲造成的髒讀只是佔整個系統讀取的一部分,如果我們把所有的讀取都切換成讀取主庫,那麼讀寫分離的意義就會大打折扣,有沒有折中的方案呢?我們知道,記憶體相對於磁碟,讀寫效率更快,那麼,我們可否在服務端維護一個LRUCache,用來表示最近哪些資料被更新過。例如,我們維護哪些使用者的訂單ID最近有更新,一旦查詢的使用者命中這個Cache,那麼就強制讀主庫。由於資料的每次查詢可能落到不同的機器上,我們可以使用Redis來作為快取,解決這個問題。

Sleep方案

,這個方案聽起來很搞笑,後臺系統怎麼可以Sleep呢?要Sleep多久呢?那是,這個方案實際上是個應用最廣泛的方案,你發現沒有?當你手機喚起微信支付或者支付寶支付之後,頁面上明明只有一個返回原來APP,卻不幫你自動跳轉,跳轉回來之後,會給你彈一個支付成功頁,而不是直接回到訂單首頁,這些都是為了延長使用者的操作時間,為後臺系統爭取更加充分的時間。

其他的,還有判斷主從同步的延遲時間等多種判斷手段,感興趣的話可以繼續瞭解。

總結

好了,今天關於Mysql的讀寫分離,我們就介紹到這裡,如果你在下一次面試中遇到,希望你能引刃而解。