redis過期策略、內存淘汰策略、持久化方式、主從複製

原文鏈接:https://blog.csdn.net/a745233700/article/details/85413179

一、Redis的過期策略以及內存淘汰策略:
1、過期策略:定期刪除+惰性刪除:

①定期刪除:redis默認每隔100ms就隨機抽取一些設置了過期時間的key,檢查其是否過期,如果有過期就刪除。注意這裏是隨機抽取的。爲什麼要隨機呢?你想一想假如 redis 存了幾十萬個 key ,每隔100ms就遍歷所有的設置過期時間的 key 的話,就會給 CPU 帶來很大的負載。

②惰性刪除:定期刪除可能導致很多過期的key 到了時間並沒有被刪除掉。這時就要使用到惰性刪除。在你獲取某個key的時候,redis會檢查一下,這個key如果設置了過期時間並且過期了,是的話就刪除。

2、定期刪除+惰性刪除存在的問題:
如果定期刪除沒刪除key,然後也沒即時去請求key,也就是說惰性刪除也沒生效。這時,如果大量過期的key堆積在內存中,redis的內存會越來越高,導致redis的內存塊耗盡。那麼就應該採用內存淘汰機制。

3、爲什麼不用定時刪除策略?
定時刪除,用一個定時器來負責監視key,過期則自動刪除。雖然內存及時釋放,但是十分消耗CPU資源。在大併發請求下,CPU要將時間應用在處理請求,而不是刪除key,因此沒有采用這一策略。

4、redis內存數據淘汰策略:

問題:MySQL裏有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據?redis內存數據集大小上升到一定大小的時候,就會施行數據淘汰策略。
①allkeys-lru:在所有的鍵空間中,移除最近最少使用的key。推薦使用,目前項目在用這種。

②volatile-lru:在設置了過期時間的鍵空間中,移除最近最少使用的key。這種情況一般是把redis既當緩存,又做持久化存儲的時候才用。不推薦

③allkeys-random:在鍵空間中,隨機移除某個key。應該也沒人用吧,你不刪最少使用Key,去隨機刪。

④volatile-random:在設置了過期時間的鍵空間中,隨機移除某個key。依然不推薦。

⑤volatile-ttl:在設置了過期時間的鍵空間中,移除即將過期的key進行淘汰。不推薦。

⑥noeviction:不進行移除,新寫入操作會報錯。應該沒人用吧。
ps:如果沒有設置 expire 的key, 不滿足先決條件(prerequisites); 那麼 volatile-lru, volatile-random 和 volatile-ttl 策略的行爲, 和 noeviction(不刪除) 基本上一致。

 

二、Reids的持久化方式:RDB和AOF
第一種持久化方式:RDB
1、什麼是RDB:

在指定的時間間隔內將內存中的數據集快照寫入磁盤(dump.rdb文件),即Snapshot快照,它恢復時是將快照文件從磁盤直接讀到內存裏。

2、默認持久化設置:

save 900 1              #在900秒(15分鐘)之後,如果至少有1個key發生變化,則dump內存快照。

save 300 10            #在300秒(5分鐘)之後,如果至少有10個key發生變化,則dump內存快照。

save 60 10000        #在60秒(1分鐘)之後,如果至少有10000個key發生變化,則dump內存快照。

是1分鐘內改了1萬次,或5分鐘內改了10次,或15分鐘內改了1次。

3、持久化原理:

        Redis會單獨創建(fork)一個子進程來進行持久化,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,再用這個臨時文件替換上次持久化好的文件。整個過程中,主進程是不進行任何IO操作的,這就確保了極高的性能。

        fork的作用是複製一個與當前進程一樣的進程。新進程的所有數據(變量、環境變量、程序計數器等)數值都和原進程一致,但是是一個全新的進程,並作爲原進程的子進程。

 4、優勢:

(1)如果需要進行大規模數據的恢復,且對於數據恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

(2)相比於AOF機制,如果數據集很大,RDB的啓動效率會更高。

5、劣勢:

(1)在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失最後一次快照後的所有修改。

(2)fork的時候,內存中的數據被克隆了一份,大致2倍的膨脹性需要考慮。

第二種持久化方式:AOF:
 1、什麼是AOF:

