canal數(shù)據(jù)同步方案設(shè)計(jì)
背景:
項(xiàng)目中一部分?jǐn)?shù)據(jù)如頁面靜態(tài)數(shù)據(jù)需要從redis中獲取,以提高頁面加載速度。頁面數(shù)據(jù)的修改是通過管理畫面修改mysql,通過定時(shí)任務(wù)或手動(dòng)將mysql數(shù)據(jù)同步到redis,以供頁面獲取。這里數(shù)據(jù)同步不是增量同步,而是根據(jù)條件查詢得到數(shù)據(jù)集后同步。網(wǎng)關(guān)中的一些參數(shù)同樣是在mysql維護(hù),然后定時(shí)或手動(dòng)推送到redis,并通知網(wǎng)關(guān)刷新內(nèi)存數(shù)據(jù)。有時(shí)增加一個(gè)數(shù)據(jù)的變動(dòng)會(huì)出發(fā)多個(gè)同步操作,如增加一個(gè)api,既要將其在門戶畫面展示,又要推送到網(wǎng)關(guān),如果想實(shí)時(shí)生效就需要兩次手動(dòng)操作。這樣就很繁瑣,因此設(shè)計(jì)一種實(shí)時(shí)或準(zhǔn)實(shí)時(shí)將mysql同步至redis的方案。
方案1:
更新數(shù)據(jù)庫的同時(shí)執(zhí)行同步redis方法,如在增刪改首頁數(shù)據(jù)的方法添加注解,利用aop統(tǒng)一處理數(shù)據(jù)同步的邏輯。這種方案實(shí)際就是spring cache。但是這里不僅僅要將數(shù)據(jù)同步至redis,還要發(fā)布訂閱事件,因此需要自己實(shí)現(xiàn)aop邏輯。
方案2:
利用canal,監(jiān)聽mysql數(shù)據(jù)變更進(jìn)行數(shù)據(jù)同步和發(fā)布訂閱事件。這樣不必修改原代碼,邏輯解耦。并且如果mysql修改失敗不會(huì)觸發(fā)同步操作。
綜上采用方案2。
詳細(xì)方案設(shè)計(jì):
在canal定義一個(gè)destination監(jiān)聽數(shù)據(jù)庫,當(dāng)有感興趣的數(shù)據(jù)變動(dòng)時(shí),通過feign調(diào)用對應(yīng)服務(wù)的同步方法(這里的同步方法復(fù)用已有的手動(dòng)調(diào)用方法,不用新寫)。因?yàn)橥降氖菧?zhǔn)全量數(shù)據(jù),為避免mysql每次更新都查詢,黨一個(gè)數(shù)據(jù)變動(dòng)后一分鐘內(nèi)沒有新的數(shù)據(jù)變動(dòng),才觸發(fā)同步操作。此外,通過apollo配置中心動(dòng)態(tài)啟停同步服務(wù)。
canal部署:
參照官網(wǎng)的方案,利用zookeeper進(jìn)行服務(wù)協(xié)調(diào),實(shí)現(xiàn)canal server,canal client的高可用。
由于測試環(huán)境分為SIT,QA和UAT,每個(gè)環(huán)境有單獨(dú)的數(shù)據(jù)庫,因此canal定義三個(gè)destination監(jiān)聽對應(yīng)的數(shù)據(jù)庫實(shí)例。

未來的優(yōu)化方向:
Redis獲取數(shù)據(jù)失敗fallback到數(shù)據(jù)庫
增加一層內(nèi)存緩存
感知同步數(shù)據(jù)成功與否
作者:ssd
鏈接:https://juejin.cn/post/6881578926771666951
來源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
