1. 程式人生 > >Redis的刪除機制、持久化 主從

Redis的刪除機制、持久化 主從

Redis的使用分兩點:

效能
如下圖所示,我們在碰到需要執行耗時特別久,且結果不頻繁變動的SQL,就特別適合將執行結果放入快取。這樣,後面的請求就去快取中讀取,使得請求能夠迅速響應

 

併發
在大併發的情況下,所有的請求直接訪問資料庫,資料庫會出現連線異常。這個時候,就需要使用redis做一個緩衝操作,讓請求先訪問到redis,而不是直接訪問資料庫

 

使用redis有什麼缺點

分析:大家用redis這麼久,這個問題是必須要了解的,基本上使用redis都會碰到一些問題,常見的也就幾個。
回答:主要是四個問題
(一)快取和資料庫雙寫一致性問題
(二)快取雪崩問題
(三)快取擊穿問題
(四)快取的併發競爭問題

 

 

 

redis的過期策略以及記憶體淘汰機制

分析:這個問題其實相當重要,到底redis有沒有用到家,這個問題就可以看出來。比如你的redis只能儲存5G資料,課時你寫了10G,那會刪除5G的資料。怎麼刪的,則會個問題思考過嗎?還有,你的資料已經設定了過期時間了,記憶體佔有率還是比較高,有思考過嗎?且看我來講解:

redis是採用定期刪除+惰性刪除策略

 

為什麼不用定時刪除策略?:

定時刪除,用一個定時器來負責監視key,當這個key過期就自動刪除,雖然記憶體及時釋放,但是十分消耗CPU資源,在大併發請求下CPU要儘可能的把時間都用在處理請求,而不是刪除key,因此沒有采用這一策略

 

定期刪除+惰性刪除是如何工作的呢?

定時刪除,redis預設每100ms檢查是否有過期的key,有過期的key則刪除。需要說明的是redis不是每個100ms將所有的key檢查一次,而是隨機抽取進行檢查(如果每100ms,全部key進行檢查,redis豈不是卡死了)。因此,如果只採用定期策略,會導致很多key到時間沒有刪除

也就是使用定時刪除會導致刪除不完全,於是惰性刪除就登場了。

也就是說你在獲取key的時候,redis會檢查一下,這個key如果設定過期時間那麼是否過期了?如果過期 此時就刪除。

採用定期刪除+惰性刪除就沒問題了呢?

不是的如果定期刪除沒有刪除key,然後你也沒有及時去請求這個key,也就是說惰性刪除也沒有生效。這樣redis的記憶體會越來越高,那麼就應該採用記憶體淘汰機制。

在redis.conf中有一行配置

# maxmemory-policy volatile-lru

該配置就是配記憶體淘汰策略的(什麼,你沒配過?好好反省一下自己)
1)noeviction:當記憶體不足以容納新寫入資料時,新寫入操作會報錯。應該沒人用吧。
2)allkeys-lru:當記憶體不足以容納新寫入資料時,在鍵空間中,移除最近最少使用的key。推薦使用,目前專案在用這種。
3)allkeys-random:當記憶體不足以容納新寫入資料時,在鍵空間中,隨機移除某個key。應該也沒人用吧,你不刪最少使用Key,去隨機刪。
4)volatile-lru:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,移除最近最少使用的key。這種情況一般是把redis既當快取,又做持久化儲存的時候才用。不推薦
5)volatile-random:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,隨機移除某個key。依然不推薦
6)volatile-ttl:當記憶體不足以容納新寫入資料時,在設定了過期時間的鍵空間中,有更早過期時間的key優先移除。不推薦
ps:如果沒有設定 expire 的key, 不滿足先決條件(prerequisites); 那麼 volatile-lru, volatile-random 和 volatile-ttl 策略的行為, 和 noeviction(不刪除) 基本上一致。

 

 

 

Redis持久化原理及配置詳解

