Redis
緩存中間件
基礎篇
鍵值數據庫 key Value
是NoSql數據庫
非結構化、無關聯的、非SQL、BASE(無法滿足ACID)
命令執行是單線程,符合原子性。
低延遲、速度塊(基于內存,IO多路復用,良好的編碼)
支持數據的持久化(定期把數據寫到磁盤)
支持主從集群、分片集群
支持多語言客戶端
一、常用命令
1.停止服務
停止 Redis 服務
sudo systemctl stop redis檢查服務狀態
sudo systemctl status redis
2.啟動服務
redis-server#指定配置文件啟動
redis-server redis.conf
3.查看運行狀態
ps -ef | grep redis
4.打開客戶端
redis-cli -a 200112
5.通常命令
#查看符合模板的所有key
keys
#刪除指定的一個key
DEL
#判斷key是否存在
exists
#給key設置一個有效期
EXPIRE
#查看key的剩余有效期
TTL
二、常見數據類型
Redis 支持多種數據類型,每種類型針對不同的使用場景設計,以下是常見的五種核心數據類型及其特點:
String(字符串)
? 特點:二進制安全的字符串,可存儲文本、序列化數據或數字。
? 常用命令:
? SET key value
/ GET key
? INCR key
(原子性遞增)
? MSET
/ MGET
(批量操作)
? 應用場景:
? 緩存HTML片段、用戶會話(Session)。
? 計數器(如文章閱讀量)。
? 分布式鎖(通過 SETNX
)。
最大是512M
SET、GET、MSET、MGET。增減刪除
INCR。讓整型key+1
java對象序列化為json字符串,然后存儲。
Hash(哈希表)
? 特點:鍵值對集合,適合存儲對象。
? 常用命令:
? HSET key field value
/ HGET key field
? HGETALL key
(獲取所有字段和值)
? HINCRBY
(字段數值增減)
? 應用場景:
? 存儲用戶信息(如用戶ID為Key,字段為姓名、年齡等)。
? 商品詳情頁的屬性存儲。
可以對字段做CRUD
List(列表)
? 特點:有序的字符串列表,支持雙向操作(類似雙向隊列)。
? 常用命令:
? LPUSH key value
/ RPOP key
(左右插入和彈出)
? LRANGE key start end
(范圍查詢)
? BLPOP
(阻塞式彈出)
? 應用場景:
? 消息隊列(生產者-消費者模型)。
? 最新消息排行(如朋友圈動態)。
? 歷史記錄(如用戶瀏覽日志)。
Set(集合)
? 特點:無序且唯一的字符串集合,支持交并差運算。
? 常用命令:
? SADD key member
/ SMEMBERS key
? SINTER key1 key2
(交集)
? SISMEMBER key member
(判斷存在性)
? 應用場景:
? 標簽系統(如文章標簽)。
? 共同好友(交集運算)。
? 去重(如UV統計)。
Sorted Set(有序集合)
? 特點:成員關聯一個分數(score),按分數排序且唯一。
? 常用命令:
? ZADD key score member
/ ZRANGE key start end
? ZRANK key member
(獲取排名)
? ZRANGEBYSCORE
(按分數范圍查詢)
? 應用場景:
? 排行榜(如游戲分數排名)。
? 延遲隊列(用時間戳作為分數)。
? 范圍查詢(如價格區間篩選)。
其他擴展類型(需Redis模塊支持)
? Bitmaps:通過位操作實現布隆過濾器、用戶簽到。
? HyperLogLog:基數統計(如UV去重)。
? Streams:消息流(類似Kafka,用于時序數據)。
選擇依據
? 讀寫模式:高頻寫入用List,需排序用Sorted Set。
? 查詢需求:精確查詢用Hash,范圍查詢用Sorted Set。
? 數據量:小對象用String,大對象用Hash分字段存儲。
合理利用這些類型能顯著提升Redis性能和資源利用率。
常見面試題
一、緩存穿透
緩存穿透說簡單點就是大量請求的 key 是不合理的,根本不存在于緩存中,也不存在于數據庫中。這就導致這些請求直接到了數據庫上,根本沒有經過緩存這一層,對數據庫造成了巨大的壓力,可能直接就被這么多請求弄宕機了
解決辦法
1.緩存無效 key
表名:列名:主鍵名:主鍵值作為key
2.布隆過濾器
把所有可能存在的請求的值都存放在布隆過濾器中,當用戶請求過來,先判斷用戶發來的請求的值是否存在于布隆過濾器中。不存在的話,直接返回請求參數錯誤信息給客戶端,存在的話才會走下面的流程。
3.接口限流
二、緩存擊穿
緩存擊穿中,請求的 key 對應的是 熱點數據,該數據 存在于數據庫中,但不存在于緩存中(通常是因為緩存中的那份數據已經過期)。這就可能會導致瞬時大量的請求直接打到了數據庫上,對數據庫造成了巨大的壓力,可能直接就被這么多請求弄宕機了。
舉個例子:秒殺進行過程中,緩存中的某個秒殺商品的數據突然過期,這就導致瞬時大量對該商品的請求直接落到數據庫上,對數據庫造成了巨大的壓力。
解決辦法
- 永不過期(不推薦):設置熱點數據永不過期或者過期時間比較長。
- 提前預熱(推薦):針對熱點數據提前預熱,將其存入緩存中并設置合理的過期時間比如秒殺場景下的數據在秒殺結束之前不過期。
- 加鎖(看情況):在緩存失效后,通過設置互斥鎖確保只有一個請求去查詢數據庫并更新緩存
三、緩存雪崩
緩存在同一時間大面積的失效,導致大量的請求都直接落到了數據庫上,對數據庫造成了巨大的壓力。 這就好比雪崩一樣,摧枯拉朽之勢,數據庫的壓力可想而知,可能直接就被這么多請求弄宕機了
緩存中的大量數據在同一時間過期,這個時候突然有大量的請求需要訪問這些過期的數據。這就導致大量的請求直接落到數據庫上,對數據庫造成了巨大的壓力。
針對 Redis 服務不可用的情況:
- Redis 集群:采用 Redis 集群,避免單機出現問題整個緩存服務都沒辦法使用。Redis Cluster 和 Redis Sentinel 是兩種最常用的 Redis 集群實現方案
- 多級緩存:設置多級緩存,例如本地緩存+Redis 緩存的二級緩存組合,當 Redis 緩存出現問題時,還可以從本地緩存中獲取到部分數據。
針對大量緩存同時失效的情況:
- 設置隨機失效時間(可選):為緩存設置隨機的失效時間,例如在固定過期時間的基礎上加上一個隨機值,這樣可以避免大量緩存同時到期,從而減少緩存雪崩的風險。
- 提前預熱(推薦):針對熱點數據提前預熱,將其存入緩存中并設置合理的過期時間,比如秒殺場景下的數據在秒殺結束之前不過期。
- 持久緩存策略(看情況):雖然一般不推薦設置緩存永不過期,但對于某些關鍵性和變化不頻繁的數據,可以考慮這種策略