一、什么是Redis
Redis是一種基于內存的數據庫,對數據的讀寫操作都是在內存中完成,因此讀寫速度非常快,用于存儲鍵值對、緩存、消息隊列、分布式鎖等。
二、Redis和mencached的區別
相同:都是基于內存的數據庫,讀寫都很快
不同:
1.Redis支持的數據類型更豐富(string、list、hash、set、zset);而mencached只支持string
2.Redis支持數據的持久化,可以將內存中數據保存在磁盤中,重啟的時候可以重新加載使用;mencached沒有持久化功能
3.Redis原生支持集群模式
三、Redis實現持久化
1.AOF日志:Redis在執行完一條寫操作命令后,把該命令以追加的方式寫入到一個文件里面(先執行后寫入),重啟Redis時會讀取該文件里的命令逐一操作來進行數據恢復
2.AOF重寫機制:當AOF日志過大時,讀取每一條鍵值對最新的操作命令記錄到新的AOF文件中。相當于壓縮了AOF日志。
3.RDB快照:每次執行把內存中所有的數據都記錄到磁盤中,這樣恢復數據的效率會比AOF高些。用save(主線程里執行)和bgsave命令。
4.混合持久化:工作在AOF日志重寫的過程。新的AOF文件前半部分是RDB格式的全量數據,后半部分是AOF格式的增量數據。重啟時由于前半部分是RDB全量數據所以加載速度會很快,后半部分的增量數據會使丟失的數據更少。
四、Redis實現服務高可用
1.主從復制:主服務器進行讀寫操作;從服務器只進行讀操作;主服務器將寫操作同步到從服務器
2.哨兵模式:哨兵群進行監控,當主服務器發生故障,選舉出新的主服務器
五、Redis過期刪除策略
1.惰性刪除:數據庫訪問key時才檢測key是否過期
2.定期刪除:每隔一段時間隨機從數據庫中取出一定數量的key進行檢查
六、Redis內存淘汰算法
1.LRU(least recently used,最近最少使用算法):最新操作的鍵會被移動到表頭
2.Redis采用的近似LRU算法:在Redis對象結構體中添加一個額外字段來記錄此數據的最后一次訪問時間,使用隨機采樣的方式淘汰數據
七、Redis的三大緩存問題
1.緩存雪崩:大量數據同時過期,或Redis故障宕機,大量請求直接訪問數據庫導致數據庫壓力驟增
解決方法:
(1)均勻設置過期時間
(2)設置互斥鎖。訪問到過期數據,在對其進行緩存重構時加鎖(鎖要設置超時時間避免阻塞)。未能獲得互斥鎖的要么等待要么返回默認值或空值
(3)后臺更新緩存
(4)服務器熔斷或請求限流
(5)構建高可用的Redis主從集群
2.緩存擊穿:頻繁被訪問的熱點數據過期了,也會導致大量請求直接訪問數據庫
解決方法:
(1)互斥鎖
(2)后臺更新緩存
3.緩存穿透:數據在緩存和數據庫里都沒有。緩存里找不到->訪問數據庫->數據庫找不到無法重構緩存
解決方法:
(1)限制非法請求
(2)設置空值或默認值,后續請求得到該值后不會繼續訪問數據庫
(3)使用布隆過濾器(位圖+哈希函數)。寫入數據庫數據時用布隆過濾器做標記,緩存失效后去布隆過濾器里快速判斷數據是否存在。這樣請求只會訪問混存和布隆過濾器
八、Redis保證數據庫和緩存一致性
先更新數據庫,再刪除緩存。并用以下兩種方法異步操作緩存
1.重試機制:引入消息隊列記錄刪除緩存的操作。刪除緩存失敗的話可以從消息隊列中讀數據重試刪除操作
2.訂閱MySQL binlog:更新數據庫的時候產生一條日志記錄在binlog里,通過訂閱binlog日志拿到具體要操作的數據再去刪除緩存
參考文檔:小林coding圖解Redis