以日誌的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加文件但不可以改寫文件,redis啓動之初會讀取該文件重新構建數據,換言之,redis重啓的話就根據日誌文件的內容將寫指令從前到後執行一次以完成數據的恢復工作。(appendonly.aof文件)

2、AOF文件的rewrite機制:

(1)因爲AOF採用文件追加方式,文件會越來越大,爲避免出現此種情況,新增了重寫機制,當AOF文件的大小超過所設定的閾值時,Redis就會啓動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集,可以使用命令bg rewriteaof,異步執行一個 AOF(AppendOnly File) 文件重寫操作。

(2)重寫原理:AOF文件持續增長而過大時,會fork出一條新進程來將文件重寫(也是先寫臨時文件最後再rename),遍歷新進程的內存中數據,每條記錄有一條的Set語句。重寫aof文件的操作,並沒有讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點類似。

在執行 BGREWRITEAOF 命令時,Redis 服務器會維護一個 AOF 重寫緩衝區,該緩衝區會在子進程創建新AOF文件期
間,記錄服務器執行的所有寫命令。當子進程完成創建新AOF文件的工作之後,服務器會將重寫緩衝區中的所有內容追加到新AOF文件的末尾,使得新舊兩個AOF文件所保存的數據庫狀態一致。最後,服務器用新的AOF文件替換舊的AOF文件,以此來完成AOF文件重寫操作。

(3)觸發時機:Redis會記錄上次重寫時的AOF大小,默認配置是當AOF文件大小是上次rewrite後大小的一倍且文件大於64M時觸發。

3、AOF持久化配置:

(1)每修改同步:appendfsync always   同步持久化,每次發生數據變更會被立即記錄到磁盤,性能較差但數據完整性比較好。

(2)每秒同步:appendfsync everysec    異步操作,每秒記錄,如果一秒內宕機,有數據丟失。

(3)不同步:appendfsync no   從不同步

4、劣勢:

(1)相同數據集的數據而言aof文件要遠大於rdb文件,恢復速度慢於rdb。

(2)aof運行效率要慢於rdb,每秒同步策略效率較好,不同步效率和rdb相同。

注:如果同時開啓兩種持久化方式,在這種情況下,當redis重啓的時候會優先載入AOF文件來恢復原始的數據,因爲在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整。

Redis4.0對於持久化機制的優化:

Redis4.0開始支持RDB和AOF的混合持久化(默認關閉,可以通過配置項 aof-use-rdb-preamble 開啓)。

如果把混合持久化打開,AOF 重寫的時候就直接把 RDB 的內容寫到 AOF 文件開頭。這樣做的好處是可以結合 RDB和 AOF 的優點, 快速加載同時避免丟失過多的數據。當然缺點也是有的, AOF 裏面的 RDB 部分是壓縮格式不再是AOF 格式,可讀性較差。

 

三、Redis事務:
可以一次執行多個命令,本質是一組命令的集合。一個事務中的所有命令都會序列化,一次性地按順序地串行化執行,並且在事務執行期間,服務器不會中斷事務而改去執行其他客戶端的命令請求,即不會被其它命令插入,不許加塞,它會將事務中的所有命令都執行完畢,然後纔去處理其他客戶端的命令請求。即一個隊列中,一次性、順序性、排他性的執行一系列命令。

1、常用命令:

(1)開啓事務:MULTI。MULTI執行之後,客戶端可以繼續向服務器發送任意多條命令,這些命令不會立即被執行,而是被放到一個緩存隊列中,當EXEC命令被調用時,所有隊列中的命令纔會被執行。

(2)執行事務:EXEC。

(3)放棄事務:DISCARD。開啓事務之後,可以通過調用DISCARD,清空事務隊列,並放棄執行事務。

(4)監視key:WATCH。作爲WATCH命令的參數的鍵會受到Redis的監控,Redis能夠檢測到它們的變化。如果在事務執行之前這些key被其他命令所改動,那麼整個事務將會被打斷。WATCH命令可用於提供CAS(check-and-set)功能。

(5)取消監視:UNWATCH。

2、Redis事務的特性:

(1)非原子性,不支持回滾:執行EXEC命令的時候,Redis同一個事務中如果有一條命令執行失敗,其後的命令仍然會被執行,沒有回滾。在 EXEC 命令只保證批量操作的一次性批量執行過程。

