緩存一致性和跨服務器查詢的數據異構解決方案canal

轉載:?緩存一致性和跨服務器查詢的數據異構解決方案canal


緩存一致性和跨服務器查詢的數據異構解決方案canal

當你的項目數據量上去了之后,通常會遇到兩種情況,第一種情況應是最大可能的使用cache來對抗上層的高并發,第二種情況同樣也是需要使用分庫

分表對抗上層的高并發。。。逼逼逼起來容易,做起來并不那么樂觀,由此引入的問題,不見得你有好的解決方案,下面就具體分享下。

一:盡可能的使用Cache

比如在我們的千人千面系統中,會針對商品,訂單等維度為某一個商家店鋪自動化建立大約400個數據模型,然后買家在淘寶下訂單之后,淘寶會將訂單推

送過來,訂單會在400個模型中兜一圈,從而推送更貼切符合該買家行為習慣的短信和郵件,這是一個真實的業務場景,為了應對高并發,這些模型自然都是緩

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

redis。。。對吧,如下圖:

說的簡單,web開發的程序員會說,麻蛋的,我管你什么業務,更新你妹啊。。。我把自己的手頭代碼寫好就可以了,我要高內聚,所以你必須碰一鼻子灰。

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

無法保證這個db和cache的緩存一致性,那這個時候能不能換個思路,我直接寫個程序訂閱database的binlog,從binlog中分析出模型數據的CURD操作,根

據這些CURD的實際情況更新Redis的緩存數據,第一個可以實現和web的解耦,第二個實現了高度的緩存一致性,所以新的架構是這樣的。

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

一個偽裝成mysql的slave,不斷的通過dump命令從mysql中盜出binlog日志,從而完美的實現了這個需求。

二:數據異構

本篇開頭也說到了,數據量大了之后,必然會存在分庫分表,甚至database都要分散到多臺服務器上,現在的電商項目,都是業務趕著技術跑。。。

誰也不知道下一個業務會是一個怎樣的奇葩,所以必然會導致你要做一些跨服務器join查詢,你以為自己很聰明,其實DBA早就把跨服務器查詢的函數給你

關掉了,求爹爹拜奶奶都不會給你開的,除非你殺一個DBA祭天,不過如果你的業務真的很重要,可能DBA會給你做數據異構,所謂的數據異構,那就是

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

那如果用canal來訂閱binlog,就可以改造成下面這種架構。

三:搭建一覽

好了,canal的應用場景給大家也介紹到了,最主要是理解這種思想,人家搞不定的東西,你的價值就出來了。

1. 開啟mysql的binlog功能

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

my.ini。

2. 驗證binlog是否開啟

使用命令驗證,并且開啟binlog的過期時間為30天,默認情況下binlog是不過期的,這就導致你的磁盤可能會爆滿,直到掛掉。

3. 給canal服務器分配一個mysql的賬號權限,方便canal去偷binlog日志。

4. 下載canal

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

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

6. canal 和 instance 配置文件

canal的模式是這樣的,一個canal里面可能會有多個instance,也就說一個instance可以監控一個mysql實例,多個instance也就可以對應多臺服務器

的mysql實例。也就是一個canal就可以監控分庫分表下的多機器mysql。

《1》 canal.properties

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

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

canal.port= 11111       當前canal的服務器端口號

canal.destinations= example     當前默認開啟了一個名為example的instance實例,如果想開多個instance,用","逗號隔開就可以了。。。

canal.instance.filter.regex = .*\..*   mysql實例下的所有db的所有表都在監控范圍內。

《2》 instance.properties

這個就是具體的某個instances實例的配置,未涉及到的配置都會從canal.properties上繼承。

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

7. 開啟canal

大家要記得把/canal/bin 目錄配置到 /etc/profile 的 Path中,方便快速開啟,通過下圖你會看到11111端口已經在centos上開啟了。

8. Java Client 代碼

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

9. 啟動java代碼進行驗證

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

<1> Update操作

<2> Insert操作

<3> Delete 操作

從結果中看,沒毛病,有圖有真相,好了,本篇就說到這里,對于開發的你,肯定是有幫助的~~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容