緩存一致性和跨服務(wù)器查詢的數(shù)據(jù)異構(gòu)解決方案canal

轉(zhuǎn)載:?緩存一致性和跨服務(wù)器查詢的數(shù)據(jù)異構(gòu)解決方案canal


緩存一致性和跨服務(wù)器查詢的數(shù)據(jù)異構(gòu)解決方案canal

當(dāng)你的項(xiàng)目數(shù)據(jù)量上去了之后,通常會(huì)遇到兩種情況,第一種情況應(yīng)是最大可能的使用cache來(lái)對(duì)抗上層的高并發(fā),第二種情況同樣也是需要使用分庫(kù)

分表對(duì)抗上層的高并發(fā)。。。逼逼逼起來(lái)容易,做起來(lái)并不那么樂(lè)觀,由此引入的問(wèn)題,不見(jiàn)得你有好的解決方案,下面就具體分享下。

一:盡可能的使用Cache

比如在我們的千人千面系統(tǒng)中,會(huì)針對(duì)商品,訂單等維度為某一個(gè)商家店鋪?zhàn)詣?dòng)化建立大約400個(gè)數(shù)據(jù)模型,然后買家在淘寶下訂單之后,淘寶會(huì)將訂單推

送過(guò)來(lái),訂單會(huì)在400個(gè)模型中兜一圈,從而推送更貼切符合該買家行為習(xí)慣的短信和郵件,這是一個(gè)真實(shí)的業(yè)務(wù)場(chǎng)景,為了應(yīng)對(duì)高并發(fā),這些模型自然都是緩

存在Cache中,模型都是從db中灌到redis的,那如果有新的模型進(jìn)來(lái)了,我如何通知redis進(jìn)行緩存更新呢???通常的做法就是在添加模型的時(shí)候,順便更新

redis。。。對(duì)吧,如下圖:

說(shuō)的簡(jiǎn)單,web開(kāi)發(fā)的程序員會(huì)說(shuō),麻蛋的,我管你什么業(yè)務(wù),更新你妹啊。。。我把自己的手頭代碼寫(xiě)好就可以了,我要高內(nèi)聚,所以你必須碰一鼻子灰。

除了一鼻子灰之后,也許你還會(huì)遇到更新database成功,再更新redis的時(shí)候失敗,可人家不管,而且錯(cuò)誤日志還是別人的日志系統(tǒng)里面,所以你很難甚至

無(wú)法保證這個(gè)db和cache的緩存一致性,那這個(gè)時(shí)候能不能換個(gè)思路,我直接寫(xiě)個(gè)程序訂閱database的binlog,從binlog中分析出模型數(shù)據(jù)的CURD操作,根

據(jù)這些CURD的實(shí)際情況更新Redis的緩存數(shù)據(jù),第一個(gè)可以實(shí)現(xiàn)和web的解耦,第二個(gè)實(shí)現(xiàn)了高度的緩存一致性,所以新的架構(gòu)是這樣的。

上面這張圖,相信大家都能看得懂,重點(diǎn)就是這個(gè)處理binlog程序,從binlog中分析出CURD從而更新Redis,其實(shí)這個(gè)binlog程序就是本篇所說(shuō)的canal。。。

一個(gè)偽裝成mysql的slave,不斷的通過(guò)dump命令從mysql中盜出binlog日志,從而完美的實(shí)現(xiàn)了這個(gè)需求。

二:數(shù)據(jù)異構(gòu)

本篇開(kāi)頭也說(shuō)到了,數(shù)據(jù)量大了之后,必然會(huì)存在分庫(kù)分表,甚至database都要分散到多臺(tái)服務(wù)器上,現(xiàn)在的電商項(xiàng)目,都是業(yè)務(wù)趕著技術(shù)跑。。。

誰(shuí)也不知道下一個(gè)業(yè)務(wù)會(huì)是一個(gè)怎樣的奇葩,所以必然會(huì)導(dǎo)致你要做一些跨服務(wù)器join查詢,你以為自己很聰明,其實(shí)DBA早就把跨服務(wù)器查詢的函數(shù)給你

