小編給大家分享一下往redis里寫(xiě)的數(shù)據(jù)為什么沒(méi)了,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)建站是一家專業(yè)提供自貢企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、H5開(kāi)發(fā)、小程序制作等業(yè)務(wù)。10年已為自貢眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。
使用Redis的同學(xué)你要明白一點(diǎn),你為什么用Redis?用redis的作用是什么?用redis的好處是什么?凡事多思考一下為什么,多想想背后的原因。
就在不久前有朋友跟我說(shuō)過(guò),說(shuō)他們生產(chǎn)環(huán)境的Redis怎么經(jīng)常會(huì)丟掉一些數(shù)據(jù)?寫(xiě)進(jìn)去了,過(guò)一會(huì)兒可能就沒(méi)了。我的天啊,你問(wèn)這個(gè)問(wèn)題就說(shuō)明Redis你就沒(méi)用對(duì)啊。Redis是緩存,你給當(dāng)存儲(chǔ)了用了是吧?
首先要明白一點(diǎn)啥叫緩存?為啥用緩存?
Redis是用內(nèi)存當(dāng)緩存的。內(nèi)存是無(wú)限的嗎?相反,內(nèi)存是很寶貴而且是有限的,磁盤是廉價(jià)而且是大量的。可能一臺(tái)機(jī)器就幾十個(gè)G的內(nèi)存,但是可以有幾個(gè)T的硬盤空間。Redis主要是基于內(nèi)存來(lái)進(jìn)行高性能、高并發(fā)的讀寫(xiě)操作的。
那既然內(nèi)存是有限的,比如Redis就只能用10個(gè)G,你一直往里面寫(xiě)數(shù)據(jù),一直寫(xiě)一直寫(xiě)最后10個(gè)G都用的差不多了,你還寫(xiě)會(huì),你想想會(huì)發(fā)生什么?當(dāng)然會(huì)干掉一些的數(shù)據(jù)了,然后就保留10個(gè)G的數(shù)據(jù)。你說(shuō)會(huì)不會(huì)造成數(shù)據(jù)丟失?
那Redis會(huì)干掉哪些數(shù)據(jù)?保留哪些數(shù)據(jù)呢?當(dāng)然是干掉不常用的數(shù)據(jù),保留常用的數(shù)據(jù)了。
所以說(shuō),這是緩存的一個(gè)最基本的概念:數(shù)據(jù)是會(huì)過(guò)期的。要么是你自己設(shè)置個(gè)過(guò)期時(shí)間,要么是Redis自己給干掉。
所以你的Redis如果使用不當(dāng),把生產(chǎn)數(shù)據(jù)存到里面,又沒(méi)有去持久化到MySQL,那就會(huì)有丟失的可能。
還有一種就是如果你給key設(shè)置好了一個(gè)過(guò)期時(shí)間,你知道到一定的時(shí)間再去查這個(gè)key就沒(méi)有了,但是你知道redis是怎么給你弄成過(guò)期的嗎?什么時(shí)候刪除掉?
如果你不知道,在實(shí)際的使用過(guò)程中你就可能會(huì)發(fā)現(xiàn)這么一個(gè)問(wèn)題:為啥好多數(shù)據(jù)明明應(yīng)該過(guò)期了,結(jié)果發(fā)現(xiàn)redis內(nèi)存占用還是很高?那是因?yàn)槟悴恢?strong>Redis是怎么刪除那些過(guò)期key的。
舉例,Redis 內(nèi)存一共是10個(gè)G,你現(xiàn)在往里面寫(xiě)了5個(gè)G的數(shù)據(jù),然后你對(duì)這些數(shù)據(jù)全都設(shè)置了10分鐘之后過(guò)期,結(jié)果10分鐘之后,你再來(lái)查看看,Redis的內(nèi)存使用率怎么還是50%呢?5個(gè)G的數(shù)據(jù)都過(guò)期了,我從redis里查,是查不到了,結(jié)果過(guò)期的數(shù)據(jù)為啥還占用著Redis的內(nèi)存呢。
如果你連這個(gè)問(wèn)題都不知道,上來(lái)就懵了,回答不出來(lái),建議你使用Redis之前多做做功課,不然你寫(xiě)代碼的時(shí)候,想當(dāng)然的認(rèn)為寫(xiě)進(jìn)Redis的數(shù)據(jù)就一定會(huì)存在,后面導(dǎo)致系統(tǒng)各種漏洞和bug,就不好弄了。
set key value 過(guò)期時(shí)間(1小時(shí))
表示set進(jìn)去的key,1小時(shí)之后就沒(méi)了,就失效了。
我們set key的時(shí)候,都可以給一個(gè)expire time,就是過(guò)期時(shí)間,指定這個(gè)key比如說(shuō)只能存活1個(gè)小時(shí)?10分鐘?這個(gè)很有用,我們自己可以指定緩存到期就失效。
如果假設(shè)你設(shè)置一批key只能存活1個(gè)小時(shí),那么接下來(lái)1小時(shí)后,redis是怎么對(duì)這批key進(jìn)行刪除的?
答案是:定期刪除+惰性刪除
所謂定期刪除,指的是Redis默認(rèn)是每隔100ms就隨機(jī)抽取
一些設(shè)置了過(guò)期時(shí)間的key,檢查其是否過(guò)期,如果過(guò)期就刪除。
為什么是隨機(jī)抽?。?/strong>
假設(shè)Redis里放了10萬(wàn)個(gè)key,都設(shè)置了過(guò)期時(shí)間,你每隔幾百毫秒,就檢查10萬(wàn)個(gè)key,那redis基本上就死了,因?yàn)檫@樣cpu負(fù)載會(huì)很高的,全都消耗在你的檢查過(guò)期key上了。
所以這里可不是每隔100ms就遍歷所有的設(shè)置過(guò)期時(shí)間的key,Redis如果設(shè)置成檢查所有Key那將是一場(chǎng)性能上的災(zāi)難。所以實(shí)際上redis是每隔100ms隨機(jī)抽取
一些key來(lái)檢查和刪除的。
但是問(wèn)題是,隨機(jī)抽取檢測(cè)key是否過(guò)去會(huì)導(dǎo)致定期刪除
策略可能會(huì)導(dǎo)致很多過(guò)期key到了時(shí)間并沒(méi)有被刪除掉,那咋整呢?所以Redis還有另一個(gè)策略就是惰性刪除
。
惰性刪除就是說(shuō),在你獲取某個(gè)key的時(shí)候,Redis會(huì)檢查一下 ,這個(gè)key如果設(shè)置了過(guò)期時(shí)間那么是否過(guò)期了?如果過(guò)期了此時(shí)就會(huì)刪除,不會(huì)給你返回任何東西。
所以并不是key到時(shí)間就被刪除掉,而是你查詢這個(gè)key的時(shí)候,Redis再懶惰的檢查一下。
通過(guò)上述兩種手段,保證過(guò)期的key一定會(huì)被干掉。
那么剛才的問(wèn)題就不難理解了,就是說(shuō),你的過(guò)期key,靠定期刪除沒(méi)有被刪除掉,還停留在內(nèi)存里,占用著你的內(nèi)存呢,除非你的系統(tǒng)去查一下那個(gè)key,才會(huì)被redis給刪除掉。如果都過(guò)期了,定期刪除才刪了一點(diǎn)點(diǎn),而你又沒(méi)有去查,沒(méi)有觸發(fā)惰性刪除,那么短時(shí)間內(nèi)你的redis內(nèi)存占用率還是會(huì)下不來(lái)。
但是實(shí)際上這還是有問(wèn)題的,如果定期刪除漏掉了很多過(guò)期key,然后你也沒(méi)及時(shí)去查,也就沒(méi)走惰性刪除,此時(shí)會(huì)怎么樣?如果大量過(guò)期key堆積在內(nèi)存里,導(dǎo)致redis內(nèi)存塊耗盡了,咋整?
別擔(dān)心Redis還有方案:內(nèi)存淘汰機(jī)制。
如果Redis的內(nèi)存占用過(guò)多的時(shí)候,此時(shí)會(huì)進(jìn)行內(nèi)存淘汰,Redis提供如下豐富的可選策略:
1)noeviction:
當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),新寫(xiě)入操作會(huì)報(bào)錯(cuò)。
(這個(gè)一般沒(méi)人用吧,實(shí)在是太惡心了)
2)allkeys-lru:
當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),在所有鍵空間中,移除最近最少使用的key
(這個(gè)是最常用的)
3)allkeys-random:
當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),在所有鍵空間中,隨機(jī)移除某個(gè)key。
(這個(gè)一般沒(méi)人用吧,為啥要隨機(jī),把我重要的key干掉了咋整,肯定是把最近最少使用的干掉)
4)volatile-lru:
當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),在設(shè)置了過(guò)期時(shí)間的鍵空間中,移除最近最少使用的key。
(這個(gè)一般不太合適)
5)volatile-random:
當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),在設(shè)置了過(guò)期時(shí)間的鍵空間中,隨機(jī)移除某個(gè)key。
6)volatile-ttl:
當(dāng)內(nèi)存不足以容納新寫(xiě)入數(shù)據(jù)時(shí),在設(shè)置了過(guò)期時(shí)間的鍵空間中,有更早過(guò)期時(shí)間的key優(yōu)先移除。
例如:Redis 里有10個(gè)key,現(xiàn)在內(nèi)存已經(jīng)滿了,設(shè)置的淘汰策略是allkeys-lru
,此時(shí)Redis需要?jiǎng)h除掉一些key來(lái)保證你可以繼續(xù)寫(xiě)入。在這10個(gè)key中,其中1個(gè)key,最近1分鐘被查詢了100次,1個(gè)key,最近10分鐘被查詢了50次,1個(gè)key,最近1個(gè)小時(shí)被查詢了1次。肯定那些最近最少使用的被干掉了。
為啥存redis的數(shù)據(jù)有時(shí)候會(huì)丟失?
很簡(jiǎn)單,你寫(xiě)的數(shù)據(jù)太多了,內(nèi)存占滿了,或者觸發(fā)了什么條件,如redis使用了allkeys-lru內(nèi)存淘汰策略,自動(dòng)給你清理掉了一些最近很少使用的數(shù)據(jù)。
以上是“往Redis里寫(xiě)的數(shù)據(jù)為什么沒(méi)了”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!