㈠ 該怎麼解決 Redis 緩存穿透和緩存雪崩問題
緩存雪崩: 由於緩存層承載著大量請求,有效地 保護了存儲層,但是如果緩存層由於某些原因不能提供服務,比如 Redis 節點掛掉了,熱點 key 全部失效了,在這些情況下,所有的請求都會直接請求到資料庫,可能會造成資料庫宕機的情況。
預防和解決緩存雪崩問題,可以從以下三個方面進行著手:
1、使用 Redis 高可用架構:使用 Redis 集群來保證 Redis 服務不會掛掉
2、緩存時間不一致: 給緩存的失效時間,加上一個隨機值,避免集體失效
3、限流降級策略:有一定的備案,比如個性推薦服務不可用了,換成熱點數據推薦服務
緩存穿透: 緩存穿透是指查詢一個根本不存在的數據,這樣的數據肯定不在緩存中,這會導致請求全部落到資料庫上,有可能出現資料庫宕機的情況。
預防和解決緩存穿透問題,可以考慮以下兩種方法:
1、緩存空對象: 將空值緩存起來,但是這樣就有一個問題,大量無效的空值將佔用空間,非常浪費。
2、布隆過濾器攔截: 將所有可能的查詢key 先映射到布隆過濾器中,查詢時先判斷key是否存在布隆過濾器中,存在才繼續向下執行,如果不存在,則直接返回。布隆過濾器有一定的誤判,所以需要你的業務允許一定的容錯性。
㈡ redis 宕機數據怎麼辦
用redis保存的*.rdb文件恢復即喊孝滾可。
另外redis還有AOF功慎槐能,啟動時可以自動恢復到前一條查詢。鄭余
㈢ 每天一個知識點:宕機情況下,Redis 如何實現快速恢復
上一篇文章,我們講到了宕機情況下,Redis 如何進行數據備份,那麼,數據備份之後如何快速恢復呢?我的建議是使用內存快照(Redis Database)。
AOF 方法進行故障恢復的時候,需要逐一把操作日誌都執行一遍。如果操作日誌非常多,Redis 就會恢核沒復得很緩慢,影響到正常使用。RDB 既可以保證可靠性,還能在宕機時實現快速恢復。
Redis 的數據都在內存中,為了提供所有數據的可靠性保證,它執行的是全量快照,也就是說,把內存中的所有數據都記錄到磁碟中,這就類似於給 100 個人拍合影,把每一個人都拍進照片里。這樣做的好處是,一次性記錄了所有數據,一個都不少。
Redis 提供了兩個命令來生成 RDB 文件,分別是 save 和 bgsave。
bgsave 可以避免阻塞,但避免阻塞和正常處理寫操作並不是一回事。此時,主線程的確沒有阻塞,可以正常接收請求,但是,為了保證快照完整性,它只能處理讀操作,因為不能修改正在執行快照的數據。為了快照而暫停寫操作,肯定是不能接受的。所以這個時候,Redis 就會藉助操作系統提供的寫時復制技術(Copy-On-Write, COW),在執行快照的同時,正常處理寫操作。簡單來說,bgsave 子進程是由主線程 fork 生成的,可以共享主線鏈豎程的所有內存數據。bgsave 子進程運行後,開始讀取主線程的內存數據,並把它們寫入 RDB 文件。此時,如果主線程對這些數據也都是讀操作(例如圖中的鍵值對 A),那麼,主線程和 bgsave 子進程相互不影響。但是,如果主線程要修改一塊數據(例如圖中的鍵值對 C),那麼,這塊數據就會被復制一份,生成該數據的副本(鍵值對 C』)。然後,主線程在這個數據副本上進行修改。同時,bgsave 子進程可以繼續把原來的數據(鍵值對 C)寫入 RDB 文件。
Redis 4.0 中提出了一個棚氏大混合使用 AOF 日誌和內存快照的方法。簡單來說,內存快照以一定的頻率執行,在兩次快照之間,使用 AOF 日誌記錄這期間的所有命令操作。這樣一來,快照不用很頻繁地執行,這就避免了頻繁 fork 對主線程的影響。而且,AOF 日誌也只用記錄兩次快照間的操作,也就是說,不需要記錄所有操作了,因此,就不會出現文件過大的情況了,也可以避免重寫開銷。
關於 AOF 和 RDB 的選擇問題,有三點建議:
㈣ 「故障演練」 Redis Cluster集群,當master宕機,主從切換
性能不夠,緩存來湊
一個高並發系統肯定少不了緩存的身影,手型皮為了保證緩存服務的高可用,我們通常採用 Redis Cluster 集群模式。
描述:
集群部署採用了 3主3從 拓撲結構, 數據讀寫 訪問master節點, slave節點負責備份。
隨便登錄一台 redis 節點,都可以看到集群的slot的槽位分步區間,以及對應的主從節點映射關系。
人為模擬,master-1 機器意外宕機
此時,Redis Cluster 集群能自動感知,並自動完成主備切換,對應的slave會被選舉為新的master節點
看下 redis cluster 集群最新的主從關系
看似也沒什麼問題,一切正常
此時 Spring Boot 應用依然在線服務,當我們再嘗試操作緩存時,會報錯
問題邊界還是非常清晰的。
Redis Cluster 集群已經完成了切換。
但是 Spring Boot 客戶端 沒有動態感知到 Redis Cluster 的最新集群信息畢差
原因分析:
SpringBoot 2.X 版本, Redis默認的連接池採用 Lettuce
當Redis 集群節點發生變化後,Letture默認是不會刷新節點拓撲
解決方案:
將 Letture 二方包仲裁掉
然後,引入 Jedis 相關二方包
編譯代碼租衫,並重新啟動 SpringBoot 微服務,萬事俱備,只欠再次驗證
重新模擬將 127.0.0.1:8001 master 節點宕機,看看系統的日誌
從列印的日誌來看,客戶端已經感知到了 主備切換 ,並與最新的主節點 127.0.0.1:8004 初始化了 24 個連接。
然後,回歸業務功能, 讀寫緩存 數據也都是操作最新的主節點。
還有一種方案: 刷新節點拓撲視圖
Lettuce 官方描述:
解決方案:
編寫代碼
㈤ docker部署,集成redis mysql,經常宕機怎麼解決
docker 自帶重啟策略,restart有三個參數:no,on-failure,always
一般選擇on-failure,也就是非正常宕機都或謹孝重啟,手動停止不重啟。
1.no為默認值,表示容器退出時,docker不自動重啟容器
2.on-failure表示,若容器的退出狀態非0,則docker自動重啟容器,還可以晌喊指定重衫稿啟次數,若超過指定次數未能啟動容器則放棄:
3.always表示,只要容器退出,則docker將自動重啟容器
㈥ django redis-cache服務重啟後,緩存還在嗎
還在,這個存儲在redis裡面,redis本身帶持久化機制,正常的伺服器重啟對這個沒有影響,除非你的redis 碰到突然crash這類的問題,可能會影響短時間內的數據正常。
㈦ redis 如何重啟 linux下請輸入命令不要用kill 的方式
1、如果是用apt-get或者yum install安裝的redis,可以直接通過下面的命令停止/啟動/重啟redis:/etc/init.d/redis-server stop/etc/init.d/redis-server start/etc/init.d/redis-server restart
2、如果是通過源碼安裝的redis,則可以通過redis的客戶端程序redis-cli的shutdown命令來重啟redis。
㈧ Redis內存滿了怎麼辦
長期把Redis做緩存用,總有一天Redis內存會滿的,怎麼處理呢?
在Redis的配置文件 redis.conf 文件中,配置 maxmemory 的大小參數如下所示:
倘若實際的存儲中超出了Redis的配置參數的大小時,Redis中有 淘汰策略 ,把 需要淘汰的key給淘汰掉,整理出干凈的一塊內存給新的key值使用 。
Redis提供了 6種的淘汰策略 ,其中默認的是 noeviction ,這6中淘汰策略如下:
LRU(Least Recently Used) 即表示最近最少使用,也就是在最近的時間內最少被訪問的key,演算法根據數據的歷史訪問記錄來進行淘汰數據。
它的核心的思想就是: 假如一個key值在最近很少被使用到,那麼在將來也很少會被訪問 。
實際上Redis實現的LRU並不是真正的LRU演算法,也就是名義上我們使用LRU演算法淘汰鍵,但是實際上被淘汰的鍵並不一定是真正的最久沒用的。
Redis使用的是近似的LRU演算法, 通過隨機採集法淘汰key,每次都會隨機選出5個key,然後淘汰裡面最近最少使用的key 。
這里的5個key只是默認的個數,具體的個數也可以在配置文件中進行配置,在配置文件中的配置如下圖所示:
當近似LRU演算法取值越大謹手激的時候就會越接近真實的LRU演算法,可以這樣理解,因為 取值越大那麼獲取的數據就越全,淘汰中的數據的就越接近最近最少使用的數據 。
那麼為了實現根據時間實現LRU演算法,Redis必須為每個key中額外的增加一個內薯猜存空間用於存儲每個key的時間,大小是3位元組。
在Redis 3.0中對近似的LRU演算法做了一些優化,Redis中會維護大小是 16 的一個候選池的內存。
當第一次隨機選取的采樣數據,數據都會被放進候選池中,並且候選池中的數據會根據時間進行排序。
當第二次以後選取的數據,只有 小於候選池內的最小時間 的才會被放進候選池中。
當某一時刻候選池的數據滿了,那麼時間最大的key就會被擠出候選池。當執行淘汰時,直接從候選池中選取最近訪問時間最小的key進行淘汰。
這樣做的目的就是選取出最近似符合最近最少被訪問的key值,能夠正確的淘汰key值,因為隨機選取的樣本中的最小時間可能不是真正意義上的最小時間。
但是LRU演算法有一個弊端:就是假如一個key值在以前都沒有被訪問到,然而最近一次被訪問到了,那麼就會認為它是熱點數據,不會被淘汰。
然而有些數據以前經常被訪問到,只是最近的時間內沒有被訪問到,這樣就導致這些數據很可能被淘汰掉,這樣一來就會出現誤判而淘汰熱點數據。
於是在Redis 4.0的時候除了LRU演算法,新加了一種LFU演算法, 那麼什麼是LFU演算法演算法呢?
LFU(Least Frequently Used) 即表示最近頻繁被使用,也就是最近的時間段內,頻繁被訪問的key,它以最近的時間段的被訪問次祥襪數的頻率作為一種判斷標准。
它的核心思想就是:根據key最近被訪問的頻率進行淘汰,比較少被訪問的key優先淘汰,反之則優先保留。
LFU演算法反映了一個key的熱度情況,不會因為LRU演算法的偶爾一次被訪問被認為是熱點數據。
在LFU演算法中支持 volatile-lfu 策略和 allkeys-lfu 策略。
在Redis種有三種刪除的操作此策略,分別是:
在Redis中持久化的方式有兩種 RDB 和 AOF
在RDB中是以快照的形式獲取內存中某一時間點的數據副本,在創建RDB文件的時候可以通過 save 和 bgsave 命令執行創建RDB文件。
這兩個命令都不會把過期的key保存到RDB文件中 ,這樣也能達到刪除過期key的效果。
當在啟動Redis載入RDB文件的時候, Master 不會把過期的key載入,而 Slave 會把過期的key載入。
在AOF模式下,Redis提供了Rewite的優化措施,執行的命令分別是 REWRITEAOF 和 BGREWRITEAOF , 這兩個命令都不會把過期的key寫入到AOF文件中,也能刪除過期key 。
RDB 是一種快照存儲持久化方式,具體就是將 Redis 某一時刻的內存數據保存到硬碟的文件當中,默認保存的文件名為 mp.rdb ,而在 Redis 伺服器啟動時,會重新載入 mp.rdb 文件的數據到內存當中恢復數據。
開啟RBD持久化方式
開啟 RDB 持久化方式很簡單,客戶端可以通過向 Redis 伺服器發送 save 或 bgsave 命令讓伺服器生成 rdb 文件,或者通過伺服器配置文件指定觸發 RDB 條件。
save 命令是一個同步操作。
當客戶端向伺服器發送 save 命令請求進行持久化時,伺服器會阻塞 save 命令之後的其他客戶端的請求,直到數據同步完成。
與 save 命令不同, bgsave 命令是一個非同步操作。
當客戶端發服務發出 bgsave 命令時, Redis 伺服器主進程會 forks 一個子進程來數據同步問題,在將數據保存到rdb文件之後,子進程會退出。
所以,與 save 命令相比, Redis 伺服器在處理 bgsave 採用子線程進行IO寫入,而主進程仍然可以接收其他請求,但 forks 子進程是同步的,所以 forks 子進程時,一樣不能接收其他請求,這意味著,如果forks一個子進程花費的時間太久(一般是很快的),bgsave命令仍然有阻塞其他客戶的請求的情況發生。
除了通過客戶端發送命令外,還有一種方式,就是在 Redis 配置文件中的 save 指定到達觸發RDB持久化的條件,比如【多少秒內至少達到多少寫操作】就開啟 RDB 數據同步。
例如我們可以在配置文件redis.conf指定如下的選項:
之後在啟動伺服器時載入配置文件。
這種通過伺服器配置文件觸發RDB的方式,與bgsave命令類似,達到觸發條件時,會forks一個子進程進行數據同步,不過最好不要通過這方式來觸發RDB持久化,因為設置觸發的時間太短,則容易頻繁寫入rdb文件,影響伺服器性能,時間設置太長則會造成數據丟失。
介紹了三種讓伺服器生成rdb文件的方式,無論是由主進程生成還是子進程來生成,其過程如下:
Redis 的另外一個持久化方式: AOF(Append-only file) 。
與 RDB 存儲某個時刻的快照不同, AOF 持久化方式會記錄客戶端對伺服器的每一次寫操作命令,並將這些寫操作以 Redis 協議追加保存到以後綴為 aof 文件末尾,在Redis伺服器重啟時,會載入並運行 aof 文件的命令,以達到恢復數據的目的。
Redis默認不開啟AOF持久化方式,我們可以在配置文件中開啟並進行更加詳細的配置,如下面的redis.conf文件:
在上面的配置文件中,我們可以通過 appendfsync 選項指定寫入策略,有三個選項
客戶端的每一個寫操作都保存到 aof 文件當,這種策略很安全,但是每個寫請注都有IO操作,所以也很慢。
appendfsync 的默認寫入策略,每秒寫入一次 aof 文件,因此,最多可能會丟失1s的數據。
Redis 伺服器不負責寫入 aof ,而是交由操作系統來處理什麼時候寫入 aof 文件。更快,但也是最不安全的選擇,不推薦使用。
AOF將客戶端的每一個寫操作都追加到 aof 文件末尾,比如對一個key多次執行incr命令,這時候, aof 保存每一次命令到aof文件中,aof文件會變得非常大。
aof文件太大,載入aof文件恢復數據時,就會非常慢,為了解決這個問題,Redis支持aof文件重寫,通過重寫aof,可以生成一個恢復當前數據的最少命令集,比如上面的例子中那麼多條命令,可以重寫為:
通過在redis.conf配置文件中的選項no-appendfsync-on-rewrite可以設置是否開啟重寫,這種方式會在每次fsync時都重寫,影響伺服器性能,因此默認值為no,不推薦使用。
客戶端向伺服器發送bgrewriteaof命令,也可以讓伺服器進行AOF重寫。
AOF重寫方式也是非同步操作,即如果要寫入aof文件,則Redis主進程會forks一個子進程來處理,如下所示:
在寫入aof日誌文件時,如果Redis伺服器宕機,則aof日誌文件文件會出格式錯誤,在重啟Redis伺服器時,Redis伺服器會拒絕載入這個aof文件,可以通過以下步驟修復aof並恢復數據。
AOF只是追加日誌文件,因此對伺服器性能影響較小,速度比RDB要快,消耗的內存較少。
我們可以從幾個方面對比一下RDB與AOF,在應用時,要根本自己的實際需求,選擇RDB或者AOF,其實,如果想要數據足夠安全,可以兩種方式都開啟,但兩種持久化方式同時進行IO操作,會嚴重影響伺服器性能,因此有時候不得不做出選擇。
當RDB與AOF兩種方式都開啟時,Redis會優先使用AOF日誌來恢復數據,因為AOF保存的文件比RDB文件更完整。
㈨ Redis主從結構,主庫宕機掛了,怎麼辦
連上從庫,做save操作。將會在從掘仿兆庫的data目錄保存一份判租從庫最新的mp.rdb文件。將這份大頌mp.rdb文件拷貝到主庫的data目錄下。再重啟主庫。
㈩ Redis主從結構,主庫宕機掛了,怎麼辦
因為主庫沒有配置持久化,所以主庫的data目錄只有從庫連接主庫請求resync的時候做快照留下來的mp.rdb文件。
如果重啟主庫,主庫會按粗備照data目錄下的mp.rdb來恢復數據。
因此,如果從庫是從最開始就配置好了的而且沒有發生過再次請求resync,那麼此時的mp.rdb將是稿野空的。主庫按照空的mp.rdb恢復數據,自然數據鍵凳喊全無,從庫發現主庫能夠連接上時會自動請求resync,從庫也將拷貝一份空白的數據。