大約閱讀4分鐘,寫於 2021 0408 22:33 牀前書桌檯燈下
redis
若是你使用過 redis,那你必定知道過時策略這個命令吧,若是讓你設計一個過時鍵接口,你有什麼想法?數據庫
咱們在使用 redis 時,通常會設置一個過時時間,固然也有不設置過時時間的,也就是永久不過時。緩存
當咱們設置了過時時間,redis 是如何判斷是否過時,以及根據什麼策略來進行刪除的。服務器
redis 設置過時時間:expire key time
(以秒爲單位) – 這是最經常使用的方式setex(String key, int seconds, String value)
– 字符串獨有的方式markdown
除了字符串本身獨有設置過時時間的方法外,其餘方法都須要依靠 expire
方法來設置時間併發
若是沒有設置時間,那緩存就是永不過時ide
若是設置了過時時間,以後又想讓緩存永不過時,使用 persist key
memcached
三種過時策略:性能
目錄:
atom
含義:在設置 key 的過時時間的同時,爲該 key 建立一個定時器,讓定時器在 key 的過時時間來臨時,對 key 進行刪除
優勢:保證內存被儘快釋放
缺點:若過時 key 不少,刪除這些 key 會佔用不少的 CPU 時間,在 CPU 時間緊張的狀況下, CPU 不能把全部的時間用來作要緊的事兒,還須要去花時間刪除這些 key,定時器的建立耗時,若爲每個設置過時時間的 key 建立一個定時器(將會有大量的定時器產生),性能影響嚴重。
懶漢式刪除流程:
對於按期刪除,在程序中有一個全局變量 current_db
來記錄下一個將要遍歷的庫,假設有 16 個庫,咱們這一次按期刪除遍歷了 10 個,那此時的 current_db
就是 11,下一次按期刪除就從第11個庫開始遍歷,假設 current_db
等於 15 了,那麼以後遍歷就再從 0 號庫開始(此時 current_db==0)
在實際中,若是咱們要本身設計過時策略, 在使用 懶漢式刪除+按期刪除
時,控制時長和頻率這個尤其關鍵,須要結合服務器性能,以及併發量等狀況進行調整,以至最佳。
Redis 有四個不一樣的命令能夠用於設置鍵的生存時間(鍵能夠存在多久)或過時時間(鍵何時會被刪除):
EXPIRE<key><ttl>
命令用於將鍵 key 的生存時間設置爲 ttl 秒。
PEXPIRE<key><ttl>
命令用於將鍵 key 的生存時間設置爲 ttl 毫秒。
EXPIREAT<key><timestamp>
命令用於將鍵 key 的過時時間設置爲 timestamp 所指定的秒數時間戳。
PEXPIREAT<key><timestamp>
命令用於將鍵 key 的過時時間設置爲 timestamp 所指定的毫秒數時間戳。
原理:
雖然有多種不一樣單位和不一樣形式的設置命令,但實際上 EXPIRE、PEXPIRE、EXPIREAT
三個命令都是使用PEXPIREAT
命令來實現的:不管客戶端執行的是以上四個命令中的哪個,通過轉換以後,最終的執行效果都和執行 PEXPIREAT
命令同樣。
redisDb 結構的 expires 字典保存了數據庫中全部鍵的過時時間,咱們稱這個字典爲過時字典
過時字典的鍵是一個指針,這個指針指向鍵空間中的某個鍵對象(也便是某個數據庫鍵)。
過時字典的值是一個 long long 類型的整數,這個整數保存了鍵所指向的數據庫鍵的過時時間——一個毫秒精度的 UNIX 時間戳。
下圖展現了一個帶有過時字典的數據庫例子,在這個例子中,鍵空間保存了數據庫中的全部鍵值對,而過時字典則保存了數據庫鍵的過時時間。
爲了展現方便,圖中的鍵空間和過時字典中重複出現了兩次 alphabet 鍵對象和 book 鍵對象。在實際中,鍵空間的鍵和過時字典的鍵都指向同一個鍵對象,因此不會出現任何重複對象,也不會浪費任何空間。
圖中的過時字典保存了兩個鍵值對:
第一個鍵值對的鍵爲 alphabet 鍵對象,值爲1385877600000,這表示數據庫鍵 alphabet 的過時時間爲1385877600000(2013年12月1日零時)。
第二個鍵值對的鍵爲 book 鍵對象,值爲 1388556000000,這表示數據庫鍵 book 的過時時間爲1388556000000(2014年1月1日零時)。當客戶端執行 PEXPIREAT 命令(或者其餘三個會轉換成 PEXPIREAT 命令的命令)爲一個數據庫鍵設置過時時間時,服務器會在數據庫的過時字典中關聯給定的數據庫鍵和過時時間。
在服務器執行如下命令以後
過時字典將新增一個鍵值對,其中鍵爲 message 鍵對象,而值則爲 1391234400000(2014年2月1日零時),如圖:
如下是 PEXPIREAT 命令的僞代碼定義
PERSIST 命令能夠移除一個鍵的過時時間
PERSIST 命令就是 PEXPIREAT 命令的反操做:PERSIST 命令在過時字典中查找給定的鍵,並解除鍵和值(過時時間)在過時字典中的關聯。
過時鍵的斷定
經過過時字典,程序能夠用如下步驟檢查一個給定鍵是否過時: