redis詳解及應用(雪崩、擊穿、穿透)

1、 redis的簡介與安裝css

引用:https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/html


2、 redis的配置文件介紹android

引用:https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/redis

3、redis的五大數據類型詳細用法sql

引用:https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/數據庫


4、redis的底層數據結構緩存

引用:https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/安全


5、 redis的五大數據類型實現原理服務器

引用:https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/數據結構



6、 持久化

RDB持久化是把當前進程數據生成快照保存到硬盤的過程,觸發RDB持
久化過程分爲手動觸發和自動觸發。

配置引用: https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/

RDB的優缺點
優勢:

  1. RDB是一個緊湊壓縮的二進制文件,表明Redis在某個時間點上的數據快照。很是適用於備份,全量複製等場景。好比每6小時執行bgsave備份,並把RDB文件拷貝到遠程機器或者文件系統中(如hdfs),用於災難恢復。
  2. Redis加載RDB恢復數據遠遠快於AOF的方式。

缺點:

  1. RDB方式數據沒辦法作到實時持久化/秒級持久化。由於bgsave每次運

行都要執行fork操做建立子進程,屬於重量級操做,頻繁執行成本太高。

  1. RDB文件使用特定二進制格式保存,Redis版本演進過程當中有多個格式的RDB版本,存在老版本Redis服務沒法兼容新版RDB格式的問題。

針對RDB不適合實時持久化的問題,Redis提供了AOF持久化方式來解決。

AOF持久化

AOF(append only file)持久化:以獨立日誌的方式記錄每次寫命令,重啓時再從新執行AOF文件中的命令達到恢復數據的目的。
AOF的主要做用是解決了數據持久化的實時性,目前已是Redis持久化的主流方式

配置引用: https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/

AOF的工做流程以下圖:

1)全部的寫入命令會追加到aof_buf(緩衝區)中。
2)AOF緩衝區根據對應的策略向硬盤作同步操做。
3)隨着AOF文件愈來愈大,須要按期對AOF文件進行重寫,達到壓縮的目的。
4)當Redis服務器重啓時,能夠加載AOF文件進行數據恢復。

更詳細的工做原理能夠參考書籍【Redis開發與運維(付磊)】
或者參考這篇文章:
https://redisbook.readthedocs...

舒適提示
場景:AOF文件可能存在結尾不完整的狀況,好比機器忽然掉電致使AOF尾部文件命令寫入不全。

解決方法:

  1. 對於錯誤格式的AOF文件,先進行備份,而後採用redis-check-aof --fix命令進行修復,修復後使用diff-u對比數據的差別,找出丟失的數據,有些能夠人工修改補全。
  2. Redis爲咱們提供了aof-load-truncated配置來兼容這種狀況,默認開啓。加載AOF時,當遇到此問題時會忽略並繼續啓動,同時打印以下警告日誌:
# !!! Warning: short read while loading the AOF file !!! # !!! Truncating the AOF at offset 397856725 !!! # AOF loaded anyway because aof-load-truncated is enabled

持久化的優化

Redis持久化功能一直是影響Redis性能的高發地。主要有如下方面

1. fork操做
原由:對於高流量的Redis實例OPS可達5萬以上,若是fork操做耗時在秒級別將拖慢Redis幾萬條命令執行,對線上應用延遲影響很是明顯。正常狀況下fork耗時應該是每GB消耗20毫秒左右。能夠在info stats統計中查latest_fork_usec指標獲取最近一次fork操做耗時,單位微秒。

優化
1)優先使用物理機或者高效支持fork操做的虛擬化技術,避免使用Xen。
2)控制Redis實例最大可用內存,fork耗時跟內存量成正比,線上建議每一個Redis實例內存控制在10GB之內。
3)合理配置Linux內存分配策略,避免物理內存不足致使fork失敗。
4)下降fork操做的頻率,如適度放寬AOF自動觸發時機,避免沒必要要的全量複製等。

2. CPU
CPU開銷分析。子進程負責把進程內的數據分批寫入文件,這個過程屬於CPU密集操做,一般子進程對單核CPU利用率接近90%。
CPU消耗優化。Redis是CPU密集型服務,不要作綁定單核CPU操做。因爲子進程很是消耗CPU,會和父進程產生單核資源競爭。
不要和其餘CPU密集型服務部署在一塊兒,形成CPU過分競爭。若是部署多個Redis實例,儘可能保證同一時刻只有一個子進程執行重寫工做。

3. 內存
內存消耗優化:
1)同CPU優化同樣,若是部署多個Redis實例,儘可能保證同一時刻只有一個子進程在工做。
2)避免在大量寫入時作子進程重寫操做,這樣將致使父進程維護大量頁副本,形成內存消耗。

