互聯(lián)網(wǎng)服務(wù)線上數(shù)據(jù)遷移的原則和方法
互聯(lián)網(wǎng)業(yè)務(wù)變更非???,隨著業(yè)務(wù)規(guī)模擴(kuò)大,線上的業(yè)務(wù)也會(huì)涉及重構(gòu)和遷移。比較難的就是存儲(chǔ)遷移,可能從前的存儲(chǔ)不適合新的業(yè)務(wù)模型了,例如從關(guān)系型數(shù)據(jù)庫(kù)遷移到nosql,或者數(shù)據(jù)的存儲(chǔ)格式發(fā)生了巨大的變化。
為什么說(shuō)涉及數(shù)據(jù)遷移的業(yè)務(wù)最難呢?因?yàn)閿?shù)據(jù)是有狀態(tài)的,不像邏輯和接入層,方便灰度,即使出問(wèn)題馬上回滾就能恢復(fù)(如果涉及寫數(shù)據(jù)也也有問(wèn)題)。然而數(shù)據(jù)是有狀態(tài)的,如果切換后發(fā)現(xiàn)新的寫存儲(chǔ)數(shù)據(jù)有問(wèn)題,是很難修復(fù)的,也很難發(fā)現(xiàn)的。
任何遷移或更新,涉及到數(shù)據(jù)的,都有一個(gè)原則:要有驗(yàn)證比對(duì)和回滾能力。
驗(yàn)證比對(duì)
數(shù)據(jù)遷移后,要有辦法驗(yàn)證這次遷移是成功的,沒(méi)問(wèn)題的。只是從代碼上說(shuō),看,前后邏輯都一樣,肯定沒(méi)問(wèn)題是靠不住的。我們要從結(jié)果,從用戶的角度來(lái)驗(yàn)證,查看新老數(shù)據(jù)是否一致,是否有問(wèn)題。
一般的方法是雙寫。老的數(shù)據(jù)庫(kù)還對(duì)外服務(wù),把寫操作同步一份給新數(shù)據(jù)庫(kù),兩個(gè)庫(kù)一起寫。把有改動(dòng)的用戶數(shù)據(jù)同步過(guò)來(lái),然后再寫一個(gè)同步程序,把所有用戶的全量數(shù)據(jù)導(dǎo)過(guò)來(lái)。檢測(cè)程序,能夠根據(jù)每個(gè)key進(jìn)行比對(duì),定期把庫(kù)里所有的數(shù)據(jù)進(jìn)行新老比對(duì),當(dāng)比對(duì)率達(dá)到閾值以后。還要做一個(gè)數(shù)據(jù)比對(duì)層,用戶讀寫的時(shí)候先走比對(duì)層,同時(shí)給新老兩個(gè)邏輯層同步包,也接收回包。然后把回包進(jìn)行二進(jìn)制比對(duì),保證返回給用戶的數(shù)據(jù)也是一致的。
當(dāng)都達(dá)到一致之后,就可以切換了,切換后以新層為主,老層為輔,也接收同步數(shù)據(jù)。
回滾數(shù)據(jù)能力
為什么驗(yàn)證比對(duì)里最后老層還要接收新層的同步呢,直接切換不好嗎?是因?yàn)槿f(wàn)一切換后出現(xiàn)bug,發(fā)現(xiàn)其他地方有問(wèn)題,可以馬上回滾回老數(shù)據(jù)。保證線上服務(wù)正常,給開發(fā)修復(fù)bug留下充足的時(shí)間,不會(huì)有很大的時(shí)間壓力。如果不能馬上回滾,只能在線修bug。后續(xù)的每次發(fā)布修改,對(duì)開發(fā)的個(gè)人能力和狀態(tài)依賴大,不可控因素太多。很難保證服務(wù)質(zhì)量。
再多說(shuō)一下,由于是重構(gòu),有時(shí)會(huì)發(fā)現(xiàn)從前數(shù)據(jù)里的錯(cuò)數(shù)據(jù),或邏輯bug。不建議馬上修復(fù),新的要先和老的邏輯數(shù)據(jù)對(duì)齊,穩(wěn)定后再修復(fù)老bug。否則bug改完后就沒(méi)有一個(gè)標(biāo)桿來(lái)驗(yàn)證數(shù)據(jù)是否一致了。
有人會(huì)說(shuō),弄這么多,得多久能完成遷移啊,效率太低??荚囶}目做的再快,不對(duì)也是白搭,之所以做這么多,就是保證萬(wàn)無(wú)一失。欲速則不達(dá),如果數(shù)據(jù)錯(cuò)了再去修補(bǔ),時(shí)間花費(fèi)的更多,而且有時(shí)是補(bǔ)不回來(lái)的,只能回檔,那時(shí)給用戶造成的損失就大了。在QQ后臺(tái),每次數(shù)據(jù)遷移都要經(jīng)過(guò)幾周的發(fā)布比對(duì)才能切換,重大的數(shù)據(jù)層重構(gòu),沒(méi)個(gè)一年半載達(dá)到六個(gè)9的一致性,根本不會(huì)切換的。這也是為什么一次次在行動(dòng)的火車上換發(fā)動(dòng)機(jī)能夠成功的原因!
總結(jié)
涉及到數(shù)據(jù)的變更發(fā)布,要有比對(duì)能力,有從結(jié)果出發(fā)的方法,能夠驗(yàn)證數(shù)據(jù)遷移后是正常的才可以。只從代碼邏輯層面分析是不靠譜的。
要有plan B,如果真的有問(wèn)題,要能夠回滾,有回旋的余地。
做到以上所說(shuō),才能立于平滑遷移數(shù)據(jù)服務(wù)的不敗之地!