大量key在同一時間過期,注意什么?
如果過期時間過於集中,會導致Redis可能會出現短暫的卡頓現象。嚴重的話會出現緩存雪崩,一般需要在時間上加一個隨機值,
使用過期時間分散一些。
Redis分布式鎖的實現原理
setnx命令設置唯一的key,只有不存在時才返回成功,這就相當於爭搶鎖。再使用expire給鎖加一個過期時間防止鎖忘記釋放,導致死鎖情況。
不過setnx和expire是兩個命令,可以使用set命令,將兩個操作合成一個原子操作
使用keys掃出指定模式key列表會有什么問題
由於Redis是單線程,keys指令在運行時會導致線程阻塞一段時間,線上服務會停頓
可以使用scan無阻塞地提取,但會有一定的重復概率,需要在客戶端做一次去重,所花時間比keys要長。
增量式迭代命令
如何使用Redis做異步隊列?
一般使用list結構,rpush生產消息,lpop消費消息。無消息時,適應sleep()重試或使用blpop阻塞直到有消息到來
如何Redis實現延時隊列
使用sortedset,拿時間戳作為score,消息內容作為key調用add來生間消息,消費者用zrangebyscore指令獲取N次之前的數據輪詢進行處理
怎么持久化
RDB:鏡像全量持久化
AOF:增量持久化。
Redis雪崩、穿透 擊穿
緩存同一時間大面積失效,導致大量的請求直接由db處理。就好像洪水一瞬點沖向小堤壩一樣。
穿透是指請求了緩存和數據庫中都沒有的數據,而用戶不斷發起請求。一般認為是惡意攻擊,永遠不要相信用戶的輸入參數,做好校驗。
緩存擊穿和雪崩有點像,是指某幾個key非常熱點,擔承了大量的請求,當這幾個key在失效的瞬點,持續的大並發就穿破緩存,直接請求數據庫,就像在一個完好無損的桶上鑿開了一個洞。
策略,
- 在批量往Redis存數據的時候,把每個Key的失效時間都加個隨機值。
- 如果是集群部署,將熱點數據均勻分布在不同的Redis庫也能避免。
- 或者熱點數據永不過期,有更新操作就更新緩存就好了。
- Nginx配置項
- 布隆過濾器
- 熱點數據永不過期
- 互斥鎖
小總結
- 事前:Redis高可用,主從+哨兵,Redis Cluster,避免全盤崩潰
- 事中:本地ehcache緩存+Hystrix限流+降級,避免 MySQL被打死
- 事后: Redis持久化RDB+AOF,一旦重啟,自動從磁盤上加載數據,快速恢復數據。
Redis為啥快
- 完全基於內存
- 數據結構簡單
- 采用單線程,避免不必要的上下文切換和競爭條件,
- 也不存在多進程或者是多線程導致的切換而消耗CPU,不用考慮各種鎖的問題。
- 使用多路I/O復用模型,非阻塞IO
- 底層通過機制優化
單進程單線程瓶頸怎么解決
單機多核開多個Redis實例,集群、主從同步讀寫分離
持久化問題
持久化的話是Redis高可用中比較重要的一個環節,因為Redis數據在內存的特性,持久化必須得有,我了解到的持久化是有兩種方式的。
- RDB:RDB 持久化機制,是對 Redis 中的數據執行周期性的持久化。
- AOF:AOF 機制對每條寫入命令作為日志,以 append-only 的模式寫入一個日志文件中,因為這個模式是只追加的方式,所以沒有任何磁盤尋址的開銷,所以很快,有點像Mysql中的binlog。
兩種方式都可以把Redis內存中的數據持久化到磁盤上,然后再將這些數據備份到別的地方去,RDB更適合做冷備,AOF更適合做熱備,比如我杭州的某電商公司有這兩個數據,我備份一份到我杭州的節點,再備份一個到上海的,就算發生無法避免的自然災害,也不會兩個地方都一起掛吧,這災備也就是異地容災,地球毀滅他沒辦法
哨兵?
主要功能:
- 集群監控:負責監控Redis master 和slave進程是否正常工作
- 消息通知:如果某個Redis實現有故障,那么哨兵負責發送消息作為報警通知給管理員
- 故障轉換:如果master node掛掉了,會自動轉換到slave node上
- 配置中心:如果故障轉移發生了,通知client客戶端新的master地址。
主從之間數據怎么同步
啟動slave時,會發送一個Pysnc命令給master,如果這個slave第一次連接到master,他會觸發一個全量復制。master會避動一個線程,生成RDB快照,
還會把新的寫請求都緩存在內存中,RDB文件生成后,master會將這個RDB發送給slave,slave拿到之后第一件事情就是寫進本地磁盤,然后加載進內存,然后
master會把內存里面緩存的那些新命名都發給slave.
過期策略
- 定期刪除,默認100ms就隨機抽一些設置了過期時間的Key,檢查是否過期,刪除。
- 惰性刪除,查詢時時再檢測是否過期,過期就刪除還不給你返回
- 內存淘汰機制
對於定期沒刪除又沒查詢的,近似LRU算法思路