知識點二:Redis 的 key 規範,雪崩,擊穿,穿透,布隆過濾器,分佈式鎖,隊列,持久化,同步,內存淘汰

Redis 的 key 的設置規範

  1. redis 的 key 要求全大寫,命令規範是 系統前綴 : 業務標識,其中系統前綴爲,領域縮寫_系統簡稱_子系統名,業務標識爲,下劃線分隔的業務特徵字符串,要求在保證可讀性的前提下,key 的長度儘可能短,value 小於10K;

緩存雪崩,擊穿和穿透

  1. 緩存雪崩是指,大量 key 同時失效,導致請求都進入存儲層,給存儲層造成壓力,甚至宕機;

  2. 緩存雪崩的解決方案是,設置 key 失效時間時添加一個隨機值;

  3. 緩存擊穿是指,非常熱點的 key 失效,導致大量請求都進入存儲層來重建緩存,給存儲層造成壓力;

  4. 緩存擊穿的解決方案是,在同步代碼塊中重建緩存,保證 key 失效後,只有一個線程請求到數據庫來重建緩存,或者設置 key 爲不失效,依賴定時任務去刷新緩存;

  5. 緩存穿透是指,大量請求訪問緩存和數據庫不存在的結果,導致每次請求都到達存儲層,給存儲層造成壓力;

  6. 緩存穿透的解決方案,一種是將數據庫查詢爲 null 也存放到緩存中,如果出現大量查詢 null 的請求,可能會佔滿緩存,導致有用緩存被淘汰,另一種方案,是在緩存和數據庫之間加入一個布隆過濾器,過濾掉數據庫不存在的請求,減少數據庫壓力;

		redis 4.0 之後就引入了布隆過濾器,通過 bf.add,bf.exists 來使用
		更多參考:https://www.zhihu.com/search?type=content&q=redis%20%E6%95%96%E4%B8%99

布隆過濾器

  1. 類似 HashMap 的結構,底層是數組,數組元素是 bit,put 元素時,將元素值經過多次哈希,得到多個數組下標值,將這些數組下標值都設置爲 1,這樣判斷元素是否存在時,只需要同樣多次哈希,判斷各個下標元素的與運算是否是 1;

  2. 布隆過濾器,使用多次哈希,是爲降低哈希衝突的概率,不同的元素,多次哈希得到的下標都相同的概率,比只一次哈希相同的概率要低,構造布隆過濾器時,參數有數據類型,插入值的個數和期望的誤判率(默認是3%),誤判率和存儲空間,查找時間相關;

  3. 布隆過濾器用於檢索元素是否在海量集合中,優點是節省空間,查找效率高,但有一定的誤判率和刪除比較困難,集合中存在的元素,一定返回存在,集合中不存在的元素,可能因爲與其他元素哈希衝突,會返回存在;

  4. 在緩存擊穿上的應用,將數據庫表中的主鍵或唯一字段,放入布隆過濾器中,每次請求在緩存查找不存在時,首先在布隆過濾器中判斷是否存在,如果存在才向數據庫發送請求,否則直接返回結果不存在;

  5. 布隆過濾器還可以用在垃圾郵箱過濾等海量數據查重的場景上;

Redis 構造分佈式鎖

  1. 加鎖,setnx(key, value),只有 key 不存在才能設置成功,且是原子操作,所以只有一個線程能設置成功,表示加鎖成功,通常加鎖給 key 設置一個過期時間,來保證鎖能被釋放,不會因爲業務節點問題,導致死鎖;

  2. 釋放鎖,刪除掉 key 即可,del key;

  3. 如何解決過期時間到了,但是同步操作還未執行完,還想繼續持有鎖的問題,通過加鎖線程,同時啓動一個守護線程,每間隔一定時間檢查下,如果仍持有鎖,就延長 key 的過期時間,這樣能保證同步操作未完成,能繼續持有鎖,並且不會無限延期,因爲鎖釋放,會顯示關閉守護線程,節點宕機,守護線程也會自動終止;

  4. 如果要實現可重入鎖,在設置 value 的時候,將加鎖的線程的唯一 id 放入,這樣下次加鎖判斷一下節點 id 是否是自身,來決定是否加鎖成功,

  5. 真實生產應用場景,通常使用 Redisson 的開源框架來實現,並且 zookeeper 來實現分佈式鎖更容易;

	更多參考:https://cloud.tencent.com/developer/article/1349732
	https://blog.csdn.net/belongtocode/article/details/102511520