Redis的強大功能很大程度上是由於其將所有資料都儲存在記憶體中。為了使Redis在重啟後仍能保證資料不丟失,需要將資料從記憶體中以某種形式持久化到硬碟中。Redis支援兩種持久化方式,一種是RDB方式,一種是AOF方式。可以單獨使用其中一種或兩種結合使用。(持久化即將資料儲存到磁碟,機器宕機或者重啟資料不丟失,儲存到記憶體中的資料會丟失)


Redis有兩種持久化的方式:快照(RDB檔案)和追加式檔案(AOF檔案):

  • RDB持久化方式會在一個特定的間隔儲存那個時間點的一個數據快照。
  • AOF持久化方式則會記錄每一個伺服器收到的寫操作。在服務啟動時,這些記錄的操作會逐條執行從而重建出原來的資料。寫操作命令記錄的格式跟Redis協議一致,以追加的方式進行儲存。
  • Redis的持久化是可以禁用的,就是說你可以讓資料的生命週期只存在於伺服器的執行時間裡。
  • 兩種方式的持久化是可以同時存在的,但是當Redis重啟時,AOF檔案會被優先用於重建資料。

RDB概述:

RDB是在某個時間點將資料寫入一個臨時檔案,持久化結束後,用這個臨時檔案替換上次持久化的檔案,達到資料恢復。
優點:使用單獨子程序來進行持久化,主程序不會進行任何IO操作,保證了redis的高效能
缺點:RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生資料丟失。所以這種方式更適合資料要求不嚴謹的時候
RDB是Redis預設的持久化方式,所以RDB是預設開啟的

redis.conf中的具體配置引數如下;

#dbfilename:持久化資料儲存在本地的檔案
dbfilename dump.rdb
#dir:持久化資料儲存在本地的路徑,如果是在/redis/redis-3.0.6/src下啟動的redis-cli,則資料會儲存在當前src目錄下
dir ./
##snapshot觸發的時機,save <seconds> <changes>  
##如下為900秒後,至少有一個變更操作,才會snapshot  
##對於此值的設定,需要謹慎,評估系統的變更操作密集程度  
##可以通過“save “””來關閉snapshot功能  
#save時間,以下分別表示更改了1個key時間隔900s進行持久化儲存;更改了10個key300s進行儲存;更改10000個key60s進行儲存。
save 900 1
save 300 10
save 60 10000
##當snapshot時出現錯誤無法繼續時,是否阻塞客戶端“變更操作”,“錯誤”可能因為磁碟已滿/磁碟故障/OS級別異常等  
stop-writes-on-bgsave-error yes  
##是否啟用rdb檔案壓縮,預設為“yes”,壓縮往往意味著“額外的cpu消耗”,同時也意味這較小的檔案尺寸以及較短的網路傳輸時間  
rdbcompression yes  

 

人們常說的redis的預設持久化就是因為它預設支援RDB模式,又因為RDB支援持久化所以就說redis預設持久化,但是我們寫的內容又無法滿足這個持久化的條件所以就沒有把資料儲存起來

禁用redis快照:

 

如果想禁用快照儲存的功能,可以通過註釋掉所有"save"配置達到,或者在最後一條"save"配置後新增如下的配置:

save ""

 

 

快照並不是很可靠。如果你的電腦突然宕機了,或者電源斷了,又或者不小心殺掉了程序,那麼最新的資料就會丟失。而AOF檔案則提供了一種更為可靠的持久化方式。每當Redis接受到會修改資料集的命令時,就會把命令追加到AOF檔案裡,當你重啟Redis時,AOF裡的命令會被重新執行一次,重建資料。

AOF概述

Redis的AOF持久化策略是將傳送到Redis服務端的每一條命令都記錄下來,並且儲存在硬碟的AOF檔案中。可以通過引數appendonly來設定是否啟用AOF。AOF檔案的位置和RDB的位置相同,都是通過dir引數設定,預設的檔名是appendonly.aof,可以通過appendfilename引數修改。

