關(guān)于業(yè)務(wù)存儲(chǔ)結(jié)構(gòu)擴(kuò)容的方案設(shè)計(jì)和思考
今天和研發(fā)團(tuán)隊(duì)溝通一個(gè)數(shù)據(jù)存儲(chǔ)方案的設(shè)計(jì)和改造,大體的背景是在數(shù)據(jù)庫中有些id類數(shù)據(jù),如果數(shù)據(jù)類型是int,則存在一定的溢出風(fēng)險(xiǎn),在程序?qū)用嫘枰崆翱紤]修改為int64,在MySQL中可以簡單理解為bigint.
我們假設(shè)這個(gè)id字段為uid,如果是用戶業(yè)務(wù),則很多業(yè)務(wù)邏輯都是和這個(gè)uid強(qiáng)相關(guān)的,那么就會(huì)存在大量的業(yè)務(wù)梳理和研發(fā)代碼的接入,如果底層數(shù)據(jù)存儲(chǔ)的壓力和風(fēng)險(xiǎn)過大,則這個(gè)事情的改進(jìn)周期和影響范圍就會(huì)更難以評估和控制。
所以這個(gè)問題從長期來看是未雨綢繆,對已有的數(shù)據(jù)存儲(chǔ)是完全兼容的。但是從短期來看,這個(gè)調(diào)整會(huì)對已有的線上服務(wù)帶來一些風(fēng)險(xiǎn),如果涉及到約束的變更,則這個(gè)事情的復(fù)雜度會(huì)更高。為此我們經(jīng)過溝通,想到了如下的幾類解決方案:
1)新增字段uid_64,這樣已有的業(yè)務(wù)邏輯可以正常運(yùn)行,新的字段可以并行調(diào)整,當(dāng)然從數(shù)據(jù)存儲(chǔ)來看,這個(gè)代價(jià)是比較高了,而且后續(xù)調(diào)整為uid_64之后很可能需要再統(tǒng)一為uid的模式,所以從研發(fā)還是數(shù)據(jù)存儲(chǔ)來說,改造幅度都比較大。
2)在線變更,這里我說的在線變更拆分為了4類場景。
場景1:
對于一些復(fù)雜度較為可控的業(yè)務(wù),數(shù)據(jù)量也不夠大,采用在線變更的模式是比較合適的,這里我們可以使用online DDL,pt-osc或者gh-ost的方式來實(shí)現(xiàn)在線變更;
場景2:
對于一些較為復(fù)雜的業(yè)務(wù),如MySQL集群,采用了分庫分表,數(shù)據(jù)量可能在億級別,這種變更的復(fù)雜度就比較大了,而且可以肯定的是在線變更對于復(fù)雜架構(gòu)模式的風(fēng)險(xiǎn)大,而且不可控因素會(huì)更多,這里可以采用更好的應(yīng)用架構(gòu)設(shè)計(jì),基于高可用靈活切換的方式,比如整個(gè)結(jié)構(gòu)的變更都可以在從庫端進(jìn)行統(tǒng)一調(diào)整,因?yàn)檫@種數(shù)據(jù)類型的擴(kuò)容是具備兼容性的,所以原生的復(fù)制不會(huì)產(chǎn)生直接影響,而且即使執(zhí)行時(shí)間長一些,對于線上業(yè)務(wù)來說是幾乎無感知的,等變更完成之后,就可以快速通過服務(wù)切換的方式將集群從原本的主庫切換到從庫,這個(gè)過程是需要主動(dòng)觸發(fā),如果是秒級的異常,會(huì)對研發(fā)來說是直接反饋,這種情況下反而是好事。這個(gè)過程涉及的細(xì)節(jié)較多,核心思想就是從庫,異步,高可用切換;
場景3:
對于流水日志的處理方式,采用T+1的模式對于研發(fā)側(cè)來說是幾乎不需要修改主干業(yè)務(wù)邏輯就可以適配的。
場景4:
這一類場景較為復(fù)雜,比如在業(yè)務(wù)中會(huì)有不規(guī)范的使用方式,對于不規(guī)范導(dǎo)致的列名不是uid的情況,比如從xid修改為uid,在數(shù)據(jù)庫和研發(fā)側(cè)的修改代價(jià)都是比較高的,這種情況下,我是不建議使用在線變更的模式
3)業(yè)務(wù)在線遷移
這一類場景對于后端數(shù)據(jù)存儲(chǔ)是相對簡單的,就是提供一個(gè)新的數(shù)據(jù)庫,讓業(yè)務(wù)來完成整體的遷移和切換,這種情況下,對于研發(fā)的能力要求較高,所有的關(guān)鍵操作都是通過研發(fā)在線遷移的方式來實(shí)現(xiàn)。
綜上的三種方案,我是建議根據(jù)場景來靈活適配,比如方案2和方案3來組合的形式。如果后端的數(shù)據(jù)存儲(chǔ)在梳理中修改范圍更加的龐大,則需要根據(jù)細(xì)化的業(yè)務(wù)場景來選擇當(dāng)前更合適的方案。