Redis 中設置過時時間主要經過如下四種方式:html
下面分別來看以上這些命令的具體實現。java
127.0.0.1:6379> set key value OK 127.0.0.1:6379> expire key 100 (integer) 1 127.0.0.1:6379> ttl key (integer) 97
其中命令 ttl
的全稱是 Time To Live
表示此鍵值在 n 秒後過時。例如,上面的結果 97
表示 key
在 97s 後過時。redis
127.0.0.1:6379> set key2 value2 OK 127.0.0.1:6379> pexpire key2 100000 (integer) 1 127.0.0.1:6379> pttl key2 (integer) 94524
其中 pexpire key2 100000
表示設置 key2
在 100000 毫秒(100秒)後過時。shell
127.0.0.1:6379> set key3 value3 OK 127.0.0.1:6379> expireat key3 1573472683 (integer) 1 127.0.0.1:6379> ttl key3 (integer) 67
其中 expireat key3 1573472683
表示 key3
在時間戳 1573472683
後過時(精確到秒),使用 ttl
查詢能夠發如今 67s 後 key3
會過時。數據庫
小貼士:在 Redis 可使用 time 命令查詢當前時間的時間戳(精確到秒),示例以下: 127.0.0.1:6379> timesegmentfault
- "1573472563"
- "248426"
127.0.0.1:6379> set key4 value4 OK 127.0.0.1:6379> pexpireat key4 1573472683000 (integer) 1 127.0.0.1:6379> pttl key4 (integer) 3522
其中 pexpireat key4 1573472683000
表示 key4
在時間戳 1573472683000
後過時(精確到毫秒),使用 ttl
查詢能夠發如今 3522ms 後 key4
會過時。服務器
字符串中幾個直接操做過時時間的方法,以下列表:框架
實現示例以下:函數
127.0.0.1:6379> set k v ex 100 OK 127.0.0.1:6379> ttl k (integer) 97
127.0.0.1:6379> set k2 v2 px 100000 OK 127.0.0.1:6379> pttl k2 (integer) 92483
127.0.0.1:6379> setex k3 100 v3 OK 127.0.0.1:6379> ttl k3 (integer) 91
使用命令: persist key
能夠移除鍵值的過時時間,以下代碼所示:unix
127.0.0.1:6379> ttl k3 (integer) 97 127.0.0.1:6379> persist k3 (integer) 1 127.0.0.1:6379> ttl k3 (integer) -1
能夠看出第一次使用 ttl
查詢 k3
會在 97s 後過時,當使用了 persist
命令以後,在查詢 k3
的存活時間發現結果是 -1,它表示 k3
永不過時。
本文將使用 Jedis 框架來實現對 Redis 過時時間的操做,以下代碼所示:
public class TTLTest { public static void main(String[] args) throws InterruptedException { // 建立 Redis 鏈接 Jedis jedis = new Jedis("xxx.xxx.xxx.xxx", 6379); // 設置 Redis 密碼(若是沒有密碼,此行可省略) jedis.auth("xxx"); // 存儲鍵值對(默認狀況下永不過時) jedis.set("k", "v"); // 查詢 TTL(過時時間) Long ttl = jedis.ttl("k"); // 打印過時日誌 System.out.println("過時時間:" + ttl); // 設置 100s 後過時 jedis.expire("k", 100); // 等待 1s 後執行 Thread.sleep(1000); // 打印過時日誌 System.out.println("執行 expire 後的 TTL=" + jedis.ttl("k")); } }
程序的執行結果爲:
過時時間:-1 執行 expire 後的 TTL=99
能夠看出使用 Jedis 來操做 Redis 的過時時間仍是很方便的,可直接使用 jedis.ttl("k")
查詢鍵值的生存時間,使用 jedis.expire("k",seconds)
方法設置過時時間(精確到秒)。
小貼士:使用 Jedis 以前,先要把 Jedis 引入到程序中,若是使用的是 Maven 項目的,直接在 pom.xml 文件中添加如下引用:
<!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>version</version> </dependency>
更多過時操做方法,以下列表:
完整示例代碼以下:
public class TTLTest { public static void main(String[] args) throws InterruptedException { // 建立 Redis 鏈接 Jedis jedis = new Jedis("xxx.xxx.xxx.xxx", 6379); // 設置 Redis 密碼(若是沒有密碼,此行可省略) jedis.auth("xxx"); // 存儲鍵值對(默認狀況下永不過時) jedis.set("k", "v"); // 查詢 TTL(過時時間) Long ttl = jedis.ttl("k"); // 打印過時日誌 System.out.println("過時時間:" + ttl); // 設置 100s 後過時 jedis.expire("k", 100); // 等待 1s 後執行 Thread.sleep(1000); // 打印過時日誌 System.out.println("執行 expire 後的 TTL=" + jedis.ttl("k")); // 設置 n 毫秒後過時 jedis.pexpire("k", 100000); // 設置某個時間戳後過時(精確到秒) jedis.expireAt("k", 1573468990); // 設置某個時間戳後過時(精確到毫秒) jedis.pexpireAt("k", 1573468990000L); // 移除過時時間 jedis.persist("k"); } }
上面咱們講了過時鍵在 Redis 正常運行中一些使用案例,接下來,咱們來看 Redis 在持久化的過程當中是如何處理過時鍵的。 Redis 持久化文件有兩種格式:RDB(Redis Database)和 AOF(Append Only File),下面咱們分別來看過時鍵在這兩種格式中的呈現狀態。
RDB 文件分爲兩個階段,RDB 文件生成階段和加載階段。
從內存狀態持久化成 RDB(文件)的時候,會對 key 進行過時檢查,過時的鍵不會被保存到新的 RDB 文件中,所以 Redis 中的過時鍵不會對生成新 RDB 文件產生任何影響。
RDB 加載分爲如下兩種狀況:
RDB 文件加載的源碼能夠在 rdb.c 文件的 rdbLoad() 函數中找到,源碼所示:
/* Check if the key already expired. This function is used when loading * an RDB file from disk, either at startup, or when an RDB was * received from the master. In the latter case, the master is * responsible for key expiry. If we would expire keys here, the * snapshot taken by the master may not be reflected on the slave. * * 若是服務器爲主節點的話, * 那麼在鍵已通過期的時候,再也不將它們關聯到數據庫中去 */ if (server.masterhost == NULL && expiretime != -1 && expiretime < now) { decrRefCount(key); decrRefCount(val); // 跳過 continue; }
當 Redis 以 AOF 模式持久化時,若是數據庫某個過時鍵還沒被刪除,那麼 AOF 文件會保留此過時鍵,當此過時鍵被刪除後,Redis 會向 AOF 文件追加一條 DEL 命令來顯式地刪除該鍵值。
執行 AOF 重寫時,會對 Redis 中的鍵值對進行檢查已過時的鍵不會被保存到重寫後的 AOF 文件中,所以不會對 AOF 重寫形成任何影響。
當 Redis 運行在主從模式下時,從庫不會進行過時掃描,從庫對過時的處理是被動的。也就是即時從庫中的 key 過時了,若是有客戶端訪問從庫時,依然能夠獲得 key 對應的值,像未過時的鍵值對同樣返回。
從庫的過時鍵處理依靠主服務器控制,主庫在 key 到期時,會在 AOF 文件裏增長一條 del 指令,同步到全部的從庫,從庫經過執行這條 del 指令來刪除過時的 key。
本文咱們知道了 Redis 中的四種設置過時時間的方式:expire、pexpire、expireat、pexpireat,其中比較經常使用的是 expire 設置鍵值 n 秒後過時。
字符串中能夠在添加鍵值的同時設置過時時間,並可使用 persist 命令移除過時時間。同時咱們也知道了過時鍵在 RDB 寫入和 AOF 重寫時都不會被記錄。
過時鍵在主從模式下,從庫對過時鍵的處理要徹底依靠主庫,主庫刪除過時鍵以後會發送 del 命令給全部的從庫。
本文的知識點,以下圖所示:
http://www.javashuo.com/article/p-qtlhhixl-cq.html
http://www.javashuo.com/article/p-ymsgysfp-dd.html
關注下面二維碼,訂閱更多精彩內容。