將“操作 + 資料”以格式化指令的方式追加到操作日誌檔案的尾部,在append操作返回後(已經寫入到檔案或者即將寫入),才進行實際的資料變更當server需要資料恢復時,可以直接replay此日誌檔案,即可還原所有的操作過程。AOF相對可靠

 

優點:

  • 比RDB可靠。你可以制定不同的fsync策略:不進行fsync、每秒fsync一次和每次查詢進行fsync。預設是每秒fsync一次。這意味著你最多丟失一秒鐘的資料。
  • AOF日誌檔案是一個純追加的檔案。就算是遇到突然停電的情況,也不會出現日誌的定位或者損壞問題。甚至如果因為某些原因(例如磁碟滿了)命令只寫了一半到日誌檔案裡,我們也可以用redis-check-aof這個工具很簡單的進行修復。
  • 當AOF檔案太大時,Redis會自動在後臺進行重寫。重寫很安全,因為重寫是在一個新的檔案上進行,同時Redis會繼續往舊的檔案追加資料。新檔案上會寫入能重建當前資料集的最小操作命令的集合。當新檔案重寫完,Redis會把新舊檔案進行切換,然後開始把資料寫到新檔案上。
  • AOF把操作命令以簡單易懂的格式一條接一條的儲存在檔案裡,很容易匯出來用於恢復資料。例如我們不小心用FLUSHALL命令把所有資料刷掉了,只要檔案沒有被重寫,我們可以把服務停掉,把最後那條命令刪掉,然後重啟服務,這樣就能把被刷掉的資料恢復回來。

缺點:

  • 在相同的資料集下,AOF檔案的大小一般會比RDB檔案大。
  • 在某些fsync策略下,AOF的速度會比RDB慢。通常fsync設定為每秒一次就能獲得比較高的效能,而在禁止fsync的情況下速度可以達到RDB的水平。

 

AOF預設關閉,開啟方法,修改配置檔案reds.conf:appendonly yes

##此選項為aof功能的開關,預設為“no”,可以通過“yes”來開啟aof功能  
##只有在“yes”下,aof重寫/檔案同步等特性才會生效  
appendonly yes  

##指定aof檔名稱  
appendfilename appendonly.aof  

##指定aof操作中檔案同步策略,有三個合法值:always everysec no,預設為everysec  
appendfsync everysec  
##在aof-rewrite期間,appendfsync是否暫緩檔案同步,"no"表示“不暫緩”,“yes”表示“暫緩”,預設為“no”  
no-appendfsync-on-rewrite no  

##aof檔案rewrite觸發的最小檔案尺寸(mb,gb),只有大於此aof檔案大於此尺寸是才會觸發rewrite,預設“64mb”,建議“512mb”  
auto-aof-rewrite-min-size 64mb  

##相對於“上一次”rewrite,本次rewrite觸發時aof檔案應該增長的百分比。  
##每一次rewrite之後,redis都會記錄下此時“新aof”檔案的大小(例如A),那麼當aof檔案增長到A*(1 + p)之後  
##觸發下一次rewrite,每一次aof記錄的新增,都會檢測當前aof檔案的尺寸。  
auto-aof-rewrite-percentage 100  

AOF是檔案操作,對於變更操作比較密集的server,那麼必將造成磁碟IO的負荷加重;此外linux對檔案操作採取了“延遲寫入”手段,即並非每次write操作都會觸發實際磁碟操作,而是進入了buffer中,當buffer資料達到閥值時觸發實際寫入(也有其他時機),這是linux對檔案系統的優化,但是這卻有可能帶來隱患,如果buffer沒有重新整理到磁碟,此時物理機器失效(比如斷電),那麼有可能導致最後一條或者多條aof記錄的丟失。通過上述配置檔案,可以得知redis提供了3中aof記錄同步選項:

