redis學習

redis學習

對於redis的5中數據類型以及使用方法這兒先暫時不詳細說明,大家可以到菜鳥教程自行查找。本文著重學習redis的持久化方式淘汰策略

 

一、Redis的持久化

  redis持久化的兩種方式:

  (1) RDB(Redis DataBase):把數據以快照的形式保存在磁碟上。進一步來說是指在一定的時間間隔,把數據集快照寫入磁碟中。這也是默認的持久化方式,這種方式就是把記憶體中的數據以快照的方式寫入到二進位文件中,默認文件名為「dump.rdb

  reids是如何來觸發這個RDB 機制的呢?對於RDB來說,redis通過三種機制來觸發RDB,分別是:save、bgsave、自動化 三種方式,同時我們也可手動通過 shutdown 命令來觸發。那麼分別看一下:

    • save觸發模式

      save命令會阻塞當前redis伺服器,在save命令執行期間,Redis伺服器不能執行其他命令,直到RDB過程執行完成為止。具體流程如下:

      

      因為save在執行期間會造成堵塞,當我們的客戶端有幾萬或者幾十萬甚至更多的時候,讓這麼多客戶端一直在等待,顯然是不妥的,所以這種方式是不可取的。

 

    • bgsave觸發模式  

      Redis在執行該命令時會在後台非同步執行快照操作,快照的同時也可以響應客戶端的請求,具體流程如下:

      

      

       Redis  fork一個子進程,子進程負責快照操作(先將數據寫到一個臨時的文件中,然後用臨時文件替換原來的dump.rdb文件),操作完成後會自動結束。整個過程堵塞只會發生在fork階段,一般時間很短,基本上redis內部所有的RDB操作都是通過bgsave來完成的。

 

    • 自動觸發

      自動觸發是由配置文件來完成的,在redis.conf配置文件中,裡面有如下配置,我們可以去設置:

      ①save:這裡是用來配置觸發 Redis的 RDB 持久化條件,也就是什麼時候將記憶體中的數據保存到硬碟。比如「save m n」。表示m秒內數據集存在n次修改時,自動觸發bgsave。默認配置如下:

#表示900 秒內如果至少有 1 個 key 的值變化,則保存

save 900 1

#表示300 秒內如果至少有 10 個 key 的值變化,則保存

save 300 10

#表示60 秒內如果至少有 10000 個 key 的值變化,則保存

save 60 10000

不需要持久化,那麼你可以注釋掉所有的 save 行來停用保存功能。

②stop-writes-on-bgsave-error :默認值為yes。當啟用了RDB且最後一次後台保存數據失敗,Redis是否停止接收數據。這會讓用戶意識到數據沒有正確持久化到磁碟上,否則沒有人會注意到災難(disaster)發生了。如果Redis重啟了,那麼又可以重新開始接收數據了

③rdbcompression ;默認值是yes。對於存儲到磁碟中的快照,可以設置是否進行壓縮存儲。

④rdbchecksum :默認值是yes。在存儲快照後,我們還可以讓redis使用CRC64演算法來進行數據校驗,但是這樣做會增加大約10%的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能。

⑤dbfilename :設置快照的文件名,默認是 dump.rdb

⑥dir:設置快照文件的存放路徑,這個配置項一定是個目錄,而不能是文件名。

我們可以修改這些配置來實現我們想要的效果。

 

