1. 程式人生 > >Redis 面試常見問題

Redis 面試常見問題

Redis常見問題

  1. 為什麼使用Redis

    效能和併發(分散式鎖還有其他中介軟體可以代替)

    • 效能

      需要執行耗時特別久,且結果不頻繁變動的結果,將執行結果放入快取。後面的請求去快取中獲取,使得請求能夠迅速響應。

    • 併發

      在大併發情況下,所有的請求直接訪問資料庫,資料庫會出現連線異常。

      使用Redis做一個緩衝操作,讓請求先訪問Redis,而不是直接訪問資料庫

  2. 使用Redis有什麼缺點

    • 快取和資料庫雙寫一致性問題
    • 快取雪崩問題
    • 快取擊穿問題
    • 快取的併發競爭問題
  3. 單執行緒的Redis問什麼這麼快

    • 純記憶體操作
    • 單執行緒操作,避免了頻繁的上下文切換
    • 採用了非阻塞 I/O 多路複用機制(單個執行緒,通過跟蹤每個 I/O 流的狀態,來管理多個 I/O 流)
  4. Redis的資料型別,以及每種資料型別的使用場景

    • String

      最常規的 set/get 操作,一般做一些複雜的計數功能的快取

    • Hash

      value 存放的是結構化的物件,比較方便操作其中的某個欄位。

    • List

      可以做簡單的訊息佇列的功能。

      可以利用 lrange 命令,做基於Redis的分頁功能

    • Set

      可以做全域性去重的功能(如果使用 JVM 自帶的Set進行去重,還需要起一個公共服務)

      利用交集、並集、差集操作,計算共同喜好、全部喜好、獨有喜好

    • Sorted Set

      多了一個權重引數 Score, 集合中的元素能夠按 Score 進行排列

      可以做排行榜應用。延時任務。範圍查詢

  5. Redis 的過期策略以及記憶體淘汰機制

    Redis 採用定期刪除 + 惰性刪除策略

    • 為什麼不用定時刪除策略

      定時刪除,需要用一個定時器來負責監視 Key,過期自動刪除。十分消耗 CPU 資源。

      在大併發請求下,CPU 要將時間應用在處理請求,而不是刪除 Key。

    • 定期刪除 + 惰性刪除如何工作

      定期刪除,Redis 預設每 100ms 檢查,是否有過期的 Key,有過期的 Key 則刪除。

      檢查並不是將所有的 Key 都進行檢查,而是隨機抽取檢查。

      只採用定期刪除策略,會導致很多 Key 到時間沒有刪除。於是,就引入了惰性刪除。

      惰性刪除,在獲取某個 Key 的時候,Redis 會檢查一下,這個 Key 如果設定了過期時間,那麼是否過期了?如果過期了此時就會刪除

    採用定期刪除+惰性刪除為什麼記憶體還是越來越高?

    如果定期刪除沒刪除 key。然後也沒有即時去請求 Key,也就是說惰性刪除也沒生效。Redis的記憶體會越來越高。那麼就應該採用記憶體淘汰機制。

    在 redis.conf 中有一行配置:

    # maxmemory-policy volatile-lru
    

    該配置就是配記憶體淘汰策略的:

    • noeviction: 當記憶體不足以容納新寫入資料時,新寫入操作會報錯。
    • allkeys-lru: 當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近很少使用的 Key。
    • allkeys-random: 當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個 Key。
    • volatile-lru: 當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最少使用的 Key。
    • volatile-random: 當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,隨機移除某個 Key。
    • **volatile-ttl:**當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的 Key 優先移除。
  6. Redis 和資料庫雙寫一致性問題

    一致性問題是分散式常見問題,還可以再分為最終一致性和強一致性。資料庫和快取雙寫,就必然存在不一致的問題。

    採取正確更新策略,先更新資料庫,再刪快取。其次,因為可能存在刪除快取失敗的問題,提供一個補償措施。

  7. 如何應對快取穿透和快取雪崩問題

    **快取穿透,**請求快取中不存在的資料,導致所有的請求都傳至資料庫上,導致資料庫連線異常。

    快取穿透解決方案:

    • **利用互斥鎖:**快取失效的時候,先獲得鎖,得到鎖了,再去請求資料庫。沒得到鎖,則休眠一段時間重試。
    • 採用非同步更新策略,無論 Key 是否取到值,都直接返回。
    • 提供一個能迅速判斷請求是否有效的攔截機制

    **快取雪崩,**即快取同一時間大面積的失效,同時又來了一波請求,結果請求都傳至資料庫,從而導致資料庫連線異常。

    快取雪崩解決方案:

    • 給快取的失效時間,加一個隨機值,避免集體失效

    • 使用互斥鎖

    • 雙快取。有兩個快取,快取 A 和快取 B。快取 A 的失效時間為 20 分鐘,快取 B 不設失效時間。自己做快取預熱操作。

      從快取 A 讀資料,有則直接返回;A 沒有資料,直接從 B 讀資料,直接返回,並且非同步啟動一個更新執行緒,更新執行緒同時更新快取 A 和快取 B。

  8. 如何解決 Redis 的併發競爭 Key 問題

    這個問題引發原因是,同時有多個子系統去 Set 一個 Key。

    • 如果對這個 Key 操作,不要求順序

      準備一個分散式鎖,大家去搶鎖,搶到鎖就做 set 操作

    • 如果對這個 Key 操作,要求順序

      在資料寫入時,同時儲存一個時間戳。

      寫入 Redis 前,比較時間戳,如果早於快取中的時間戳,則不做 set 操作。

      也可以利用佇列,set方法變成序列訪問

轉載自微信公眾號