always:每一條aof記錄都立即同步到檔案,這是最安全的方式,也以為更多的磁碟操作和阻塞延遲,是IO開支較大。
everysec:每秒同步一次,效能和安全都比較中庸的方式,也是redis推薦的方式。如果遇到物理伺服器故障,有可能導致最近一秒內aof記錄丟失(可能為部分丟失)。
no:redis並不直接呼叫檔案同步,而是交給作業系統來處理,作業系統可以根據buffer填充情況/通道空閒時間等擇機觸發同步;這是一種普通的檔案操作方式。效能較好,在物理伺服器故障時,資料丟失量會因OS配置有關。

其實,我們可以選擇的太少,everysec是最佳的選擇。如果你非常在意每個資料都極其可靠,建議你選擇一款“關係性資料庫”吧。 

 

 

主從:

通過持久化功能,Redis保證了即使在伺服器重啟的情況下也不會損失(或少量損失)資料,因為持久化會把記憶體中資料儲存到硬碟上,重啟會從硬碟上載入資料。 
。但是由於資料是儲存在一臺伺服器上的,如果這臺伺服器出現硬碟故障等問題,也會導致資料丟失。為了避免單點故障,通常的做法是將資料庫複製多個副本以部署在不同的伺服器上,這樣即使有一臺伺服器出現故障,其他伺服器依然可以繼續提供服務。為此, Redis 提供了複製(replication)功能,可以實現當一臺資料庫中的資料更新後,自動將更新的資料同步到其他資料庫上。

概述
1、redis的複製功能是支援多個數據庫之間的資料同步。一類是主資料庫(master)一類是從資料庫(slave),主資料庫可以進行讀寫操作,當發生寫操作的時候自動將資料同步到從資料庫,而從資料庫一般是隻讀的,並接收主資料庫同步過來的資料,一個主資料庫可以有多個從資料庫,而一個從資料庫只能有一個主資料庫。

2、通過redis的複製功能可以很好的實現資料庫的讀寫分離,提高伺服器的負載能力。主資料庫主要進行寫操作,而從資料庫負責讀操作

主從複製過程:

 

 

過程:

1:當一個從資料庫啟動時,會向主資料庫傳送sync命令,

2:主資料庫接收到sync命令後會開始在後臺儲存快照(執行rdb操作),並將儲存期間接收到的命令快取起來

3:當快照完成後,redis會將快照檔案和所有快取的命令傳送給從資料庫。

4:從資料庫收到後,會載入快照檔案並執行收到的快取的命令。

主從複製是樂觀複製,當客戶端傳送寫執行給主,主執行完立即將結果返回客戶端,並非同步的把命令傳送給從,從而不影響效能。也可以設定至少同步給多少個從主才可寫。 
無硬碟複製:如果硬碟效率低將會影響複製效能,2.8之後可以設定無硬碟複製,repl-diskless-sync yes

 

哨兵:

當主資料庫遇到異常中斷服務後,開發者可以通過手動的方式選擇一個從資料庫來升格為主資料庫,以使得系統能夠繼續提供服務。
然而整個過程相對麻煩且需要人工介入,難以實現自動化。 為此,Redis 2.6中提供了哨兵2.8才穩定,哨兵工具來實現自動化的系統監控和故障恢復功能。 哨兵的作用就是監控redis主、從資料庫是否正常執行,主出現故障自動將從資料庫轉換為主資料庫。

顧名思義,哨兵的作用就是監控Redis系統的執行狀況。它的功能包括以下兩個。

 
 

    (1)監控主資料庫和從資料庫是否正常執行。 
    (2)主資料庫出現故障時自動將從資料庫轉換為主資料庫。

 

 

哨兵就是為了監測你的主資料庫是否出問題,如果主資料庫出問題就會把從資料庫升為主資料庫,也可以設定多個哨兵來監測主從,然後多個哨兵監測的時候就會運用投票來監測主從,

如果是主資料庫掛掉 ,就需要你的這些多個哨兵來投票 當多票當選的時候就會讓從資料庫變成主,當有哨兵機制的時候是進行連線哨兵 ,哨兵再連線資料庫