RDB的優勢與劣勢:

        優勢:

           1> RDB文件緊湊,全量備份,非常適合用來做數據備份和災難恢復

           2> 生成RDB文件的時候,RDB會fork一個子進程來處理所有的保存工作,主進程不需要進行任何的磁碟I/O操作

           3> RDB恢復大數據集的時候要比AOF的回復速度要快

        劣勢:

            RDB快照是一次全量備份,存儲的是記憶體數據的二進位序列化形式,存儲上非常緊湊。當進行快照持久化時,會開啟一個子進程專門負責快照持久化,子進程會擁有父進程的記憶體數據,父進程修改記憶體子進程不會反應出來,所以在快照持久化期間修改的數據不會被保存,可能丟失數據。

        

 

 

  (2) AOF(Append Only File)

  全量備份總是耗時的,有時候我們提供一種更加高效的方式AOF,工作機制很簡單,redis會將每一個收到的寫命令都通過write函數追加到文件中。通俗的理解就是日誌記錄。

  持久化原理:

    

  每當有一個寫命令過來時就會寫進我們的aof文件。

  文件重寫原理

  AOF的方式也同時帶來了另一個問題。持久化文件會變的越來越大。為了壓縮aof的持久化文件。redis提供了bgrewriteaof命令。將記憶體中的數據以命令的方式保存到臨時文件中,同時會fork出一條新進程來將文件重寫。

  文件重寫個人理解:比如 redis 有這樣一個命令:incr  num 0;如果這個num表示閱讀次數,例如作者的這篇文章很火爆(玩笑玩笑,別當真),一天內有100人閱讀了,那麼我們的appendonly.aof文件中就會有100條這樣的重複命令,這樣造成文件大小浪費,重寫可能就是會優化我們的命令成:set num 100;這樣一條命令直接就代替了我們原來的100條命令了;再例如:set num 99,然後存進了appendoy.aof,然後緊接著有執行力:del num;又寫進了appendonly.aof文件,如果不進行文件重寫,這兩條語句佔用磁碟空間,但卻沒有實際意義,進行bgrewriteaof後,可能就刪除了這兩個語句,達到文件瘦身吧!!!

  觸發bgrewriteaof的條件是什麼呢?

auto_aofrewrite_perc: aof文件的大小超過基準百分之多少後觸發bgrewriteaof。默認這個值設置為100,意味著當前aof是基準大小的兩倍的時候觸發bgrewriteaof。把它設置為0可以禁用自動觸發的功能。
auto_aofrewrite_min_size: 當前aof文件大於多少位元組後才觸發。避免在aof較小的時候無謂行為。默認大小為64mb
兩個參數都是可以在conf里靜態配置,或者通過config set來動態修改的。

  

redis 127.0.0.1:6379> config get auto-aof-rewrite-percentage
1) "auto-aof-rewrite-percentage"
2) "100"
redis 127.0.0.1:6379> config get auto-aof-rewrite-min-size
1) "auto-aof-rewrite-min-size"
2) "1048576"
redis 127.0.0.1:6379> config get auto-aof-rewrite-min-size
1) "auto-aof-rewrite-min-size"
2) "1048576"
redis 127.0.0.1:6379> config set auto-aof-rewrite-percentage 200
OK
redis 127.0.0.1:6379> config set auto-aof-rewrite-min-size 10485760
OK

 

AOF也有三種觸發機制

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

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

(3)不同no:從不同步

 

AOF優點:

(1)AOF可以更好的保護數據不丟失,一般AOF會每隔1秒,通過一個後台執行緒執行一次fsync操作,最多丟失1秒鐘的數據。(2)AOF日誌文件沒有任何磁碟定址的開銷,寫入性能非常高,文件不容易破損。

(3)AOF日誌文件即使過大的時候,出現後台重寫操作,也不會影響客戶端的讀寫。

(4)AOF日誌文件的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用flushall命令清空了所有數據,只要這個時候後台rewrite還沒有發生,那麼就可以立即拷貝AOF文件,將最後一條flushall命令給刪了,然後再將該AOF文件放回去,就可以通過恢復機制,自動恢復所有數據

AOF缺點:

(1)對於同一份數據來說,AOF日誌文件通常比RDB數據快照文件更大

(2)AOF開啟後,支援的寫QPS會比RDB支援的寫QPS低,因為AOF一般會配置成每秒fsync一次日誌文件,當然,每秒一次fsync,性能也還是很高的

(3)以前AOF發生過bug,就是通過AOF記錄的日誌,進行數據恢復的時候,沒有恢復一模一樣的數據出來。

Tags: