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架構時,儘可能做到高可用,當個別節點、部分機器出現問題後,不影響整體。