01 為什么要理解Redis緩存問(wèn)題?
在高并發(fā)的業(yè)務(wù)場(chǎng)景下胳赌,數(shù)據(jù)庫(kù)大多數(shù)情況都是用戶并發(fā)訪問(wèn)最薄弱的環(huán)節(jié)牢撼。所以,就需要使用redis做一個(gè)緩沖操作匈织,讓請(qǐng)求先訪問(wèn)到redis浪默,而不是直接訪問(wèn)Mysql等數(shù)據(jù)庫(kù)牡直。這樣可以大大緩解數(shù)據(jù)庫(kù)的壓力缀匕。
當(dāng)緩存庫(kù)出現(xiàn)時(shí),必須要考慮如下問(wèn)題:
緩存穿透
緩存穿擊
緩存雪崩
緩存污染(或者滿了)
緩存和數(shù)據(jù)庫(kù)一致性
02 緩存穿透
問(wèn)題來(lái)源
緩存穿透是指緩存和數(shù)據(jù)庫(kù)中都沒(méi)有的數(shù)據(jù)碰逸,而用戶不斷發(fā)起請(qǐng)求乡小。由于緩存是不命中時(shí)被動(dòng)寫(xiě)的,并且出于容錯(cuò)考慮饵史,如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫(xiě)入緩存满钟,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到存儲(chǔ)層去查詢,失去了緩存的意義胳喷。
在流量大時(shí)湃番,可能DB就掛掉了,要是有人利用不存在的key頻繁攻擊我們的應(yīng)用吭露,這就是漏洞吠撮。
如發(fā)起為id為“-1”的數(shù)據(jù)或id為特別大不存在的數(shù)據(jù)。這時(shí)的用戶很可能是攻擊者讲竿,攻擊會(huì)導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大泥兰。
解決方案
接口層增加校驗(yàn),如用戶鑒權(quán)校驗(yàn)题禀,id做基礎(chǔ)校驗(yàn)鞋诗,id<=0的直接攔截;
從緩存取不到的數(shù)據(jù)迈嘹,在數(shù)據(jù)庫(kù)中也沒(méi)有取到削彬,這時(shí)也可以將key-value對(duì)寫(xiě)為key-null,緩存有效時(shí)間可以設(shè)置短點(diǎn),如30秒(設(shè)置太長(zhǎng)會(huì)導(dǎo)致正常情況也沒(méi)法使用)融痛。這樣可以防止攻擊用戶反復(fù)用同一個(gè)id暴力攻擊
布隆過(guò)濾器糕篇。bloomfilter就類似于一個(gè)hash set,用于快速判某個(gè)元素是否存在于集合中酌心,其典型的應(yīng)用場(chǎng)景就是快速判斷一個(gè)key是否存在于某容器拌消,不存在就直接返回。布隆過(guò)濾器的關(guān)鍵就在于hash算法和容器大小安券,
03 緩存擊穿
問(wèn)題來(lái)源
緩存擊穿是指緩存中沒(méi)有但數(shù)據(jù)庫(kù)中有的數(shù)據(jù)(一般是緩存時(shí)間到期)墩崩,這時(shí)由于并發(fā)用戶特別多,同時(shí)讀緩存沒(méi)讀到數(shù)據(jù)侯勉,又同時(shí)去數(shù)據(jù)庫(kù)去取數(shù)據(jù)鹦筹,引起數(shù)據(jù)庫(kù)壓力瞬間增大,造成過(guò)大壓力址貌。
解決方案
1铐拐、設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過(guò)期。
2练对、接口限流與熔斷遍蟋,降級(jí)。重要的接口一定要做好限流策略螟凭,防止用戶惡意刷接口虚青,同時(shí)要降級(jí)準(zhǔn)備,當(dāng)接口中的某些 服務(wù) 不可用時(shí)候螺男,進(jìn)行熔斷棒厘,失敗快速返回機(jī)制。
3下隧、加互斥鎖
04 緩存雪崩
問(wèn)題來(lái)源
緩存雪崩是指緩存中數(shù)據(jù)大批量到過(guò)期時(shí)間奢人,而查詢數(shù)據(jù)量巨大,引起數(shù)據(jù)庫(kù)壓力過(guò)大甚至down機(jī)淆院。和緩存擊穿不同的是何乎,緩存擊穿指并發(fā)查同一條數(shù)據(jù),緩存雪崩是不同數(shù)據(jù)都過(guò)期了迫筑,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫(kù)宪赶。
解決方案
緩存數(shù)據(jù)的過(guò)期時(shí)間設(shè)置隨機(jī),防止同一時(shí)間大量數(shù)據(jù)過(guò)期現(xiàn)象發(fā)生脯燃。
如果緩存數(shù)據(jù)庫(kù)是分布式部署搂妻,將熱點(diǎn)數(shù)據(jù)均勻分布在不同的緩存數(shù)據(jù)庫(kù)中。
設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過(guò)期辕棚。
05 緩存污染(或滿了)
緩存污染問(wèn)題說(shuō)的是緩存中一些只會(huì)被訪問(wèn)一次或者幾次的的數(shù)據(jù)欲主,被訪問(wèn)完后邓厕,再也不會(huì)被訪問(wèn)到,但這部分?jǐn)?shù)據(jù)依然留存在緩存中扁瓢,消耗緩存空間详恼。
緩存污染會(huì)隨著數(shù)據(jù)的持續(xù)增加而逐漸顯露,隨著服務(wù)的不斷運(yùn)行引几,緩存中會(huì)存在大量的永遠(yuǎn)不會(huì)再次被訪問(wèn)的數(shù)據(jù)昧互。緩存空間是有限的,如果緩存空間滿了伟桅,再往緩存里寫(xiě)數(shù)據(jù)時(shí)就會(huì)有額外開(kāi)銷敞掘,影響Redis性能。這部分額外開(kāi)銷主要是指寫(xiě)的時(shí)候判斷淘汰策略楣铁,根據(jù)淘汰策略去選擇要淘汰的數(shù)據(jù)玖雁,然后進(jìn)行刪除操作。
5.1 最大緩存設(shè)置多大
系統(tǒng)的設(shè)計(jì)選擇是一個(gè)權(quán)衡的過(guò)程:大容量緩存是能帶來(lái)性能加速的收益盖腕,但是成本也會(huì)更高赫冬,而小容量緩存不一定就起不到加速訪問(wèn)的效果。一般來(lái)說(shuō)溃列,我會(huì)建議把緩存容量設(shè)置為總數(shù)據(jù)量的 15% 到 30%劲厌,兼顧訪問(wèn)性能和內(nèi)存空間開(kāi)銷。
對(duì)于 Redis 來(lái)說(shuō)哭廉,一旦確定了緩存最大容量脊僚,比如 4GB,你就可以使用下面這個(gè)命令來(lái)設(shè)定緩存的大小了:
CONFIGSET maxmemory 4gb@pdai: 代碼已經(jīng)復(fù)制到剪貼板
不過(guò)遵绰,緩存被寫(xiě)滿是不可避免的, 所以需要數(shù)據(jù)淘汰策略。
5.2 緩存淘汰策略
Redis共支持八種淘汰策略增淹,分別是noeviction椿访、volatile-random、volatile-ttl虑润、volatile-lru成玫、volatile-lfu、allkeys-lru拳喻、allkeys-random 和 allkeys-lfu 策略哭当。
怎么理解呢?主要看分三類看:
不淘汰
noeviction (v4.0后默認(rèn)的)
對(duì)設(shè)置了過(guò)期時(shí)間的數(shù)據(jù)中進(jìn)行淘汰
隨機(jī):volatile-random
ttl:volatile-ttl
lru:volatile-lru
lfu:volatile-lfu
全部數(shù)據(jù)進(jìn)行淘汰
隨機(jī):allkeys-random
lru:allkeys-lru
lfu:allkeys-lfu
具體對(duì)照下:
noeviction
該策略是Redis的默認(rèn)策略冗澈。在這種策略下钦勘,一旦緩存被寫(xiě)滿了,再有寫(xiě)請(qǐng)求來(lái)時(shí)亚亲,Redis 不再提供服務(wù)彻采,而是直接返回錯(cuò)誤腐缤。這種策略不會(huì)淘汰數(shù)據(jù),所以無(wú)法解決緩存污染問(wèn)題肛响。一般生產(chǎn)環(huán)境不建議使用岭粤。
其他七種規(guī)則都會(huì)根據(jù)自己相應(yīng)的規(guī)則來(lái)選擇數(shù)據(jù)進(jìn)行刪除操作。
volatile-random
這個(gè)算法比較簡(jiǎn)單特笋,在設(shè)置了過(guò)期時(shí)間的鍵值對(duì)中剃浇,進(jìn)行隨機(jī)刪除。因?yàn)槭请S機(jī)刪除猎物,無(wú)法把不再訪問(wèn)的數(shù)據(jù)篩選出來(lái)偿渡,所以可能依然會(huì)存在緩存污染現(xiàn)象,無(wú)法解決緩存污染問(wèn)題霸奕。
volatile-ttl
這種算法判斷淘汰數(shù)據(jù)時(shí)參考的指標(biāo)比隨即刪除時(shí)多進(jìn)行一步過(guò)期時(shí)間的排序溜宽。Redis在篩選需刪除的數(shù)據(jù)時(shí),越早過(guò)期的數(shù)據(jù)越優(yōu)先被選擇质帅。
volatile-lru
LRU算法:LRU 算法的全稱是 Least Recently Used适揉,按照最近最少使用的原則來(lái)篩選數(shù)據(jù)。這種模式下會(huì)使用 LRU 算法篩選設(shè)置了過(guò)期時(shí)間的鍵值對(duì)煤惩。
Redis優(yōu)化的LRU算法實(shí)現(xiàn):
Redis會(huì)記錄每個(gè)數(shù)據(jù)的最近一次被訪問(wèn)的時(shí)間戳嫉嘀。在Redis在決定淘汰的數(shù)據(jù)時(shí),第一次會(huì)隨機(jī)選出 N 個(gè)數(shù)據(jù)魄揉,把它們作為一個(gè)候選集合剪侮。接下來(lái),Redis 會(huì)比較這 N 個(gè)數(shù)據(jù)的 lru 字段洛退,把 lru 字段值最小的數(shù)據(jù)從緩存中淘汰出去瓣俯。通過(guò)隨機(jī)讀取待刪除集合,可以讓Redis不用維護(hù)一個(gè)巨大的鏈表兵怯,也不用操作鏈表彩匕,進(jìn)而提升性能。
Redis 選出的數(shù)據(jù)個(gè)數(shù) N媒区,通過(guò) 配置參數(shù) maxmemory-samples 進(jìn)行配置驼仪。個(gè)數(shù)N越大,則候選集合越大袜漩,選擇到的最久未被使用的就更準(zhǔn)確绪爸,N越小,選擇到最久未被使用的數(shù)據(jù)的概率也會(huì)隨之減小宙攻。
volatile-lfu
會(huì)使用 LFU 算法選擇設(shè)置了過(guò)期時(shí)間的鍵值對(duì)奠货。
LFU 算法:LFU 緩存策略是在 LRU 策略基礎(chǔ)上,為每個(gè)數(shù)據(jù)增加了一個(gè)計(jì)數(shù)器粘优,來(lái)統(tǒng)計(jì)這個(gè)數(shù)據(jù)的訪問(wèn)次數(shù)仇味。當(dāng)使用 LFU 策略篩選淘汰數(shù)據(jù)時(shí)呻顽,首先會(huì)根據(jù)數(shù)據(jù)的訪問(wèn)次數(shù)進(jìn)行篩選,把訪問(wèn)次數(shù)最低的數(shù)據(jù)淘汰出緩存丹墨。如果兩個(gè)數(shù)據(jù)的訪問(wèn)次數(shù)相同廊遍,LFU 策略再比較這兩個(gè)數(shù)據(jù)的訪問(wèn)時(shí)效性,把距離上一次訪問(wèn)時(shí)間更久的數(shù)據(jù)淘汰出緩存贩挣。 Redis的LFU算法實(shí)現(xiàn):
當(dāng) LFU 策略篩選數(shù)據(jù)時(shí)喉前,Redis 會(huì)在候選集合中,根據(jù)數(shù)據(jù) lru 字段的后 8bit 選擇訪問(wèn)次數(shù)最少的數(shù)據(jù)進(jìn)行淘汰王财。當(dāng)訪問(wèn)次數(shù)相同時(shí)卵迂,再根據(jù) lru 字段的前 16bit 值大小,選擇訪問(wèn)時(shí)間最久遠(yuǎn)的數(shù)據(jù)進(jìn)行淘汰绒净。
Redis 只使用了 8bit 記錄數(shù)據(jù)的訪問(wèn)次數(shù)见咒,而 8bit 記錄的最大值是 255,這樣在訪問(wèn)快速的情況下挂疆,如果每次被訪問(wèn)就將訪問(wèn)次數(shù)加一改览,很快某條數(shù)據(jù)就達(dá)到最大值255,可能很多數(shù)據(jù)都是255缤言,那么退化成LRU算法了宝当。所以Redis為了解決這個(gè)問(wèn)題,實(shí)現(xiàn)了一個(gè)更優(yōu)的計(jì)數(shù)規(guī)則胆萧,并可以通過(guò)配置項(xiàng)庆揩,來(lái)控制計(jì)數(shù)器增加的速度。
參數(shù)?:
lfu-log-factor 跌穗,用計(jì)數(shù)器當(dāng)前的值乘以配置項(xiàng) lfu_log_factor 再加 1订晌,再取其倒數(shù),得到一個(gè) p 值瞻离;然后腾仅,把這個(gè) p 值和一個(gè)取值范圍在(0,1)間的隨機(jī)數(shù) r 值比大小套利,只有 p 值大于 r 值時(shí),計(jì)數(shù)器才加 1鹤耍。
lfu-decay-time肉迫, 控制訪問(wèn)次數(shù)衰減。LFU 策略會(huì)計(jì)算當(dāng)前時(shí)間和數(shù)據(jù)最近一次訪問(wèn)時(shí)間的差值稿黄,并把這個(gè)差值換算成以分鐘為單位喊衫。然后,LFU 策略再把這個(gè)差值除以 lfu_decay_time 值杆怕,所得的結(jié)果就是數(shù)據(jù) counter 要衰減的值族购。
lfu-log-factor設(shè)置越大壳贪,遞增概率越低,lfu-decay-time設(shè)置越大寝杖,衰減速度會(huì)越慢违施。
我們?cè)趹?yīng)用 LFU 策略時(shí),一般可以將 lfu_log_factor 取值為 10瑟幕。 如果業(yè)務(wù)應(yīng)用中有短時(shí)高頻訪問(wèn)的數(shù)據(jù)的話磕蒲,建議把 lfu_decay_time 值設(shè)置為 1≈豁铮可以快速衰減訪問(wèn)次數(shù)辣往。
volatile-lfu 策略是 Redis 4.0 后新增。
allkeys-lru
使用 LRU 算法在所有數(shù)據(jù)中進(jìn)行篩選殖卑。具體LFU算法跟上述 volatile-lru 中介紹的一致站削,只是篩選的數(shù)據(jù)范圍是全部緩存,這里就不在重復(fù)孵稽。
allkeys-random
從所有鍵值對(duì)中隨機(jī)選擇并刪除數(shù)據(jù)许起。volatile-random 跟 allkeys-random算法一樣,隨機(jī)刪除就無(wú)法解決緩存污染問(wèn)題肛冶。
allkeys-lfu?使用 LFU 算法在所有數(shù)據(jù)中進(jìn)行篩選街氢。具體LFU算法跟上述 volatile-lfu 中介紹的一致,只是篩選的數(shù)據(jù)范圍是全部緩存睦袖,這里就不在重復(fù)珊肃。
allkeys-lfu 策略是 Redis 4.0 后新增。
06 數(shù)據(jù)庫(kù)和緩存一致性
問(wèn)題來(lái)源
使用redis做一個(gè)緩沖操作馅笙,讓請(qǐng)求先訪問(wèn)到redis伦乔,而不是直接訪問(wèn)MySQL等數(shù)據(jù)庫(kù):
讀取緩存步驟一般沒(méi)有什么問(wèn)題,但是一旦涉及到數(shù)據(jù)更新:數(shù)據(jù)庫(kù)和緩存更新董习,就容易出現(xiàn)緩存(Redis)和數(shù)據(jù)庫(kù)(MySQL)間的數(shù)據(jù)一致性問(wèn)題烈和。
不管是先寫(xiě)MySQL數(shù)據(jù)庫(kù),再刪除Redis緩存皿淋;還是先刪除緩存招刹,再寫(xiě)庫(kù),都有可能出現(xiàn)數(shù)據(jù)不一致的情況窝趣。舉一個(gè)例子:
1.如果刪除了緩存Redis疯暑,還沒(méi)有來(lái)得及寫(xiě)庫(kù)MySQL,另一個(gè)線程就來(lái)讀取哑舒,發(fā)現(xiàn)緩存為空妇拯,則去數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)寫(xiě)入緩存,此時(shí)緩存中為臟數(shù)據(jù)洗鸵。
2.如果先寫(xiě)了庫(kù)越锈,在刪除緩存前仗嗦,寫(xiě)庫(kù)的線程宕機(jī)了,沒(méi)有刪除掉緩存甘凭,則也會(huì)出現(xiàn)數(shù)據(jù)不一致情況稀拐。
因?yàn)閷?xiě)和讀是并發(fā)的,沒(méi)法保證順序,就會(huì)出現(xiàn)緩存和數(shù)據(jù)庫(kù)的數(shù)據(jù)不一致的問(wèn)題对蒲。
6.1 4種相關(guān)模式
更新緩存的的Design Pattern有四種:Cache aside, Read through, Write through, Write behind caching; 我強(qiáng)烈建議你看看這篇钩蚊,左耳朵耗子的文章:緩存更新的套路 (opens new window)
節(jié)選最最常用的Cache Aside Pattern, 總結(jié)來(lái)說(shuō)就是
讀的時(shí)候,先讀緩存蹈矮,緩存沒(méi)有的話砰逻,就讀數(shù)據(jù)庫(kù),然后取出數(shù)據(jù)后放入緩存泛鸟,同時(shí)返回響應(yīng)蝠咆。
更新的時(shí)候,先更新數(shù)據(jù)庫(kù)北滥,然后再刪除緩存刚操。
其具體邏輯如下:
失效:應(yīng)用程序先從cache取數(shù)據(jù),沒(méi)有得到再芋,則從數(shù)據(jù)庫(kù)中取數(shù)據(jù)菊霜,成功后,放到緩存中济赎。
命中:應(yīng)用程序從cache中取數(shù)據(jù)鉴逞,取到后返回。
更新:先把數(shù)據(jù)存到數(shù)據(jù)庫(kù)中司训,成功后构捡,再讓緩存失效。
注意壳猜,我們的更新是先更新數(shù)據(jù)庫(kù)勾徽,成功后,讓緩存失效统扳。那么喘帚,這種方式是否可以沒(méi)有文章前面提到過(guò)的那個(gè)問(wèn)題呢?我們可以腦補(bǔ)一下咒钟。
一個(gè)是查詢操作啥辨,一個(gè)是更新操作的并發(fā),首先盯腌,沒(méi)有了刪除cache數(shù)據(jù)的操作了,而是先更新了數(shù)據(jù)庫(kù)中的數(shù)據(jù)陨瘩,此時(shí)腕够,緩存依然有效级乍,所以,并發(fā)的查詢操作拿的是沒(méi)有更新的數(shù)據(jù)帚湘,但是玫荣,更新操作馬上讓緩存的失效了,后續(xù)的查詢操作再把數(shù)據(jù)從數(shù)據(jù)庫(kù)中拉出來(lái)大诸。而不會(huì)像文章開(kāi)頭的那個(gè)邏輯產(chǎn)生的問(wèn)題捅厂,后續(xù)的查詢操作一直都在取老的數(shù)據(jù)。
這是標(biāo)準(zhǔn)的design pattern资柔,包括Facebook的論文《Scaling Memcache at Facebook (opens new window)》也使用了這個(gè)策略焙贷。為什么不是寫(xiě)完數(shù)據(jù)庫(kù)后更新緩存?你可以看一下Quora上的這個(gè)問(wèn)答《Why does Facebook use delete to remove the key-value pair in Memcached instead of updating the Memcached during write request to the backend? (opens new window)》贿堰,主要是怕兩個(gè)并發(fā)的寫(xiě)操作導(dǎo)致臟數(shù)據(jù)辙芍。
那么,是不是Cache Aside這個(gè)就不會(huì)有并發(fā)問(wèn)題了羹与?不是的故硅,比如,一個(gè)是讀操作纵搁,但是沒(méi)有命中緩存吃衅,然后就到數(shù)據(jù)庫(kù)中取數(shù)據(jù),此時(shí)來(lái)了一個(gè)寫(xiě)操作腾誉,寫(xiě)完數(shù)據(jù)庫(kù)后徘层,讓緩存失效,然后妄辩,之前的那個(gè)讀操作再把老的數(shù)據(jù)放進(jìn)去惑灵,所以,會(huì)造成臟數(shù)據(jù)眼耀。
但英支,這個(gè)case理論上會(huì)出現(xiàn),不過(guò)哮伟,實(shí)際上出現(xiàn)的概率可能非常低干花,因?yàn)檫@個(gè)條件需要發(fā)生在讀緩存時(shí)緩存失效,而且并發(fā)著有一個(gè)寫(xiě)操作楞黄。而實(shí)際上數(shù)據(jù)庫(kù)的寫(xiě)操作會(huì)比讀操作慢得多池凄,而且還要鎖表,而讀操作必須在寫(xiě)操作前進(jìn)入數(shù)據(jù)庫(kù)操作鬼廓,而又要晚于寫(xiě)操作更新緩存肿仑,所有的這些條件都具備的概率基本并不大。
所以,這也就是Quora上的那個(gè)答案里說(shuō)的尤慰,要么通過(guò)2PC或是Paxos協(xié)議保證一致性馏锡,要么就是拼命的降低并發(fā)時(shí)臟數(shù)據(jù)的概率,而Facebook使用了這個(gè)降低概率的玩法伟端,因?yàn)?PC太慢杯道,而Paxos太復(fù)雜。當(dāng)然责蝠,最好還是為緩存設(shè)置上過(guò)期時(shí)間党巾。
6.2 方案:隊(duì)列 + 重試機(jī)制
流程如下所示
更新數(shù)據(jù)庫(kù)數(shù)據(jù);
緩存因?yàn)榉N種問(wèn)題刪除失敗
將需要?jiǎng)h除的key發(fā)送至消息隊(duì)列
自己消費(fèi)消息霜医,獲得需要?jiǎng)h除的key
繼續(xù)重試刪除操作齿拂,直到成功
然而,該方案有一個(gè)缺點(diǎn)支子,對(duì)業(yè)務(wù)線代碼造成大量的侵入创肥。于是有了方案二,在方案二中值朋,啟動(dòng)一個(gè)訂閱程序去訂閱數(shù)據(jù)庫(kù)的binlog叹侄,獲得需要操作的數(shù)據(jù)。在應(yīng)用程序中昨登,另起一段程序趾代,獲得這個(gè)訂閱程序傳來(lái)的信息,進(jìn)行刪除緩存操作丰辣。
6.3 方案:異步更新緩存(基于訂閱binlog的同步機(jī)制)
技術(shù)整體思路:
MySQL binlog增量訂閱消費(fèi)+消息隊(duì)列+增量數(shù)據(jù)更新到redis
1)讀Redis:熱數(shù)據(jù)基本都在Redis
2)寫(xiě)MySQL: 增刪改都是操作MySQL
3)更新Redis數(shù)據(jù):MySQ的數(shù)據(jù)操作binlog撒强,來(lái)更新到Redis
Redis更新
1)數(shù)據(jù)操作主要分為兩大塊:
一個(gè)是全量(將全部數(shù)據(jù)一次寫(xiě)入到redis)
一個(gè)是增量(實(shí)時(shí)更新)
這里說(shuō)的是增量,指的是mysql的update、insert笙什、delate變更數(shù)據(jù)飘哨。
2)讀取binlog后分析 ,利用消息隊(duì)列,推送更新各臺(tái)的redis緩存數(shù)據(jù)琐凭。
這樣一旦MySQL中產(chǎn)生了新的寫(xiě)入芽隆、更新、刪除等操作统屈,就可以把binlog相關(guān)的消息推送至Redis胚吁,Redis再根據(jù)binlog中的記錄,對(duì)Redis進(jìn)行更新愁憔。
其實(shí)這種機(jī)制腕扶,很類似MySQL的主從備份機(jī)制,因?yàn)镸ySQL的主備也是通過(guò)binlog來(lái)實(shí)現(xiàn)的數(shù)據(jù)一致性吨掌。
這里可以結(jié)合使用canal(阿里的一款開(kāi)源框架)半抱,通過(guò)該框架可以對(duì)MySQL的binlog進(jìn)行訂閱脓恕,而canal正是模仿了mysql的slave數(shù)據(jù)庫(kù)的備份請(qǐng)求,使得Redis的數(shù)據(jù)更新達(dá)到了相同的效果代虾。
當(dāng)然进肯,這里的消息推送工具你也可以采用別的第三方:kafka、rabbitMQ等來(lái)實(shí)現(xiàn)推送更新Redis棉磨。