我們?cè)?仿微博消息中心的系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn) 一文中,介紹了一個(gè)類(lèi)似于微博、網(wǎng)易云的消息中心模塊的設(shè)計(jì)和實(shí)現(xiàn)思路。今天跟大家介紹一下我們的實(shí)現(xiàn)后升級(jí)數(shù)據(jù)時(shí)踩的一些坑。
本次考慮到消息中心的數(shù)據(jù)量會(huì)比較大,所以持久層使用了阿里的 TableStore(簡(jiǎn)稱(chēng):ots)。在實(shí)現(xiàn)上,則使用了阿里提供的 TimeLine 封裝。
如果你是從 0 到 1 搭建消息中心的話(huà),該封裝基本上夠用。但如果你同我們一樣,不是從 0 到 1,需要考慮舊數(shù)據(jù)遷移的話(huà),那我建議你還是要慎重。如果數(shù)據(jù)量不是大到迫不得已,我還是建議你優(yōu)先使用關(guān)系型數(shù)據(jù)庫(kù)結(jié)合 nosql 的產(chǎn)品去實(shí)現(xiàn)。
接下來(lái)我們一起來(lái)看看升級(jí)過(guò)程可能碰到的一些坑,如果你也有一樣的場(chǎng)景,歡迎一起討論。
坑一:升級(jí)效率較低,遷移方案的開(kāi)發(fā)較繁雜。由于使用了 TimeLine,遷移時(shí),只能使用 TimeLine 的 sdk 去同步寫(xiě)(異步寫(xiě),可能會(huì)亂序)。這就導(dǎo)致了升級(jí)時(shí)間會(huì)被拖長(zhǎng)。如果數(shù)據(jù)量大的時(shí)候,這個(gè)遷移過(guò)程,就是個(gè)很大的問(wèn)題。
坑二:如果之前的消息存在不同表結(jié)構(gòu)中,然后現(xiàn)在希望表 A 和表 B 的點(diǎn)贊消息合并到一個(gè)時(shí)間線(xiàn)中,我們只能自己先將表 A 和表 B 的數(shù)據(jù)合并,然后再做升級(jí)。由于數(shù)據(jù)量都較大,這個(gè)合并的難度較大,耗時(shí)較長(zhǎng)。
坑三:由于 TimeLine 中的 sequenceId 是自增列。也就是說(shuō) sequenceId 是插入 ots 后,由 ots 自動(dòng)產(chǎn)生。那么就導(dǎo)致,我們一旦升級(jí)失敗,我們無(wú)法重復(fù)升級(jí)。我們能做的有三種。1.記住失敗的地方,然后從該處接著升。 2.遍歷查詢(xún)已升級(jí)的數(shù)據(jù),然后批量刪除(ots 的限量刪除限制 200 筆),這種刪除方式可以想象寫(xiě)起來(lái)有多蛋疼。 3.直接刪庫(kù)重建,但如果已經(jīng)升級(jí)了 90% 的數(shù)據(jù)了,這個(gè)時(shí)候去刪庫(kù),顯然不是一個(gè)很好的選擇。不管是哪種方式,其實(shí)風(fēng)險(xiǎn)都是比較高的。
坑四:如果是 2B 的企業(yè)往下看,不是的話(huà)可以跳過(guò)本段。其實(shí)這個(gè)是對(duì)坑三的補(bǔ)充,由于在 ots 沒(méi)有庫(kù)的概念,所以我們只能在一張表里去存所有租戶(hù)的數(shù)據(jù)。如果某個(gè)租戶(hù)升級(jí)時(shí)異常了,部分用戶(hù)升級(jí)一半數(shù)據(jù),我們會(huì)比較難處理。如果刪數(shù)據(jù)重升的話(huà),刪除某個(gè)租戶(hù)的數(shù)據(jù)又不好刪(只能遍歷刪除,做法低效)。如果不刪數(shù)據(jù),使用 TimeLine 又無(wú)法重復(fù)升級(jí)。這個(gè)問(wèn)題暫時(shí)無(wú)解。
關(guān)于 TimeLine 升級(jí)過(guò)程的這些坑,我們自己也無(wú)解,后續(xù)考慮不再使用 TimeLine 封裝。大家如果有碰到一樣的場(chǎng)景或類(lèi)似的問(wèn)題,歡迎留言討論!!
關(guān)于 TableStore 和 TimeLine 封裝,推薦幾篇文章,感興趣的可以去了解一下。