1.redis過期時間介紹
有時候我們並不希望redis的key一直存在。例如緩存,驗證碼等數據,我們希望它們能在一定時間內自動的被銷毀。redis提供了一些命令,能夠讓我們對key設置過期時間,並且讓key過期之后被自動刪除
2.redis過期時間相關命令
1.EXPIRE PEXPIRE
EXPIRE 接口定義:EXPIRE key "seconds"
接口描述:設置一個key在當前時間"seconds"(秒)之后過期。返回1代表設置成功,返回0代表key不存在或者無法設置過期時間。
PEXPIRE 接口定義:PEXPIRE key "milliseconds"
接口描述:設置一個key在當前時間"milliseconds"(毫秒)之后過期。返回1代表設置成功,返回0代表key不存在或者無法設置過期時間。
127.0.0.1:6379> set aa bb OK 127.0.0.1:6379> EXPIRE aa 60 (integer) 1 127.0.0.1:6379> EXPIRE aa 600 (integer) 1
2.EXPIREAT PEXPIREAT
EXPIREAT 接口定義:EXPIREAT key "timestamp"
接口描述:設置一個key在"timestamp"(時間戳(秒))之后過期。返回1代表設置成功,返回0代表key不存在或者無法設置過期時間。
PEXPIREAT 接口定義:PEXPIREAT key "milliseconds-timestamp"
接口描述:設置一個key在"milliseconds-timestamp"(時間戳(毫秒))之后過期。返回1代表設置成功,返回0代表key不存在或者無法設置過期時間
127.0.0.1:6379> set aa bb OK 127.0.0.1:6379> EXPIREAT aa 1586941008 (integer) 1 127.0.0.1:6379> PEXPIREAT aa 1586941008000 (integer) 1
3.TTL PTTL
TTL 接口定義:TTL key
接口描述:獲取key的過期時間。如果key存在過期時間,返回剩余生存時間(秒);如果key是永久的,返回-1;如果key不存在或者已過期,返回-2。
PTTL 接口定義:PTTL key
接口描述:獲取key的過期時間。如果key存在過期時間,返回剩余生存時間(毫秒);如果key是永久的,返回-1;如果key不存在或者已過期,返回-2。
127.0.0.1:6379> set aa bb OK 127.0.0.1:6379> EXPIRE aa 60 (integer) 1 127.0.0.1:6379> ttl aa (integer) 58 127.0.0.1:6379> ttl aa (integer) 56 127.0.0.1:6379> pttl aa (integer) 40395
4.PERSIST
PERSIST 接口定義:PERSIST key
接口描述:移除key的過期時間,將其轉換為永久狀態。如果返回1,代表轉換成功。如果返回0,代表key不存在或者之前就已經是永久狀態。
127.0.0.1:6379> set aa bb OK 127.0.0.1:6379> EXPIRE aa 600 (integer) 1 127.0.0.1:6379> ttl aa (integer) 596 127.0.0.1:6379> PERSIST aa (integer) 1 127.0.0.1:6379> ttl aa (integer) -1
5.SETEX
SETEX 接口定義:SETEX key "seconds" "value"
接口描述:SETEX在邏輯上等價於SET和EXPIRE合並的操作,區別之處在於SETEX是一條命令,而命令的執行是原子性的,所以不會出現並發問題。
127.0.0.1:6379> SETEX aa 100 bb OK 127.0.0.1:6379> pttl aa (integer) 95834 127.0.0.1:6379> ttl aa (integer) 81
3.redis如何清理過期key
redis出於性能上的考慮,無法做到對每一個過期的key進行即時的過期監聽和刪除。但是redis提供了其它的方法來清理過期的key。
1.被動清理
當用戶主動訪問一個過期的key時,redis會將其直接從內存中刪除。
2.主動清理
在redis的持久化中,我們知道redis為了保持系統的穩定性,健壯性,會周期性的執行一個函數。在這個過程中,會進行之前已經提到過的自動的持久化操作,同時也會進行內存的主動清理。
在內存主動清理的過程中,redis采用了一個隨機算法來進行這個過程:簡單來說,redis會隨機的抽取N(默認100)個被設置了過期時間的key,檢查這其中已經過期的key,將其清除。同時,如果這其中已經過期的key超過了一定的百分比M(默認是25),則將繼續執行一次主動清理,直至過期key的百分比在概率上降低到M以下。
3.內存不足時觸發主動清理
在redis的內存不足時,也會觸發主動清理。
4.redis內存不足時的策略
redis是一個基於內存的數據庫,如果存儲的數據量很大,達到了內存限制的最大值,將會出現內存不足的問題。redis允許用戶通過配置maxmemory-policy參數,指定redis在內存不足時的解決策略
1.volatile-lru 使用LRU算法刪除一個鍵(只針對設置了過期時間的key
2.allkeys-lru 使用LRU算法刪除一個鍵
3.volatile-lfu 使用LFU算法刪除一個鍵(只針對設置了過期時間的鍵)
4.allkeys-lfu 使用LFU算法刪除一個鍵
5.volatile-random 隨機刪除一個鍵(只針對設置了過期時間的鍵)
6.allkeys-random 隨機刪除一個鍵
7.volatile-ttl 刪除最早過期的一個鍵
8.noeviction 不刪除鍵,返回錯誤信息(redis默認選項)
對於只針對設置了過期時間的鍵進行刪除的策略,在所有的可被刪除的鍵(非永久的鍵)都被刪除時內存依然不足,將會拋出錯誤。
其中,LRU算法--->最近最少使用算法,較為注重於時間;LFU算法--->最近最不常用算法,較為注重於被訪問頻率。
redis的內存置換算法和操作系統中的內存置換算法類似,就不在這里展開了。
5.redis過期時間總結
redis的過期時間還有許多的細節值得去深入了解,例如持久化時對過期時間的處理,redis周期性的常規操作等等,只有這樣才能更准確的定位問題,解決問題。
而想進一步的理解這些知識,除了仔細的思考外,最好的辦法就是通過閱讀源代碼,理解redis的底層運行原理。但是這一目標對於現在的我來說難度過大,希望通過不斷的學習,將來的我能夠做到這一點。