Redis從生米煮成熟飯

Redis爲何選用單線

單線程減少線程上下文切換和鎖競爭。

網絡IO模型採用IO多路複用,使用EPOLL註冊讀寫事件通知,同步非阻塞。

Redis單線程如何發揮多核CPU優勢

在單臺服務器上運行多個redis實例。
使用taskset命令,將每個redis實例和cpu核心進行綁定

Redis分佈式鎖實現

setnx key value
如果key不存在,則創建並賦值。成功返回1 失敗返回0。
同時設置過期時間: expire key seconds

也可使用set命令配合NX EX選項一次性設置
SET key value EX 10086 NX

緩存雪崩、緩存擊穿、緩存穿透

緩存雪崩: 大量的KEY過期時間過於集中,導致瞬時很多緩存失效,由此可能導致數據庫壓力陡然升高。
解決方案: 將失效時間隨機打亂,如在系統啓動預熱時設定一定程度上離散的過期時間。

緩存擊穿: 緩存中某一個KEY過期失效,如果此時有大量請求過來無法命中緩存的KEY,緩存層像被鑿開了一個口子一樣流入大量數據庫查詢請求
解決方案:雙重校驗方式從數據庫中讀取數據到緩存。雙重校驗:第一層查詢緩存失敗後,進入臨界區,保證同時只有一個請求線程讀取數據庫,進入臨界區後再次嘗試緩存,仍然沒有命中則查詢數據庫。

緩存穿透: 外部請求不斷查詢一個系統中不存在的數據,服務無法命中緩存轉而每次嘗試從數據庫中查詢。
解決方案

  1. 對查詢結果爲空key設置值爲null的緩存,犧牲緩存空間換響應時間。
  2. 把所有非法的key映射到一個bitmap中,通過bitmap攔截。《布隆過濾器》原理

Redis如何刪除過期key

  1. 主動刪除:redis 默認每隔一定時間檢查已過期key進行刪除, 或者內存不足時觸發主動刪除機制

  2. 惰性刪除:在有請求讀寫key時再檢查key是否過期,過期則刪除

Redis如何持久化

AOF

AOF(Append Only File ): 記錄每次redis的寫命令,如對一個key更新10次,記錄10條寫指令。可以設置每秒一次或者每個寫動作發生後追加。
優點: 持久化頻率高,異常down機時數據丟失少。
缺點: 文件大,恢復時相對耗時。

Redis默認使用RDB持久化,可同時開啓AOF持久化,如下

appendonly yes
appendfilename "appendonly.aof"

AOF重寫

AOF文件體積過大時會進行重寫。重寫的作用是用一條命令去記錄鍵值對,代替之前記錄該鍵值對的多個命令。如一個key自增100次,原文件記錄了100條指令,重寫後將原來的指令合併成爲最新的一條,由此大大壓縮AOF文件體積。

重寫採用寫時賦值(Copy On Write)原理,不直接操作原文件。

RDB

RDB:快照持久化。在特點時間點保存全量的數據信息。
優點: 恢復時直接將快照文件加載到內存,速度快。
缺點: 因爲全量數據量大,持久化頻率一般設置較低。異常關機時會丟失上次持久化到關機時刻的變更數據。

如RDB方式配置

save 900 1 #在900s內如果有1條數據被寫入,則產生一次快照。 
save 300 10#在300s內如果有10條數據被寫入,則產生一次快照   
save 60 10000 #在60s內如果有10000條數據被寫入,則產生一次快照  
stop-writes-on-bgsave-error yes    # 如果爲yes則表示,當備份進程出錯的時候,   主進程就停止進行接受新的寫入操作,這樣是爲了保護持久化的數據一致性的問題。

bgsave

也可通過basave命令手動觸發快照的持久化。bgsave fork出子進程,採用寫時複製機制寫入。不阻塞主進程的工作(對比save命令)。

AOF和RDB可搭配同時使用,開啓AOF時,redis啓動默認從AOF日誌文件中重建緩存。

Redis集羣方案

  1. Sentinel: 哨兵模式,主要實現高可用。解決Redis原有的主從同步模式,當Master實例故障時導致整個集羣無法工作的缺陷。Sentinel是一個獨立運行的進程,檢測Redis集羣狀態,如Master因故障下線時則在集羣機器中發起選舉選出新的Master節點。
  2. Cluster: 解決單臺主機的內存容量有限。 Redis集羣定義有16384個哈希槽,每個節點負責一段。每個key通過CRC16校驗後對16384取模來決定放置哪個分片。

Redis和數據庫不一致問題

數據庫更新時需要觸發緩存更新

如果先刪除緩存再進行數據庫更新, 可能在數據庫更新之前,新的請求進來因爲沒有命中緩存從數據庫中讀取舊數據。
如果先進行數據庫更新在刪除緩存,可能出現數據庫寫入成功後刪除緩存失敗。導致緩存仍然是舊數據。

網上流傳雙刪策略: 先刪除緩存–> 數據庫寫入 ——》再次刪除緩存。

好處是能數據更新前能預檢查下redis工作狀態,但是關鍵的問題:寫入後刪除緩存時失敗的情況仍然可能存在。根本的解決方案應該在寫入後刪除失敗時增加重試機制,或者回滾數據庫更新。

Redis內存淘汰策略

Redis使用內存超過 maxmemory 配置大小時觸發內存淘汰策略。

  • noeviction:不刪除策略,內存達到上限時直接返回錯誤信息
  • allkeys-random: 針對所有的key,隨機刪除一部分
  • allkeys-lru: 針對所有的key,優先刪除最少使用的
  • volatile-random: 針對設置了過期時間的key,隨機刪除一部分
  • volatile-ttl: 針對設置了過期時間的key,優先刪除最快過期的key

參考

Redis中文官方網站

原文地址:《Redis從生米煮成熟飯》
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章