redis雪崩和穿透,redis雪崩怎么解決
各位老鐵們,大家好,今天由我來為大家分享redis雪崩和穿透,以及redis雪崩怎么解決的相關(guān)問題知識,希望對大家有所幫助。如果可以幫助到大家,還望關(guān)注收藏下本站,您的...
各位老鐵們,大家好,今天由我來為大家分享redis雪崩和穿透,以及redis雪崩怎么解決的相關(guān)問題知識,希望對大家有所幫助。如果可以幫助到大家,還望關(guān)注收藏下本站,您的支持是我們最大的動力,謝謝大家了哈,下面我們開始吧!
海量數(shù)據(jù)下如何正確訪問Redis服務(wù)才不會掛掉
要保證Redis不會掛掉,也就是提高Redis的高可用性,可以從這么幾個方面考慮。
集群式部署方式Redis單副本:也就是只部署一臺Redis,不需要節(jié)點之間的數(shù)據(jù)同步,架構(gòu)簡單,部署方便;但是單臺機(jī)器畢竟是有風(fēng)險的,按照題目中【海量數(shù)據(jù)】的場景,是不能達(dá)到高可用要求的。
Redis主從:主從實例可以部署在不同的物理服務(wù)器上,充分利用多臺服務(wù)器的資源,在主庫發(fā)生故障的時候,可以進(jìn)行主備切換,從而保證系統(tǒng)的穩(wěn)定運行,甚至可以做到讀寫分離,主庫專門用作寫操作,一臺或多臺備庫進(jìn)行讀操作;但是當(dāng)主庫發(fā)生故障的時候(如果沒有HA方案的話),是需要手動進(jìn)行主備切換的。
RedisSentinel:部署架構(gòu)分為兩部分【Sentinel集群】和【數(shù)據(jù)集群】;Sentinel集群是由多個Sentinel節(jié)點組成的分布式集群,通常是2N+1臺服務(wù)器,可以實現(xiàn)故障發(fā)現(xiàn)和轉(zhuǎn)移、客戶端通知等功能;數(shù)據(jù)集群用于存儲數(shù)據(jù);它能夠解決主從模式下的自動切換問題,并且數(shù)據(jù)集群是可以橫向擴(kuò)展的;當(dāng)然這個架構(gòu)實現(xiàn)和部署起來,也更為復(fù)雜一些;并且這個架構(gòu)不能做到讀寫分離。
RedisCluster:Redis3.0集群,是分布式集群解決方案之一,物理架構(gòu)中配置2N個節(jié)點(主從一一對應(yīng)),主節(jié)點提供讀寫操作,從節(jié)點作為備份;數(shù)據(jù)分布保存在多個節(jié)點上,是一種無中心的架構(gòu),如果有部分節(jié)點發(fā)生故障,能夠?qū)崿F(xiàn)故障自動轉(zhuǎn)移和切換,用投票機(jī)制完成備庫升級為主庫(下文的Redis分片章節(jié),還會介紹到RedisCluster)。
Redis分片Redis在3.0之前只支持單實例,在此之前,在數(shù)據(jù)量比較大的情況,通常有幾種方案可以做到把數(shù)據(jù)分片保存到多臺服務(wù)器上。
客戶端分片:分片邏輯被放到了客戶端上,由客戶端根據(jù)路由規(guī)則,把數(shù)據(jù)保存不同的Redis實例中,讀取的時候也是根據(jù)規(guī)則,去對應(yīng)的實例上讀取數(shù)據(jù);但是當(dāng)Redis實例數(shù)量發(fā)生變化的時候(增加實例或減少實例),需要手動地調(diào)整分片的規(guī)則程序;并且這種部署方式,也增加了運維的成本。
Redis代理組件:在這種架構(gòu)中,客戶端不再直接訪問Redis實例,而是訪問代理組件,由它管理路由的規(guī)則;客戶端不需要關(guān)心有幾個Redis實例,數(shù)據(jù)被路由到哪個實例上;但是由于在客戶端和Redis之間增加了一層代理,多多少少也會產(chǎn)生一些性能上的損耗。
RedisCluster:上文中提到的Redis3.0集群,這里對數(shù)據(jù)的存儲和路由方式,再介紹幾句:Redis把所有的Key分成了16384個slot,每個Redis實例負(fù)責(zé)其中一部分slot;每個Redis都知道每個slot在哪個節(jié)點上存儲(實例節(jié)點定期做數(shù)據(jù)交換);當(dāng)客戶端訪問到一個Redis實例的時候,如果數(shù)據(jù)不在這個實例上,那么會通過重定向命令引導(dǎo)客戶端訪問數(shù)據(jù)所在的實例。
熱點數(shù)據(jù)挑戰(zhàn)單節(jié)點的極限雖然我們已經(jīng)把數(shù)據(jù)分散保存到多臺Redis實例上了,但是如果有一個熱點數(shù)據(jù)被頻繁訪問,超過了單實例的服務(wù)器極限,那么該如何解決呢?通常的手段就是做讀寫分離,部署多臺只讀節(jié)點,對外提供服務(wù)。
我將持續(xù)分享Java開發(fā)、架構(gòu)設(shè)計、程序員職業(yè)發(fā)展等方面的見解,希望能得到你的關(guān)注。如何解決Redis緩存雪崩、緩存穿透、緩存并發(fā)等問題
緩存穿透
很多項目在使用Redis或其他緩存框架的時候,都是先查詢緩存,查詢不的話再查詢數(shù)據(jù)庫,查到之后再放到內(nèi)存中;如果一個key值本身就不存在,那么每一次都會查詢數(shù)據(jù)庫,也就是常說的【緩存穿透】。
應(yīng)對方法:
如果在Redis中查詢不到,并且查詢數(shù)據(jù)庫也沒有結(jié)果,那么就將這個key寫入到Redis中,value=空,并設(shè)置一個超時過期時間,例如五分鐘,那么五分鐘以內(nèi)的對這個可以的所有查詢就可以攔截下來,如果數(shù)據(jù)庫有key對應(yīng)的數(shù)據(jù)了,那么五分鐘后Redis中的緩存過期,會訪問數(shù)據(jù)庫并加載緩存;但是如果被惡意攻擊,每次請求的key都不相同且不存在,那么依然會穿透到數(shù)據(jù)庫;
布隆過濾器:將可能存在的數(shù)據(jù)Hash到一個足夠大的bitmap上,它可以告訴你“某個key一定不存在或者可能存在”,一個一定不存在的數(shù)據(jù)會被bitmap攔截。
緩存雪崩很多時候,Redis中的緩存是要設(shè)置過期時間的,假如Redis中的數(shù)據(jù),過期時間都設(shè)置成一樣的,那么到了時間之后,全部緩存過期失效,下一秒所有的請求都會訪問數(shù)據(jù)庫,那么數(shù)據(jù)庫可能因為訪問量多大導(dǎo)致“崩潰”,這就是緩存雪崩。
應(yīng)對方法:
最暴力的解決辦法,緩存不設(shè)置自動過期時間,只要緩存不崩,數(shù)據(jù)庫就不會崩。
另外一個辦法,就是讓緩存過期時間不那么一致,比如一批緩存數(shù)據(jù)24小時后過期,那么就在這個基礎(chǔ)上,每條緩存的過期時間前后隨機(jī)1-6000秒(1-10分鐘)。
緩存并發(fā)大多數(shù)時候,我們的程序訪問Redis都不可能是單線程,那么當(dāng)多個Client并發(fā)對Redis進(jìn)行setkey操作的時候,可能會產(chǎn)生一些問題;其實Redis本身是單線程的,這種時候會按照先后順序進(jìn)行操作;或者把操作放在隊列中,按順序執(zhí)行;
但比如這種情況:
token過期,有兩個線程都去重新獲取token;
線程1獲取token1;
線程2獲取到token2,此時token1過期;
線程1把token1放到Redis,再拿著token1去調(diào)用服務(wù),發(fā)現(xiàn)過期了,繼續(xù)去請求token3,此時token2過期;
線程2把token2放到Redis,再拿著token2去調(diào)用服務(wù),發(fā)現(xiàn)過期了,繼續(xù)去請求token4,此時token3過期;
......
這就需要我們在更新緩存的時候,做一些控制了。
我將持續(xù)分享Java開發(fā)、架構(gòu)設(shè)計、程序員職業(yè)發(fā)展等方面的見解,希望能得到你的關(guān)注。好了,文章到這里就結(jié)束啦,如果本次分享的redis雪崩和穿透和redis雪崩怎么解決問題對您有所幫助,還望關(guān)注下本站哦!
本文鏈接:http:///qianduan/2811.html