Redis 隊列

  1. redis 隊列,使用 list 結構,生產者 rpush,消費者 lpop,可使用 blpop 來阻塞獲取消息,如果要實現 1:N 的廣播,可以使用 pub/sub 的訂閱模式,這種模式當沒有消費者時,消息會丟失,如果要保證消息不丟失,需要使用其他專業 mq;

  2. 構造延遲隊列,sortedset 結構,生產者 zadd myqueue score value 時,value 爲消息內容,score 爲時間戳,消費者通過 zrangebyscore 來獲取 N 秒之前的消息,比如消息延時 20s 後可以被消費,那麼生產者 zadd,score 爲當前時間戳,而消費者每次獲取消息通過 zrangebyscore myqueue 0 當前時間-20s 來獲取消息,就只會獲取 20s 之前生產的消息,起到延遲消費的作用;

Redis 持久化

  1. 有 RDB 和 AOF 兩種方式,RDB 是全量持久化,持久化 redis 的全量數據,單次耗時時間長,AOF 是增量持久化,只持久化操作命令,單次耗時時間短;

  2. 每次 RDB,客戶端會暫停幾毫秒到幾秒的時間,且兩次 RDB 之間,如果發生 Redis 重啓,會丟失該時間間隔的操作數據;

  3. AOF 可以設置爲按照時間間隔進行持久化,或者每次執行命令都進行持久化,前者可能發生數據丟失,後者不會丟失數據,但影響性能,並且 AOF 會定期重寫,來壓縮命令空間,如果有誤操作,需要立即關閉重寫,刪除 aof 中的命令,然後通過 rdb 恢復備份,從備份時間點來重放 AOF 來恢復數據;

  4. 通常兩者結合使用,RDB 間隔時間長,進行全量備份,而 AOF 設置爲 1s 進行一次備份,這樣最多隻丟失 2s 的數據;

Redis 主從同步,從從同步

  1. 觸發同步時,主節點執行一次 bgsave,生成 rdb 備份,這個過程中主節點接收的操作,都在內存 buffer 中記錄,等待 rdb 備份被髮送到從節點,從節點加載完數據後,主節點再將內存 buffer 的操作發送到從節點;

  2. 之後,主從節點依賴通過 AOF 日誌,進行同步;

Redis 的內存淘汰機制

  1. 定期刪除,redis 如果設置了 key 的過期時間,並不是到期馬上刪除,而是 redis 會將所有有過期時間的 key 集中存放,然後每隔一段時間(默認100ms),隨機選擇 20 個 key,判斷是否過期,來進行刪除,並且如果需要刪除的 key 比例超過 1/4,會重複選擇刪除的過程;

  2. 惰性刪除,是當應用主動獲取某個 key 時,redis 會判斷是否過期,如果過期,直接刪除,不返回給應用;

  3. 內存淘汰策略,是指當 redis 所佔內存超過設置值時,redis 需要對內存中的一些 key 進行淘汰;

	noeviction:不淘汰任何key,返回錯誤
	allkeys-lru:針對所有 key,通過 LRU 算法淘汰最久沒有使用的 key
	volatile-lru:針對有過期時間的 key,通過 LRU 算法淘汰最久沒有使用的 key
	allkeys-random:針對所有 key,隨機刪除
	volatile-random:針對有過期時間的 key,隨機刪除
	volatile-ttl:針對有過期時間的 key,刪除馬上要過期的 key
	volatile-lfu:針對有過期時間的 key,刪除使用頻率最少的 key
	allkeys-lfu:針對所有 key,刪除使用頻率最少的 key
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章