天天看點

redistemplate.opsforhash設定過期時間_Redis詳解(十一)------ 過期删除政策和記憶體淘汰政策...

大家好,我是可樂,一個專注原創,樂于分享的程式猿。 本系列教程持續更新,可以微信搜尋「 IT可樂 」第一時間閱讀。回複《電子書》有我為大家特别篩選的海量免費書籍資料

在介紹這篇文章之前,我們先來看如下幾個問題:

①、如何設定Redis鍵的過期時間?

②、設定完一個鍵的過期時間後,到了這個時間,這個鍵還能擷取到麼?假如擷取不到那這個鍵還占據着記憶體嗎?

③、如何設定Redis的記憶體大小?當記憶體滿了之後,Redis有哪些記憶體淘汰政策?我們又該如何選擇?

如果上面的幾個問題你都懂,那麼下面的内容你就不用看了;如果你不是很懂,那就帶着這些問題往下看。

1、設定Redis鍵過期時間

Redis提供了四個指令來設定過期時間(生存時間)。

①、EXPIRE :表示将鍵 key 的生存時間設定為 ttl 秒。

②、PEXPIRE :表示将鍵 key 的生存時間設定為 ttl 毫秒。

③、EXPIREAT :表示将鍵 key 的生存時間設定為 timestamp 所指定的秒數時間戳。

④、PEXPIREAT :表示将鍵 key 的生存時間設定為 timestamp 所指定的毫秒數時間戳。

PS:在Redis内部實作中,前面三個設定過期時間的指令最後都會轉換成最後一個PEXPIREAT 指令來完成。

另外補充兩個知識點:   一、移除鍵的過期時間

PERSIST :表示将key的過期時間移除。

二、傳回鍵的剩餘生存時間

TTL :以秒的機關傳回鍵 key 的剩餘生存時間。

PTTL :以毫秒的機關傳回鍵 key 的剩餘生存時間。

2、Redis過期時間的判定

在Redis内部,每當我們設定一個鍵的過期時間時,Redis就會将該鍵帶上過期時間存放到一個過期字典中。當我們查詢一個鍵時,Redis便首先檢查該鍵是否存在過期字典中,如果存在,那就擷取其過期時間。然後将過期時間和目前系統時間進行比對,比系統時間大,那就沒有過期;反之判定該鍵過期。

3、過期删除政策

通常删除某個key,我們有如下三種方式進行處理。

①、定時删除

  在設定某個key 的過期時間同時,我們建立一個定時器,讓定時器在該過期時間到來時,立即執行對其進行删除的操作。

優點:定時删除對記憶體是最友好的,能夠儲存記憶體的key一旦過期就能立即從記憶體中删除。

缺點:對CPU最不友好,在過期鍵比較多的時候,删除過期鍵會占用一部分 CPU 時間,對伺服器的響應時間和吞吐量造成影響。

②、惰性删除

  設定該key 過期時間後,我們不去管它,當需要該key時,我們在檢查其是否過期,如果過期,我們就删掉它,反之傳回該key。

優點:對 CPU友好,我們隻會在使用該鍵時才會進行過期檢查,對于很多用不到的key不用浪費時間進行過期檢查。

缺點:對記憶體不友好,如果一個鍵已經過期,但是一直沒有使用,那麼該鍵就會一直存在記憶體中,如果資料庫中有很多這種使用不到的過期鍵,這些鍵便永遠不會被删除,記憶體永遠不會釋放。進而造成記憶體洩漏。

③、定期删除

  每隔一段時間,我們就對一些key進行檢查,删除裡面過期的key。

優點:可以通過限制删除操作執行的時長和頻率來減少删除操作對 CPU 的影響。另外定期删除,也能有效釋放過期鍵占用的記憶體。

缺點:難以确定删除操作執行的時長和頻率。

如果執行的太頻繁,定期删除政策變得和定時删除政策一樣,對CPU不友好。

如果執行的太少,那又和惰性删除一樣了,過期鍵占用的記憶體不會及時得到釋放。

另外最重要的是,在擷取某個鍵時,如果某個鍵的過期時間已經到了,但是還沒執行定期删除,那麼就會傳回這個鍵的值,這是業務不能忍受的錯誤。