4. 硬盤
優化方法以下:
a)不要和其餘高硬盤負載的服務部署在一塊兒。如:存儲服務、消息隊列服務等。
b)AOF重寫時會消耗大量硬盤IO,能夠開啓配置no-appendfsync-on-rewrite,默認關閉。表示在AOF重寫期間不作fsync操做。
c)當開啓AOF功能的Redis用於高流量寫入場景時,若是使用普通機械磁盤,寫入吞吐通常在100MB/s左右,這時Redis實例的瓶頸主要在AOF同步硬盤上。
d)對於單機配置多個Redis實例的狀況,能夠配置不一樣實例分盤存儲AOF文件,分攤硬盤寫入壓力。

注:配置no-appendfsync-on-rewrite=yes時,在極端狀況下可能丟失整個AOF重寫期間的數據,須要根據數據安全性決定是否配置。

5.AOF追加阻塞
當開啓AOF持久化時,經常使用的同步硬盤的策略是everysec,用於平衡性能和數據安全性。對於這種方式,Redis使用另外一條線程每秒執行fsync同步硬盤。當系統硬盤資源繁忙時,會形成Redis主線程阻塞,

阻塞流程分析:
1)主線程負責寫入AOF緩衝區。
2)AOF線程負責每秒執行一次同步磁盤操做,並記錄最近一次同步時間。
3)主線程負責對比上次AOF同步時間:若是距上次同步成功時間在2秒內,主線程直接返回。若是距上次同步成功時間超過2秒,主線程將會阻塞,直到同步操做完成。

優化AOF追加阻塞問題主要是優化系統硬盤負載,優化方法參考第4點


7、事務

爲了保證多條命令組合的原子性,Redis提供了簡單的事務功能以及集成Lua腳原本解決這個問題。簡單介紹Redis中事務的使用方法以及它的侷限性。

127.0.0.1:6379> multi OK 127.0.0.1:6379> sadd user:a:follow user:b QUEUED 127.0.0.1:6379> zadd user:b:fans 1 user:a QUEUED 127.0.0.1:6379> exec 1) (integer) 1 2) (error) WRONGTYPE Operation against a key holding the wrong kind of value 127.0.0.1:6379> sismember user:a:follow user:b (integer) 1

Redis提供了簡單的事務功能,**將一組須要一塊兒執行的命令放到multi和
exec兩個命令之間**。

multi命令表明事務開始
exec命令表明事務結束
它們之間的命令是原子順序執行的。
不支持事務中的回滾特性

Lua腳本

基本語法教程可參考下面這個網址:
https://www.runoob.com/lua/lu...

在Redis中執行Lua腳本有兩種方法:eval和evalsha。

 

8、發佈訂閱

 

Redis提供了基於「發佈/訂閱」模式的消息機制,此種模式下,消息發佈
者和訂閱者不進行直接通訊,發佈者客戶端向指定的頻道(channel)發佈消息,訂閱該頻道的每一個客戶端均可以收到該消息。

  1. 發佈消息
publish channel:sports "Tim won the championship"
  1. 訂閱消息
subscribe channel:sports

有關訂閱命令有兩點須要注意

  • 客戶端在執行訂閱命令以後進入了訂閱狀態,只能接收subscribe、

psubscribe、unsubscribe、punsubscribe的四個命令。

  • 新開啓的訂閱客戶端,沒法收到該頻道以前的消息,由於Redis不會對

發佈的消息進行持久化。

Redis發佈訂閱與成熟MQ的比較

(1)MQ支持多種消息協議,包括AMQP,MQTT,Stomp等,而且支持JMS規範,但Redis沒有提供對這些協議的支持; 
(2)MQ提供持久化功能,但Redis沒法對消息持久化存儲,一旦消息被髮送,若是沒有訂閱者接收,那麼消息就會丟失; 
(3)MQ提供了消息傳輸保障,當客戶端鏈接超時或事務回滾等狀況發生時,消息會被從新發送給客戶端,Redis沒有提供消息傳輸保障。

總之,MQ所提供的功能遠比Redis發佈訂閱要複雜,畢竟Redis不是專門作發佈訂閱的,可是若是系統中已經有了Redis,而且須要基本的發佈訂閱功能,就沒有必要再安裝MQ了,由於可能MQ提供的功能大部分都用不到,並且你能夠容忍redis發佈訂閱的缺點的話,能夠考慮用它。

 9、主從複製及哨兵模式

配置引用:https://www.cnblogs.com/ysocean/tag/Redis%E8%AF%A6%E8%A7%A3/