Redis 操作失敗的原因只可能是語法錯誤或者錯誤的數據庫類型操作,這些都是在開發層面能發現的問題不會進入到生產環境,因此不需要回滾。

Redis 內部設計推崇簡單和高性能,因此不需要回滾能力。

並且,Redis 的應用場景明顯不是爲了數據存儲的高可靠而設計的,而是爲了數據訪問的高性能而設計,設計者爲了簡單性和高性能而部分放棄了原子性。

②一致性:

③單獨的隔離操作,事務中的所有命令都會被序列化,按順序地執行。事務在執行的過程中,其他客戶端發送來的命令請求不會插入到事務執行命令序列中。沒有隔離級別的概念,事務隊列中的命令沒有提交之前都不會實際的被執行。

④持久性:如果Redis運行在某種特定的持久化模式下時,事務也具有持久性。當使用Append-Only模式時,Redis會通過調用系統函數write將該事務內的所有寫操作在本次調用中全部寫入磁盤。然而如果在寫入的過程中出現系統崩潰,如電源故障導致的宕機,那麼此時也許只有部分數據被寫入到磁盤,而另外一部分數據卻已經丟失。

 

四、Redis主從複製:
        Redis支持主從複製的模式。原則:主機數據更新後根據配置和策略,自動同步到備機的master/slaver機制,slave不會將數據同步到master,Master以寫爲主,Slave以讀爲主。這樣可以有效減少單個機器的併發訪問數量。

1、配置要點:

(1)配從庫不配主。

(2)從庫配置:slaveof 主庫IP 主庫端口:

(3)slave每次與master斷開之後,都需要重新連接,除非你配置進redis.conf文件。

(4)查看redis的配置信息:info replication

2、主從複製原理:

(1)slave啓動成功連接到master後會發送一個sync命令;

(2)Master接到slave的sync命令後,啓動後臺的存盤進程,同時收集所有接收到的用於修改數據集命令,在後臺進程執行完畢之後,master將傳送整個數據文件到slave,以完成一次完全同步。

(3)全量複製:slave服務在接收到主機數據庫文件數據後,將其存盤並加載到內存中。

(4)增量複製:Master繼續將新的所有收集到的修改命令依次傳給slave,完成同步。

(5)但是只要是重新連接master,一次完全同步(全量複製)將被自動執行。

 3、常用三招:

a、一主二從:一個Master兩個Slave

(1)切入點問題?slave1、slave2是從頭開始複製還是從切入點開始複製?比如從k4進來,那之前的123是否也可以複製。答:從頭開始複製。

(2)從機是否可以寫?是否可以使用set命令?答:不可以。

(3)主機shutdown後情況如何?從機是上位還是原地待命?答:如果沒有配置哨兵模式,則是原地待命。

(4)主機又回來了後,主機新增記錄,從機還能否順利複製?答:能。

(5)其中一臺從機down後情況如何?依照原有它能跟上大部隊嗎?答:需要重新連接。

b、薪火相傳:

上一個Slave可以是下一個slave的Master,Slave同樣可以接收其他slaves的連接和同步請求,那麼該slave作爲了鏈條中下一個的master,可以有效減輕master的寫壓力。但是,如果中途變更轉向,則會清除之前的數據,重新建立拷貝最新的主機數據。

c、反客爲主:SLAVEOF no one。原本的Master掛掉之後,執行此命令,會重新選擇一臺Master。

4、哨兵模式(sentinel):

反客爲主的自動版,能夠後臺監控主機是否故障,如果故障了根據投票數自動將從庫轉換爲主庫。 

如果之前的master重啓回來,不會造成雙master衝突,因爲原本的master會變成slave。

配置步驟:

(1)在自定義的/myredis目錄下新建sentinel.conf文件,名字絕不能錯。

(2)配置哨兵,在配置文件中寫: sentinel monitor 被監控數據庫名字(自己起名字) 127.0.0.1 6379 1

上面最後一個數字1,表示主機掛掉後salve投票看讓誰接替成爲主機,得票數多少後成爲主機。

(3)啓動哨兵:redis-sentinel /myredis/sentinel.conf

5、主從複製的缺點:由於所有的寫操作都是先在Master上操作,然後同步更新到Slave上,所以從Master同步到Slave機器有一定的延遲,當系統很繁忙的時候,延遲問題會更加嚴重,Slave機器數量的增加也會使這個問題更加嚴重。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章