關(guān)掉了,求爹爹拜奶奶都不會(huì)給你開(kāi)的,除非你殺一個(gè)DBA祭天,不過(guò)如果你的業(yè)務(wù)真的很重要,可能DBA會(huì)給你做數(shù)據(jù)異構(gòu),所謂的數(shù)據(jù)異構(gòu),那就是

將需要join查詢的多表按照某一個(gè)維度又聚合在一個(gè)DB中。讓你去查詢。。。。。

那如果用canal來(lái)訂閱binlog,就可以改造成下面這種架構(gòu)。

三:搭建一覽

好了,canal的應(yīng)用場(chǎng)景給大家也介紹到了,最主要是理解這種思想,人家搞不定的東西,你的價(jià)值就出來(lái)了。

1. 開(kāi)啟mysql的binlog功能

開(kāi)啟binlog,并且將binlog的格式改為Row,這樣就可以獲取到CURD的二進(jìn)制內(nèi)容,windows上的路徑為:C:Program FilesMySQLMySQL Server 5.7

my.ini。

2. 驗(yàn)證binlog是否開(kāi)啟

使用命令驗(yàn)證,并且開(kāi)啟binlog的過(guò)期時(shí)間為30天,默認(rèn)情況下binlog是不過(guò)期的,這就導(dǎo)致你的磁盤可能會(huì)爆滿,直到掛掉。

3. 給canal服務(wù)器分配一個(gè)mysql的賬號(hào)權(quán)限,方便canal去偷binlog日志。

4. 下載canal

github的地址: https://github.com/alibaba/canal/releases

5. 然后就是各種解壓的命令

6. canal 和 instance 配置文件

canal的模式是這樣的,一個(gè)canal里面可能會(huì)有多個(gè)instance,也就說(shuō)一個(gè)instance可以監(jiān)控一個(gè)mysql實(shí)例,多個(gè)instance也就可以對(duì)應(yīng)多臺(tái)服務(wù)器

的mysql實(shí)例。也就是一個(gè)canal就可以監(jiān)控分庫(kù)分表下的多機(jī)器mysql。

《1》 canal.properties

它是全局性的canal服務(wù)器配置,具體如下,這里面的參數(shù)涉及到方方面面。

由于是全局性的配置,所以上面三處標(biāo)紅的地方要注意一下:

canal.port= 11111       當(dāng)前canal的服務(wù)器端口號(hào)

canal.destinations= example     當(dāng)前默認(rèn)開(kāi)啟了一個(gè)名為example的instance實(shí)例,如果想開(kāi)多個(gè)instance,用","逗號(hào)隔開(kāi)就可以了。。。

canal.instance.filter.regex = .*\..*   mysql實(shí)例下的所有db的所有表都在監(jiān)控范圍內(nèi)。

《2》 instance.properties

這個(gè)就是具體的某個(gè)instances實(shí)例的配置,未涉及到的配置都會(huì)從canal.properties上繼承。

上面標(biāo)紅的地方注意下就好了,去偷binlog的時(shí)候,需要知道的mysql地址和用戶名,密碼。

7. 開(kāi)啟canal

大家要記得把/canal/bin 目錄配置到 /etc/profile 的 Path中,方便快速開(kāi)啟,通過(guò)下圖你會(huì)看到11111端口已經(jīng)在centos上開(kāi)啟了。

8. Java Client 代碼

canal driver 需要在maven倉(cāng)庫(kù)中獲取一下:https://www.mvnrepository.com/artifact/com.alibaba.otter/canal.client/1.0.24,不過(guò)依賴還是蠻多的。

9. 啟動(dòng)java代碼進(jìn)行驗(yàn)證

下面的代碼對(duì)table的CURD都做了一個(gè)基本的判斷,看看是不是能夠智能感知,然后可以根據(jù)實(shí)際情況進(jìn)行redis的更新操作。。。

<1> Update操作

<2> Insert操作

<3> Delete 操作

從結(jié)果中看,沒(méi)毛病,有圖有真相,好了,本篇就說(shuō)到這里,對(duì)于開(kāi)發(fā)的你,肯定是有幫助的~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容