exists——判定 key 是否存在
語法:
exists key [key...]
# 返回值:key 存在的個數
- 針對多個
key
來說,是非常有用的 - 時間復雜度 O ( 1 ) O(1) O(1)
Redis
組織這些key
就是按照哈希表的方式來組織的。Redis
支持很多數據結構指的是value
可以是一些復雜的數據結構
Redis
自身的這些鍵值對,是通過哈希表的方式來組織的,Redis
具體的值,又可以是一些數據結構
Redis
是一個客戶端-服務器結構的程序,客戶端和服務器之間通過網絡來進行通信- 每次我們敲的命令,都是由
Redis
客戶端包裝成一個請求,發送給Redis
服務器,服務器再返回響應- 因此最好不要把 key 分開寫。分開寫會產生更多輪次的網絡通信,效率比較低,成本比較高
[!qoute] 封裝和分用
- 進行網絡通信的時候,發送方發送一個數據,這個數據就要從應用層,到物理層,層層封裝(每一層協議都要加上報頭或者尾)==>發送一個快遞,要包裝一下,要包裝好多層
- 接收方收到一個數據,這個數據就要從物理層,到應用層,層層分用(把每一層協議中的報頭或者尾給拆掉)==>收到一個快遞,要拆快遞,拆很多層
- 這些過程都是要消耗時間,消耗
CPU
的
Redis
自身也非常清楚上述問題,所以 Redis
的很多命令都支持一次就能操作多個 key
的/多種操作
del——刪除指定的 key
可以一次刪除一個或者多個
語法:
del key [key...]
- 時間復雜度 O ( 1 ) O(1) O(1)
- 返回值:刪除掉的
key
的個數
在
MySQL
中,刪除類的操作
drop database
drop table
drop from
…
這些都是非常危險的操作,一旦刪除之后,數據就沒了。但在 Redis 中,危險程度就小很多了- 因為 Redis 的主要應用場景,就是作為緩存,里面存的只是一個熱點數據,而全量數據是在
MySQL
中。如果把Redis
中的key
刪除了幾個,問題不大,大不了再從MySQL
中讀就可以了。- 但是如果把所有的數據,或者一大半數據都干沒了,這種影響就會很大。本來是靠
Redis
幫MySQL
負重前行,Redis
沒數據了,大部分請求就直接打給MySQL
了,然后就容易把MySQL
搞掛- 相比之下,如果是
MySQL
這樣的數據,哪怕誤刪了一個數據,都可能影響是很大的- 但如果是把
Redis
作為數據庫,此時誤刪數據的影響就大了
expire——給 key 設置過期時間
單位為秒
key
存活時間超過這個 expire
指定的值,就會被自動刪除
- 在很多業務場景,都是有時間限制的
- 驗證碼。要實現驗證碼一分鐘失效的功能,我們就可以把這個驗證碼信息存儲到
Redis
中,將expire
設置為60
,等到一分鐘后Redis
里面的驗證碼信息被刪除,就查詢不到了 - 點外賣。優惠券,在指定時間有效
- 分布式鎖。基于
Redis
實現分布式鎖,為了避免出現不能正確解鎖的情況,通常都會在加鎖的時候設置一下過期事假(所謂的使用Redis
作為分布式鎖,就是給Redis
里寫一個特殊的key
value
)
- 驗證碼。要實現驗證碼一分鐘失效的功能,我們就可以把這個驗證碼信息存儲到
語法:
expire key seconds
pexpire key 毫秒
- 對于計算機來說,秒是一個非常長的時間,下面的時間單位是毫秒
ttl——查詢過期時間
time to live
在網絡原理,
IP
協議報頭中,就有一個TTL
字段
IP
中的TTL
不是用時間衡量過期的,而是次數
查詢當前 key 的過期時間還剩多少
語法:
ttl key //秒
pttl key //毫秒
- 返回剩余過期時間
- 返回
-1
表示沒有關聯過期時間 - 返回
-2
表示key
不存在
過期策略是如何實現的
#高頻面試
一個 Redis
中可能同時存在很多很多 key
,這些 key
中有很大一部分都有過期時間。此時,Redis
服務器怎么知道哪些 key
已經過期要被刪除,哪些 key
還沒過期?
- 如果直接遍歷所有的 key,顯然是行不通的,效率非常低
- Redis 整體的策略是兩方面
- 定期刪除
- 惰性刪除
惰性刪除
- 假設這個
key
已經到達過期時間了,但是暫時還沒刪除它,key
還在 - 緊接著,后面又一次訪問,正好用到了這個
key
,于是這次訪問就會讓Redis
服務器觸發刪除key
的操作,同時再放回一個nil
- 你去超市買水,正要付錢的時候,看了一眼日期,發現過期了,于是老板就說不賣了,于是就把這瓶水下架了,這就是“惰性刪除”
- 老板也不清楚哪些過期了,哪些沒過期,就在賣出的時候做一次檢查,如果過期了就不賣了,如果還沒過期,就繼續賣
但顯然,單靠惰性刪除肯定是不靠譜的,一個超市這么多商品,怎么可能全去靠用戶去檢查,所以肯定還得要有一個輔助的機制——定期刪除
定期刪除
這個超市老板,要定期查看超市里面的商品,看是否有過期產品
- 但是如果超市商品很多,那么每次遍歷一遍就非常慢
- 所以,每次抽取一部分,進行驗證過期時間。保證抽取檢查的過程足夠快
為什么這對定期刪除的時間有明確的要求呢?
- 因為
Redis
是單線程程序,主要的任務是處理每個命令的任務(剛才掃描過期key
…) - 如果掃描過期
key
消耗的時間太多了,就可能導致正常處理請求命令就被阻塞了(產生了類似key *
的效果)
雖然有了上述兩種策略結合,但整體的效果仍一般。仍然有可能會有很多過期的 key
被殘留了,沒有及時刪除掉
但是 Redis
為了對上述進行補充,還提供了一系列的內存淘汰策略