4、Redis過期删除政策

前面讨論了删除過期鍵的三種政策,發現單一使用某一政策都不能滿足實際需求,聰明的你可能想到了,既然單一政策不能滿足,那就組合來使用吧。

沒錯,Redis的過期删除政策就是:惰性删除和定期删除兩種政策配合使用。

惰性删除

:Redis的惰性删除政策由 db.c/expireIfNeeded 函數實作,所有鍵讀寫指令執行之前都會調用 expireIfNeeded 函數對其進行檢查,如果過期,則删除該鍵,然後執行鍵不存在的操作;未過期則不作操作,繼續執行原有的指令。

定期删除

:由redis.c/activeExpireCycle 函數實作,函數以一定的頻率運作,每次運作時,都從一定數量的資料庫中取出一定數量的随機鍵進行檢查,并删除其中的過期鍵。

注意:并不是一次運作就檢查所有的庫,所有的鍵,而是随機檢查一定數量的鍵。

定期删除函數的運作頻率,在Redis2.6版本中,規定每秒運作10次,大概100ms運作一次。在Redis2.8版本後,可以通過修改配置檔案redis.conf 的 hz 選項來調整這個次數。

redistemplate.opsforhash設定過期時間_Redis詳解(十一)------ 過期删除政策和記憶體淘汰政策...

  看上面對這個參數的解釋,建議不要将這個值設定超過 100,否則會對CPU造成比較大的壓力。

我們看到,通過過期删除政策,對于某些永遠使用不到的鍵,并且多次定期删除也沒標明到并删除,那麼這些鍵同樣會一直駐留在記憶體中,又或者在Redis中存入了大量的鍵,這些操作可能會導緻Redis記憶體不夠用,這時候就需要Redis的記憶體淘汰政策了。

5、記憶體淘汰政策

①、設定Redis最大記憶體

  在配置檔案redis.conf 中,可以通過參數 maxmemory 來設定最大記憶體:

redistemplate.opsforhash設定過期時間_Redis詳解(十一)------ 過期删除政策和記憶體淘汰政策...

  不設定該參數預設是無限制的,但是通常會設定其為實體記憶體的四分之三。(這裡有個疑惑:為啥作者不考慮将此參數設定為百分比呢?)

②、設定記憶體淘汰方式

  當現有記憶體大于 maxmemory 時,便會觸發redis主動淘汰記憶體方式,通過設定 maxmory-policy ,有如下幾種淘汰方式:

1)volatile-lru 利用LRU算法移除設定過過期時間的key (LRU:最近使用 Least Recently Used ) 。

2)allkeys-lru 利用LRU算法移除任何key (和上一個相比,删除的key包括設定過期時間和不設定過期時間的)。通常使用該方式。

3)volatile-random 移除設定過過期時間的随機key 。

4)allkeys-random 無差别的随機移除。

5)volatile-ttl 移除即将過期的key(minor TTL)

6)noeviction 不移除任何key,隻是傳回一個寫錯誤 ,預設選項,一般不會選用。

在redis.conf 配置檔案中,可以設定淘汰方式:

redistemplate.opsforhash設定過期時間_Redis詳解(十一)------ 過期删除政策和記憶體淘汰政策...

6、總結

通過上面的介紹,相信大家對Redis的過期資料删除政策和記憶體淘汰政策有一定的了解了。這裡總結一下:

Redis過期删除政策是采用惰性删除和定期删除這兩種方式組合進行的,惰性删除能夠保證過期的資料我們在擷取時一定擷取不到,而定期删除設定合适的頻率,則可以保證無效的資料及時得到釋放,而不會一直占用記憶體資料。

但是我們說Redis是部署在實體機上的,記憶體不可能無限擴充的,當記憶體達到我們設定的界限後,便自動觸發Redis記憶體淘汰政策,而具體的政策方式要根據實際業務情況進行選取。

redistemplate.opsforhash設定過期時間_Redis詳解(十一)------ 過期删除政策和記憶體淘汰政策...
本系列教程持續更新,可以微信搜尋「 IT可樂 」第一時間閱讀。回複《電子書》有我為大家特别篩選的書籍資料

http://weixin.qq.com/r/iSqbg-fEGqplrbPg93_b (二維碼自動識别)