主節點Master 只有一個,一旦主節點掛掉以後,從節點無法擔起主節點的任務,那麼整個系統也沒法運行。若是主節點掛掉以後,從節點可以自動變成主節點,那麼問題就解決了,因而哨兵模式誕生了。

哨兵模式就是不時地監控redis是否按照預期良好地運行(至少是保證主節點是存在的),若一臺主機出現問題時,哨兵會自動將該主機下的某一個從機設置爲新的主機,並讓其餘從機和新主機創建主從關係。

 

 10、redis雪崩、擊穿、穿透

https://www.toutiao.com/i6755313319684342276/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&from=singlemessage&timestamp=1572913492&app=news_article&utm_source=weixin&utm_medium=toutiao_android&req_id=2019110508245201000804313323AE21C8&group_id=6755313319684342276

一、redis雪崩效應

因爲redis設置失效時間,當全部key在同一時間失效,併發直接打入DB,致使DB崩潰。

舉個簡單的例子:若是全部首頁的Key失效時間都是12小時,中午12點刷新的,我零點有個秒殺活動大量用戶涌入,假設當時每秒 6000 個請求,原本緩存在能夠扛住每秒 5000 個請求,可是緩存當時全部的Key都失效了。此時 1 秒 6000 個請求所有落數據庫,數據庫必然扛不住,它會報一下警,真實狀況可能DBA都沒反應過來就直接掛了。此時,若是沒用什麼特別的方案來處理這個故障,DBA 很着急,重啓數據庫,可是數據庫立馬又被新的流量給打死了。這就是我理解的緩存雪崩。

我刻意看了下我作過的項目感受再吊的都不容許這麼大的QPS直接打DB去,不過沒慢SQL加上分庫,大表分表可能還還算能頂,可是跟用了Redis的差距仍是很大。

解決:

處理緩存雪崩簡單,在批量往Redis存數據的時候,把每一個Key的失效時間都加個隨機值就行了,這樣能夠保證數據不會在同一時間大面積失效,我相信,Redis這點流量仍是頂得住的。

若是Redis是集羣部署,將熱點數據均勻分佈在不一樣的Redis庫中也能避免所有失效的問題,不過本渣我在生產環境中操做集羣的時候,單個服務都是對應的單個Redis分片,是爲了方便數據的管理,可是也一樣有了可能會失效這樣的弊端,失效時間隨機是個好策略。

或者設置熱點數據永遠不過時,有更新操做就更新緩存就行了(好比運維更新了首頁商品,那你刷下緩存就完事了,不要設置過時時間),電商首頁的數據也能夠用這個操做,保險。

 

二、緩存穿透

緩存穿透是指緩存和數據庫中都沒有的數據,而用戶不斷髮起請求,咱們數據庫的 id 都是1開始自增上去的,如發起爲id值爲 -1 的數據或 id 爲特別大不存在的數據。這時的用戶極可能是攻擊者,攻擊會致使數據庫壓力過大,嚴重會擊垮數據庫。

解決:

接口層增長校驗,好比用戶鑑權校驗,參數作校驗,不合法的參數直接代碼Return

 

三、緩存擊穿

這個跟緩存雪崩有點像,可是又有一點不同,緩存雪崩是由於大面積的緩存失效,打崩了DB,而緩存擊穿不一樣的是緩存擊穿是指一個Key很是熱點,在不停的扛着大併發,大併發集中對這一個點進行訪問,當這個Key在失效的瞬間,持續的大併發就穿破緩存,直接請求數據庫,就像在一個無缺無損的桶上鑿開了一個洞。

 

解決:

從緩存取不到的數據,在數據庫中也沒有取到,這時也能夠將對應Key的Value對寫爲null、位置錯誤、稍後重試這樣的值具體取啥問產品,或者看具體的場景,緩存有效時間能夠設置短點,如30秒(設置太長會致使正常狀況也無法使用)。

這樣能夠防止攻擊用戶反覆用同一個id暴力攻擊,可是咱們要知道正經常使用戶是不會在單秒內發起這麼屢次請求的,那網關層Nginx本渣我也記得有配置項,可讓運維大大對單個IP每秒訪問次數超出閾值的IP都拉黑。

 

總結:

  • 事前:Redis 高可用,主從+哨兵,Redis cluster,避免全盤崩潰。
  • 事中:本地 ehcache 緩存 + Hystrix 限流+降級,避免MySQL 被打死。
  • 過後:Redis 持久化 RDB+AOF,一旦重啓,自動從磁盤上加載數據,快速恢復緩存數據。
相關文章
相關標籤/搜索