面试题:如何实现丝滑般的数据库扩容
初版
如果我們的線上服務(wù)不重要,一般來個單體的數(shù)據(jù)庫DB來存儲數(shù)據(jù)即可來。
單體應(yīng)用
優(yōu)點:簡單,省事,方便。
缺點:數(shù)據(jù)并發(fā)性,穩(wěn)定性都有問題。
?
進階
隨著數(shù)據(jù)量的不斷增大,一般我們要對數(shù)據(jù)進行水平切分,水平切分的規(guī)則你可以簡單根據(jù)用戶id或者用戶IP對數(shù)據(jù)進行取模,實現(xiàn)路由功能。當然也可以增加Slave跟KeepAlived來實現(xiàn)高可用。
主從+路由
但問題是,如果隨著業(yè)務(wù)發(fā)展,目前我們2個庫的性能扛不住了,還要繼續(xù)水平拆分,造出更多庫咋辦?你一般是如何實現(xiàn)絲滑擴容的呢?
?
擴容
第一版:停機擴容
停機擴容
簡單直接暴力的方法。
APP通知用戶在某個時間段停機維護升級。
新建若干個具有高可用的庫。
停止當前服務(wù),然后寫個數(shù)據(jù)遷移程序,實現(xiàn)把老庫數(shù)據(jù)全部遷移到新庫中。
修改代碼路由規(guī)則后重新對外提供服務(wù)。
優(yōu)點:簡單
缺點:中間停服務(wù)了,無法保證高可用。數(shù)據(jù)切換前跟切換過程中需確保無任何出錯。
第二版:在線雙寫
在線雙寫
建立好新到數(shù)據(jù)庫,然后接下來用戶在寫原有數(shù)據(jù)庫到同時也寫一份數(shù)據(jù)到我們的新庫中。
寫個數(shù)據(jù)遷移程序,實現(xiàn)舊庫中的歷史數(shù)據(jù)遷移到新庫中。
遷移過程中,每次插入數(shù)據(jù)時,需檢測數(shù)據(jù)的更新情況。比如,如果新的表中沒有當前的數(shù)據(jù),則直接新增;如果新表有數(shù)據(jù)并沒有我們要遷移的數(shù)據(jù)新的話,我們就更新為當前數(shù)據(jù),只能允許新的數(shù)據(jù)覆蓋舊的數(shù)據(jù),推薦使用Canal這樣到中間件。
經(jīng)過一段時間后需要校驗新庫跟舊庫兩邊數(shù)據(jù)是否一樣。如果檢查到一樣了,則直接切換即可。
優(yōu)點:高可用了。
缺點:不夠絲滑,來回挪動數(shù)據(jù)較大。
第三版:絲滑般擴容
目標:打算將原來到兩個數(shù)據(jù)庫擴容到4個。
第一步:修改配置
修改配置
修改配置信息,注意舊庫跟新庫之間到映射關(guān)系。確保擴容后數(shù)據(jù)可以正確路由到服務(wù)器。
Id % 2 = 0 的庫變?yōu)榱??id % 4 = 0 或 ? id % 4 = 2
Id % 2 = 1 的庫變?yōu)榱??id % 4 = 1 或 ? id % 4 = 3
第二步:reload配置
服務(wù)層reload配置,可以重啟服務(wù),也可以CLoud那樣配置中心發(fā)送信號來實現(xiàn)重讀配置文件。
至此,數(shù)據(jù)庫的2 --> 4 擴容完成,原來是2個數(shù)據(jù)庫實例提供服務(wù),現(xiàn)在變?yōu)?個數(shù)據(jù)庫實例提供服務(wù)。
第三步:收縮數(shù)據(jù)
絲滑擴容
此時 ?id % 4 = 0 跟 ?id % 4 = 2 的兩個DB 還在同步數(shù)據(jù)。id % 4 = 1 跟 id % 4 = 3的兩個DB還在同步數(shù)據(jù)。需做一些收尾操作。
接觸上面的兩個同步操作。
對新庫新建高可用。
刪除冗余數(shù)據(jù),比如id % 4 = 0的機器中刪除id % 4 = 2的冗余數(shù)據(jù),只為id % 4 = 0的數(shù)據(jù)提供服務(wù),其余三個類似操作。
至此實現(xiàn)成倍擴容,還避免來數(shù)據(jù)遷移。
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號
好文章,我在看??
總結(jié)
以上是生活随笔為你收集整理的面试题:如何实现丝滑般的数据库扩容的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Intellij IDEA 4种配置热部
- 下一篇: [Windows][C#][.NET][