(面試) redis相關問題

1. redis原理

Redis底層核心原理是基於事件的處理流程。主程序處於一個阻塞狀態的事件循環中等待事件,當有事件發生時,根據事件的屬性分到相應的處理含函數進行處理。事件是以併發的方式發送到服務處理器,服務處理器將事件整合到一個有序隊列中,並分發到具體的請求處理器進行處理。

Redis採用I/O多路複用的方式,封裝了操作系統底層select/epoll等函數,實現對多個套接字 (socket)的監聽,這些套接字就是對應多個不同客戶端的連接。最後由對應的處理器將處理的結果返回客戶端。  參考https://www.jianshu.com/p/397449cadc9a

2.redis是單線程還是多線程?

Redis 在 4.0 之前明明採用單線程但卻依然快的原因:基於內存操作、量身打造的數據結構、I/O 多路複用和非阻塞 I/O、避免了不必要的線程上下文切換。 Redis4.0 開始支持多線程,主要體現在大數據的異步刪除上面,例如:unlink key、flushdb async、flushall async 等。而 Redis6.0 的多線程則增加了對 I/O 讀寫的併發能力,因爲數據在用戶態和內核態之間穿梭是需要進行拷貝的,而這一步是阻塞的,所以通過多個線程並行操作從而更好的提升 Redis 的性能。

3.持久化

Redis爲持久化提供了兩種方式:

RDB:redis的數據存儲在內從中,不定期的將數據異步同步到磁盤上(半持久化), Redis DataBase 的縮寫。

AOF:記錄redis的所有寫操作到aof(append only file)文件中(全持久化) ,AOF 是Append only file的縮寫。

redis中默認使用的是RDB實現數據持久化

RDB持久化數據的優缺點:

優勢:

  • 適合大規模數據恢復
  • 對數據完整性和已執行要求不高

劣勢:

  • 在一定時間間隔內做一次備份,可能會造成最後一次數據丟失
  • fork時,內存中的數據被克隆一份,大致2倍的數據膨脹需要考慮

AOF持久化數據的優缺點:

優勢:

  • 該機制可以帶來更高的數據安全性,即數據持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。
  • 由於該機制對日誌文件的寫入操作採用的是append模式,因此在寫入過程中即使出現宕機現象,也不會破壞日誌文件中已經存在的內容。

劣勢:

  • 對於相同數量的數據集而言,AOF文件通常要大於RDB文件。RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
  • 根據同步策略的不同,AOF在運行效率上往往會慢於RDB。

4.redis架構

單機、主從複製、哨兵、集羣等

1. 單機版

  • 特點:簡單
  • 問題:1、內存容量有限 2、處理能力有限 3、無法高可用。

2.主從複製

  • Redis 的複製(replication)功能允許用戶根據一個 Redis 服務器來創建任意多個該服務器的複製品,其中被複制的服務器爲主服務器(master),而通過複製創建出來的服務器複製品則爲從服務器(slave)。 只要主從服務器之間的網絡連接正常,主從服務器兩者會具有相同的數據,主服務器就會一直將發生在自己身上的數據更新同步 給從服務器,從而一直保證主從服務器的數據相同。
  • 特點:
  • 1、master/slave 角色
  • 2、master/slave 數據相同
  • 3、降低 master 讀壓力在轉交從庫
  • 問題:
  • 無法保證高可用
  • 沒有解決 master 寫的壓力

3.哨兵

Redis sentinel 是一個分佈式系統中監控 redis 主從服務器,並在主服務器下線時自動進行故障轉移。其中三個特性:

  • 監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
  • 提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
  • 自動故障遷移(Automatic failover): 當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作。
  • 特點:
  • 1、保證高可用
  • 2、監控各個節點
  • 3、自動故障遷移
  • 缺點:主從模式,切換需要時間丟數據
  • 沒有解決 master 寫的壓力

4. 集羣

從redis 3.0之後版本支持redis-cluster集羣,Redis-Cluster採用無中心結構,每個節點保存數據和整個集羣狀態,每個節點都和其他所有節點連接。

  • 特點:
  • 1、無中心架構(不存在哪個節點影響性能瓶頸),少了 proxy 層。
  • 2、數據按照 slot 存儲分佈在多個節點,節點間數據共享,可動態調整數據分佈。
  • 3、可擴展性,可線性擴展到 1000 個節點,節點可動態添加或刪除。
  • 4、高可用性,部分節點不可用時,集羣仍可用。通過增加 Slave 做備份數據副本
  • 5、實現故障自動 failover,節點之間通過 gossip 協議交換狀態信息,用投票機制完成 Slave到 Master 的角色提升。
  • 缺點:
  • 1、資源隔離性較差,容易出現相互影響的情況。
  • 2、數據通過異步複製,不保證數據的強一致性

總結:如果在讀數據方面存在瓶頸,則建議採用哨兵模式;如是在寫數據方面存在瓶頸,則那建議採用集羣模式。

5.如何防止緩存穿透

  • 一般的緩存系統,都是按照key去緩存查詢,如果不存在對應的value,就應該去數據庫查詢。
  • 一些惡意的請求會故意大量查詢不存在的key,就會對數據庫造成很大的壓力。這就叫做緩存穿透。
  • 解決方案: 將查詢結果爲空的情況也進行緩存,只是緩存時間設置短一點。示例代碼如下:
  • 
    
    //1.redis 查詢 商品信息
    Object goodObj = redis.get (goodId);
    if(goodObj!=null){
     return  goodObj;
    }
    
    //2.查詢數據庫
    GoodDetails goodDetails = goodDetailsMapper.selectById(goodId)
    if( goodDetails!=null){
        //3.寫入redis ,存入10分鐘
        redis.setex(goodId,goodDetails,60*10)
    }
    else{
       //4.  設置無效請求存儲到Redis,並設置較低的過期時間 1分鐘
       Random sj = new Random(10)
        redis.setex(goodId,null,60*sj.next())
    
    }
    

6. 如何防止緩存雪崩

當緩存服務器重啓或者大量緩存集中在某一個時間段失效,這樣在失效的時候,會給後端系統帶來很大壓力。導致系統崩潰。

解決方案:

1、設計合理過期時間,錯開業務交叉存儲,如:在緩存的時候給過期時間加上一個隨機值,這樣就會大幅度的減少緩存在同一時間過期,判斷是否爲熱門商品,如果是則延長過期時間 ,否則則縮短過期時間 。

2、設計Redis架構時,儘可能做到高可用,當個別節點、部分機器出現問題後,不影響整體。

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