做爲目前做爲流行的cash,redis除了支持豐富的數據類型以外,還支持對內存中u數據的持久化,這樣一來即可以防止由於一些崩潰狀況(忽然間斷電、內存吃滿)形成的整個內存數據的丟失,這對咱們來講無疑是巨大的幫助。這裏咱們簡單的瞭解一下redis持久化的策略,下面是本身的一些總結,若有錯誤,請及時指正。php
rdb是redis的一種數據持久化策略,redis將某一時間點的數據所有打包生成一個.rdb的文件,保存在磁盤中,當咱們重啓redis服務的時候,將會讀取該rdb文件恢復數據庫中的數據。html
手動生成rdb快照:redis
redis客戶端發送bgsave命令來建立rdb快照sql
redis客戶端發送save命令來建立rdb快照數據庫
redis客戶端發送shutdown命令,redis服務端會在收到命令後先產生rdb快照,再關閉服務服務器
自動生成rdb快照:app
redis基於redis配置文件的 save規則進行自動生成快照,具體的配置項請參考1.3框架
a、save選項的設置,最重要的一個配置,它直接決定了是否生成快照。redis支持設置多條save規則,當其中的一條規則知足後就會自動的執行bgsave命令(換句話說下面的這些規則是 或 的關係),下面是redis安裝時的默認save規則yii
設置的規則 | 規則解釋 |
---|---|
save 900 1 | 距離上一次執行rdb快照時間超過900秒,而且至少有1個鍵發生了改變,便會觸發備份操做 |
save 300 10 | 距離上一次執行rdb快照時間超過300秒,而且至少有10個鍵發生了改變,便會觸發備份操做 |
save 60 1000 | 距離上一次執行rdb快照時間超過60秒,而且至少有1000個鍵發生了改變,便會觸發備份操做 |
b、rdbcompression選項的設置,該規則決定是否對生成的rdb文件進行壓縮nosql
規則的選項 | 規則解釋 |
---|---|
rdbcompression yes(默認是開啓的) | 對生成的rdb快照文件進行壓縮 |
rdbcompression no | 不對生成的rdb快照文件進行壓縮 |
c、dbfilename選項的設置,該規則決定了生成的.rdb文件的名字,默認狀況下的配置爲dbfilename dump.rdb
d、 stop-writes-on-bgsave-error規則的設置,該規則決定了當bgsave備份命令執行失敗的時候,redis是中止接受客戶端發送過來的寫命令
規則的選項 | 規則解釋 |
---|---|
stop-writes-on-bgsave-error yes(默認是開啓的) | 當最近的一次rdb快照生成失敗,redis將再也不接受相關的寫命令,以此來提醒用戶備份的失敗 |
stop-writes-on-bgsave-error no | 最近一次的rdb快照生成失敗,仍然接受redis客戶端發送過來的寫命令,不過須要要靠譜的監控系統提醒咱們rdb快照失敗了,不然不會有人知道的 |
e、rdbchecksum 是否校驗rdb文件,這個配置項在實際的做用沒怎麼弄清楚,有了解的同窗能夠解釋下
規則的選項 | 規則解釋 |
---|---|
rdbchecksum yes(默認是開啓的) | 從版本RDB版本5開始,一個CRC64的校驗就被放在了文件末尾。這會讓格式更加耐攻擊,可是當存儲或者加載rbd文件的時候會有一個10%左右的性能降低,因此,爲了達到性能的最大化,你能夠關掉這個配置項 |
rdbchecksum no | 沒有校驗的RDB文件會有一個0校驗位,來告訴加載代碼跳過校驗檢查 |
f、dbfilename選項的設置,該規則決定了生成的.rdb文件的名字,默認狀況下的配置爲dbfilename dump.rdb
g、dir rdb文件要保存的位置
aof一樣是redis的持久化策略,採用該策略的時候,redis會將被執行的寫命令添加到aof文件的末尾,該文件被保留在磁盤中。當重啓redis服務的時候會優先(相對於rdb文件而言)讀取aof文件,完成對redis數據的恢復。
a、appendonly,該選項決定了是否開啓aof持久化策略
配置名稱 | 配置選項 | 解釋說明 |
---|---|---|
appendonly | yes / no | 決定是否開啓aof策略,默認狀況下是no |
b、appendfsync, 該選項決定了寫入aof文件的頻率
配置名稱 | 配置選項 | 解釋說明 |
---|---|---|
appendfsync | always | 每個redis寫命令都會被寫入到aof文件中,這樣會嚴重下降redis的速度 |
appendfsync | everysec | 每秒鐘執行一次同步,將這一秒鐘以內接受到的命令寫入aof文件中 |
appendfsync | no | 並非不進行aof持久化,而是讓操做系統決定何時將命令寫入aof文件中,這樣咱們丟失的數據將不可控 |
c、no-appendfsync-on-rewrite, 當服務器出現短暫性的阻塞的時候,一般狀況下,若是咱們執行bgsave或者bgrewriteof命令時,可能會形成服務的短暫掛起,此時該選項決定是否還將命令同步到aof文件
配置名稱 | 配置選項 | 解釋說明 |
---|---|---|
no-appendfsync-on-rewrite | yes | 當服務器出現短暫性阻塞的時候,不將命令同步到aof文件中,暫時放入內存,知道阻塞結束後再同步 |
no-appendfsync-on-rewrite | no | 當服務器出現阻塞時仍然嘗試將命令追加到aof文件 |
d、auto-aof-rewrite-percentage和auto-aof-rewite-min-size。因爲,咱們不斷將redis執行的寫命令追加到aof文件中,會致使aof文件愈來愈大,redis就想出來一個辦法,在保證redis存儲數據正確的前提下,要儘量的減小aof文件存儲的命令,從而達到幫aof文件 " 瘦身 "的目的。redis的想到的辦法就是執行bgrewriteaof命令,對aof文件進行重寫,而這兩個選項則決定了在什麼狀況下出發該命令。這裏須要提到的一點是,這兩個選項一般是一塊兒使用,共同來決定是否執行bgrewriteaof命令。
配置名稱 | 配置選項 | 解釋說明 |
---|---|---|
auto-aof-rewrite-percentage | 100(任意數字均可以) | 若是爲100的話,就表示當aof文件相對於上次的aof文件大小要增長一倍,也就是now_file_size >= last_file_size * (1 + auto-aof-rewrite-percentage / 100 ),此時便會試着出發bgrewrite,固然還要看另一個條件 |
auto-aof-rewrite-min-size | 64mb(一個指定大小) | 若是爲64mb的話,就表示當aof文件 >= 64mb 的時候,嘗試進行bgrewrite重寫 ,固然還要看另一個條件 |
e、appendfilename,選項決定了產生的aof文件的名稱,舉個例子 : appendfilename "appendonly.aof"
f、dir aof文件要保存的位置,該選項同時決定了aof和rdb兩個文件的保存位置
爲了方便測試工做,基於yii框架,寫了一個測試腳本,腳本的內容以下:
<?php namespace app\commands; use yii\console\Controller; class HelloController extends Controller { public static $START_TIME = null; public $number = 0; public function init() { parent::init(); static::$START_TIME = time(); } /** * redis database test */ public function actionRedis() { $redis = \Yii::$app->redis; while(true) { $left_time = time() - static::$START_TIME; if($left_time > 10 && $this->number > 15) { echo "\r\n","total use {$left_time} seconds, and {$this->number} keys had been set","\r\n"; break; } else { $key_name = "test:${left_time}:" . mt_rand(0, 9999); $redis->set($key_name, $key_name); echo $key_name,"\r\n"; } $this->number++; sleep(1); } } }
4.1.一、更改redis配置以下
save 15 10
rdbcompression no
4.1.二、執行測試腳本
4.1.三、查看redis內存中的數據
4.1.四、查看dump.rdb文件
通過大約15秒左右的時間,咱們發如今在指定的data目錄下產生了一個dump.rdb文件
4.1.五、強殺redis服務,模擬宕機狀況
4.1.六、重啓redis服務,查看redis內存中的數據
通過對比發現,丟失了一些key
更新redis的配置以下
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
測試的流程大體相同,這裏再也不詳細介紹,相同的測試腳本再次執行,發現key並無任何丟失,這是因爲redis每秒鐘同步一次的緣故,在這種配置下,若是寫入很頻繁,也就是丟失1秒鐘的數據
《redis實戰》
《redis入門指南》
http://redisdoc.com/topic/per...
https://my.oschina.net/wfire/...
http://blog.nosqlfan.com/html...