redis key的過期機制
本文為閱讀 http://www.redis.io/commands/expire 做的一些記錄總結
redis是一個 高效能的key-value資料庫.我們可以對其中的key設定一個過期時間,相關命令如下:
1.在建立一個key value 的時候同時設定過期時間
比如: set key1 value1 EX 60 表示: 我們想要將這個 key value 放到redis中,並在其中儲存60秒.
set key2 value2 PX 60 表示:我們想要將這個key value放到redis中,並在其中儲存 60毫秒
2.對於已經存在的key value,
比如: 事先有 set key3 value3
我們想為 key3 設定一個過期時間, 我們可以採用以下命令:
expire key3 60 表示: 我們要對已經存在的kye3 設定為 在 60秒之後(無效,或者被刪除)
我們可以檢視一個key當前的 存活(有效?)時間.
使用ttl key4 即可檢視剩餘有效時間.
==============================以上命令,沒有說明返回值表示的意思================
首先說到 "過期", 比如說一個麵包, 其保質期為1天. 那麼, 我們怎麼判定它的有效期?一般情況, 會在做好麵包的時候,在標籤上打上一個生產日期, 在我們在消費這個麵包的時候, 會把我們當前的日期, 和麵包的標籤上的有效期做一個對比,假如時間差超過1天, 那麼我們就判定這個麵包過期了, 就是說,我們為麵包設定一個基準點.其實, 也可能有另外一種實現的方式,就是在每個麵包做好之後,在上面加一個定期器, 我們在消費這個麵包的時候,只要看這個定期器中的顯示,就可以知道這個麵包是否已經過期.
======================
有了上面的一段囉嗦,現在我們就能對redis中的過期機制,起碼有兩種實現方式, 方式1, 儲存一個起始時間,就是麵包例子中的打上生產日期, 附上有效時間. 方式2.每一個key內維護一個類似定時器的東西...(這個做起來,維護成本就太大了...,與高效能的旗號違背), redis中key的過期資訊,就是通過儲存一個過期時間和起始時間資訊來維護的.(說明:redis 2.6及其以上版本用毫秒為單位儲存 起始時間,2.6以前版本用 unix時間戳儲存,所以存在的誤差也可能不一樣, 2.4版本誤差在1秒以內,2.6版本誤差在1毫秒以內)
這就有一個有趣的事情, 就是操作的時候,務必確保當前跑redis的機子上的時間是正確的,(一時間聯想到了linux下改個系統時間都需要輸入管理員密碼的用意何在,防止程式隨意修改系統時間,可能會導致一部分需要依賴系統時間的程式無法執行)
做了一個小實驗: 設定一個key的有效期為60秒,在60秒內將計算機的時間改到1分鐘之後,那麼這個key 馬上失效(突然聯想到之前有些應用時間過了就用不了了....so... )
所以, 在我們每次用get 命令去取一個key的時候,先把key找到,再判斷這個key是否已經過期(自動聯想我們看一個麵包是否已經過期...).如果已經過期了, redis就不給我們返回對應的value值了. 這是redis 處理key過期的active方式, 但是 僅僅依靠這種方式是不夠的,可以想象,假如,我們放置很多具有有效期的key value在redis中,僅僅是每次都判斷一個key是否已經過期,那麼到最後,系統中就會存在許多垃圾(已經過期,但是又沒有人去清理...). 所以,redis,還會每秒鐘執行10次以下的流程:
1.隨機抽取100個設定了有效期的key,檢查其有效期,如果已經過期,則將其刪除.
2.如果抽取到的100個key中超過25個已經過期,那麼返回步驟1,
這就是redis中清除已經過期的key的 passive 方法.
=====================================
可能會影響(或者使用者覺得會影響)key有效期的操作.
1.會刪除有效期的操作.
del 命令.
expire命令
set 命令
getset 命令
另外,其他改變值的操作都是不會修改有效期的, (文章原文:. This means that all the operations that conceptually alter the value stored at the key without replacing it with a new one will leave the timeout untouched. For instance, incrementing the value of a key with INCR, pushing a new value into a list with LPUSH, or altering the field value of a hash with HSET are all operations that will leave the timeout untouched.)
此外,還有一個命令,rename . 假如存在 key1 value1 . 並且key1存在一個有效期, 那麼使用rename key1 key2.這時候,key2的生存時間也會和原key1保持一致. 另外一種情況: 存在 key1, value1, key2,value2. 並且key1存在一個有效期, 那麼使用rename
key1 key2.這時候 key2對應的value是 value1, value2將被覆蓋,而且 key2的所有characteristics將會被 原key1的所有characteristics. (文章原文: it
does not matter if the original Key_A
had
a timeout associated or not, the new key Key_A
will
inherit all the characteristics of Key_B
)
這一小段一開始讓我疑惑:
If a key is renamed with RENAME, the associated time to live is transferred to the new key name.
If a key is overwritten by RENAME, like in the case of an existing key Key_A
that
is overwritten by a call likeRENAME Key_B Key_A
, it does not matter if the original Key_A
had
a timeout associated or not, the new key Key_A
will inherit all the characteristics of Key_B
.
有 ranamed with rename
...overwritten by rename ...
===================================
redis刪除已過期節點時對於 aof檔案以及 主從節點叢集時的處理方式
當一個key過期時,redis會同步刪除對應的aof檔案,假如key分佈在主從叢集的節點時, 也會同步刪除 對應的 slaves上的key.值得注意的是, slaves不會主動刪除已經過期的key,而會一直等待master的刪除命令. 只有當一個slave成為了master之後,才會主動刪除已經過期的key.
另外,文章也給了一個應用的例子,但是英語水平以及開發經驗有限,..無法理解,原文如下:
Pattern: Navigation session
Imagine you have a web service and you are interested in the latest N pages recently visited by your users, such that each adjacent page view was not performed more than 60 seconds after the previous. Conceptually you may think at this set of page views as a Navigation session if your user, that may contain interesting information about what kind of products he or she is looking for currently, so that you can recommend related products.
You can easily model this pattern in Redis using the following strategy: every time the user does a page view you call the following commands:
MULTI RPUSH pagewviews.user:<userid> http://..... EXPIRE pagewviews.user:<userid> 60 EXEC
If the user will be idle more than 60 seconds, the key will be deleted and only subsequent page views that have less than 60 seconds of difference will be recorded.
This pattern is easily modified to use counters using INCR instead of lists using RPUSH.
...
=============================================================================
鑑於個人開啟原頁面的時候,有時候速度非常慢,特將原文附上:
EXPIRE key seconds
Related commands
Available since 1.0.0.
Time complexity: O(1)
Set a timeout on key
. After the timeout has expired, the key will automatically be deleted. A key with an associated
timeout is often said to be volatile in Redis terminology.
The timeout is cleared only when the key is removed using the DEL command or overwritten using the SET orGETSET commands. This means that all the operations that conceptually alter the value stored at the key without replacing it with a new one will leave the timeout untouched. For instance, incrementing the value of a key with INCR, pushing a new value into a list with LPUSH, or altering the field value of a hash with HSET are all operations that will leave the timeout untouched.
The timeout can also be cleared, turning the key back into a persistent key, using the PERSIST command.
If a key is renamed with RENAME, the associated time to live is transferred to the new key name.
If a key is overwritten by RENAME, like in the case of an existing key Key_A
that
is overwritten by a call likeRENAME Key_B Key_A
, it does not matter if the original Key_A
had
a timeout associated or not, the new key Key_A
will inherit all the characteristics of Key_B
.
Refreshing expires
It is possible to call EXPIRE using as argument a key that already has an existing expire set. In this case the time to live of a key is updated to the new value. There are many useful applications for this, an example is documented in the Navigation session pattern section below.
Differences in Redis prior 2.1.3
In Redis versions prior 2.1.3 altering a key with an expire set using a command altering its value had the effect of removing the key entirely. This semantics was needed because of limitations in the replication layer that are now fixed.
Return value
-
1
if the timeout was set. -
0
ifkey
does not exist or the timeout could not be set.
Examples
redis> SET mykey "Hello"
OK
redis> EXPIRE mykey 10
(integer) 1
redis> TTL mykey
(integer) 10
redis> SET mykey "Hello World"
OK
redis> TTL mykey
(integer) -1
redis>
Pattern: Navigation session
Imagine you have a web service and you are interested in the latest N pages recently visited by your users, such that each adjacent page view was not performed more than 60 seconds after the previous. Conceptually you may think at this set of page views as a Navigation session if your user, that may contain interesting information about what kind of products he or she is looking for currently, so that you can recommend related products.
You can easily model this pattern in Redis using the following strategy: every time the user does a page view you call the following commands:
MULTI RPUSH pagewviews.user:<userid> http://..... EXPIRE pagewviews.user:<userid> 60 EXEC
If the user will be idle more than 60 seconds, the key will be deleted and only subsequent page views that have less than 60 seconds of difference will be recorded.
This pattern is easily modified to use counters using INCR instead of lists using RPUSH.
Appendix: Redis expires
Keys with an expire
Normally Redis keys are created without an associated time to live. The key will simply live forever, unless it is removed by the user in an explicit way, for instance using the DEL command.
The EXPIRE family of commands is able to associate an expire to a given key, at the cost of some additional memory used by the key. When a key has an expire set, Redis will make sure to remove the key when the specified amount of time elapsed.
The key time to live can be updated or entirely removed using the EXPIRE and PERSIST command (or other strictly related commands).
Expire accuracy
In Redis 2.4 the expire might not be pin-point accurate, and it could be between zero to one seconds out.
Since Redis 2.6 the expire error is from 0 to 1 milliseconds.
Expires and persistence
Keys expiring information is stored as absolute Unix timestamps (in milliseconds in case of Redis version 2.6 or greater). This means that the time is flowing even when the Redis instance is not active.
For expires to work well, the computer time must be taken stable. If you move an RDB file from two computers with a big desync in their clocks, funny things may happen (like all the keys loaded to be expired at loading time).
Even running instances will always check the computer clock, so for instance if you set a key with a time to live of 1000 seconds, and then set your computer time 2000 seconds in the future, the key will be expired immediately, instead of lasting for 1000 seconds.
How Redis expires keys
Redis keys are expired in two ways: a passive way, and an active way.
A key is actively expired simply when some client tries to access it, and the key is found to be timed out.
Of course this is not enough as there are expired keys that will never be accessed again. This keys should be expired anyway, so periodically Redis test a few keys at random among keys with an expire set. All the keys that are already expired are deleted from the keyspace.
Specifically this is what Redis does 10 times per second:
-
Test 100 random keys from the set of keys with an associated expire.
-
Delete all the keys found expired.
-
If more than 25 keys were expired, start again from step 1.
This is a trivial probabilistic algorithm, basically the assumption is that our sample is representative of the whole key space, and we continue to expire until the percentage of keys that are likely to be expired is under 25%
This means that at any given moment the maximum amount of keys already expired that are using memory is at max equal to max amount of write operations per second divided by 4.
How expires are handled in the replication link and AOF file
In order to obtain a correct behavior without sacrificing consistency, when a key expires, a DEL operation is synthesized in both the AOF file and gains all the attached slaves. This way the expiration process is centralized in the master instance, and there is no chance of consistency errors.
However while the slaves connected to a master will not expire keys independently (but will wait for the DEL coming from the master), they'll still take the full state of the expires existing in the dataset, so when a slave is elected to a master it will be able to expire the keys independently, fully acting as a master.
====================================================
總結:雖然設定一個redis的key設定過期對於整個redis系統來說,不是一個大的功能,但是要將一個小功能做好,也是需要充分考慮到方方面面.另外,拋一塊轉頭: 在web系統中,session一般也是有一個過期時間的,那麼在session的過期時間又是如何實現的呢?==== java ee...
相關推薦
Redis Key過期通知
概述 鍵空間通知使得客戶端可以通過訂閱頻道或模式, 來接收那些以某種方式改動了 Redis 資料集的事件。如Redis資料庫中鍵的過期事件也是通過訂閱功能實現。本文主要基於Azure PaaS Redis演示相關功能的具體實現。 配置 因為開啟鍵空間通知功能需要消耗一些 CPU , 所以
redis key的過期機制
本文為閱讀 http://www.redis.io/commands/expire 做的一些記錄總結 redis是一個 高效能的key-value資料庫.我們可以對其中的key設定一個過期時間,相關命令如下: 1.在建立一個key value 的時候同時設定過期時間
Redis中取得所有Key、過期時間配置與獲取、Key過期通知。
ive exceptio config lee var url multipl -c class string connection = "127.0.0.1:6379,password=xxxxx,connectRetry=5"; [TestM
redis監聽key過期
檢視redis版本: redis-server -v redis-server --version 在window下,下載redis:https://github.com/MicrosoftArchive/redis/releases linux下可以直接在官網下載即可:ht
redis過期機制
Redis會自己回收清理不用的資料嗎? 如果能,那如何配置? 如果不能,如何防止資料累加後大量佔用儲存空間的問題? 之前一直接觸Redis不是很深入,最近專案當中遇到一個需求場景,需要清空一些存放在Redis的資料,主要是通過一些時間進行過濾,刪除那些不滿足的資料,但是這樣的工作每天都
Redis 的過期策略以及記憶體回收機制
一、Redis過期策略 redis是如何處理過期的key? 分為2種:passive (被動)和active(主動) 所謂被動的處理方式就是 :當一些客戶端進行訪問的時候,祕鑰被動過期,
Redis實現key過期監聽,並操作redis的多個數據庫,整合到SpringBoot
最近來了個新的需求,需要使用定時器完成,本想以為用個@Scheduled()就輕易搞定的,詳細瞭解後,事情卻並沒有這麼簡單......。所以接到需求後,需要找產品明確明確再次明確,才開工,不然的話你本以為做好的工作卻是一場空。 業務場景邏輯解析:第一個請求進來,需要把請求引
redis master-slave key過期原理分析
我們線上redis做的是讀寫分離 master寫 slave讀, 我們發現master中的Key已經過期30分鐘以上,但是slave上的TTL為0 (-1永久,-2不存在)。master上已經不存在了 slave還能查出來。 這屬於髒資料的範疇了,在很多及時性的場景下 出現
一行命令使redis批量去除key過期時間/或刪除key
一行命令使redis批量去除key過期時間 redis-cli -p 12379 -n 3 keys "f_vulcan*" | xargs -n1 redis-cli -p 12379 -n 3 persist 連線12379埠的redis,選擇資料庫3,查詢f_vulcan開頭的k
redis key的過期時間
設定redis key的生存過期時間 Redis 有四個不同的命令可以用於設定鍵的生存時間(鍵可以存在多久)或過期時間(鍵什麼時候會被刪除) : EXPlRE PEXPIRE EXPIREAT redis通過exipre或則pexpire命令,可以以秒或則毫秒為精度為某個key設
redis的過期時間和過期刪除機制
一:設定過期時間 redis有四種命令可以用於設定鍵的生存時間和過期時間: EXPIRE <KEY> <TTL> : 將鍵的生存時間設為 ttl 秒 PEXPIRE <KEY> <TTL> :將鍵的生存時間設為 ttl 毫秒 EXPIREA
REDIS 主從架構key過期時間失效問題
活動中用到了Redis來存放使用者的獎勵票資訊,原則上是一天一清,現在設定的是expireAt(零點)但是最近運營反饋有部分使用者有異常票,經過加log排查後發現指定在零點過期的key並沒有準時過期,從庫中在0點23秒的時候還能讀到資料,程式中用了簡單的exists(key) 判斷key是否存在,存在就取值。
redis設定key過期時間
redis是一個廣泛應用的key-value型記憶體資料庫,和memecached一樣,key是可以被設定生存週期的。 redis設定key的過期時間非常簡單: SETEX mykey 10 "Hello" 這樣就給mykey設定了10秒的生存週期。 但是當你使用了red
redis expire key 過期不刪除
1. 問題描述 今天使用 redis 遇到個奇怪的問題,key 設定過期時間後,到期後並沒有刪除。 語句過程大概如下: 127.0.0.1:6379> SET hello 0 OK 127.0.0.1:6379> GET hello "0" 1
redis 獲取key 過期時間
<pre name="code" class="html">127.0.0.1:6379> keys *b4f107c6-e96c-4a1e-8402-a3be9a619847* 1) "shiro_redis_session:b4f107c6-e96c-
redis 的過期策略都有哪些?記憶體淘汰機制都有哪些?手寫一下 LRU 程式碼實現?
面試題 redis 的過期策略都有哪些?記憶體淘汰機制都有哪些?手寫一下 LRU 程式碼實現? 面試官心理分析 如果你連這個問題都不知道,上來就懵了,回答不出來,那線上你寫程式碼的時候,想當然的認為寫進 redis 的資料就一定會存在,後面導致系統各種 bug,誰來負責? 常見的有兩個問題: 往 red
Redis的事務機制
事務 悲觀鎖 樂觀鎖 redis 1、redis的事務是什麽 可以一次執行多個命令,本質是一組命令的集合,一個事務中的所有命令都會被序列化,按順序地串行化執行而不會被其它命令插入,不許加塞(排隊時後來者插到先到者前面的行為。) 也就是說,在隊列中,一次性、順序性、排他性的執行一系列
redis-key(鍵)
失敗 刪除 接受 dump 序列化 設置 set logs ffffff # 刪除單個 key redis> SET name huangz OK redis> DEL name (integer) 1 # 刪除一個不存在的 key redis&g
Redis 存儲機制
安全性 大小 jsb 文件大小 積累 center 變化 iss 相對 Redis存儲機制分成兩種Snapshot和AOF。無論是那種機制,Redis都是將數據存儲在內存中。 Snapshot工作原理: 是將數據先存儲在內存,然後當數據累計達到某些設定的伐值的時候,就會觸發
redis key 空閑(一)
blog exist com redis con logs sts 執行 ron 語法: redis 127.0.0.1:6379> COMMAND KEY_NAME 實例: redis 127.0.0.1:6379[1]> select 2 OK