redis持久化策略淺析

做爲目前做爲流行的cash,redis除了支持豐富的數據類型以外,還支持對內存中u數據的持久化,這樣一來即可以防止由於一些崩潰狀況(忽然間斷電、內存吃滿)形成的整個內存數據的丟失,這對咱們來講無疑是巨大的幫助。這裏咱們簡單的瞭解一下redis持久化的策略,下面是本身的一些總結,若有錯誤,請及時指正。php

redis實現數據持久化的兩種策略

一、rdb(redis database)-- 快照持久化

1.一、什麼是rdb?

rdb是redis的一種數據持久化策略,redis將某一時間點的數據所有打包生成一個.rdb的文件,保存在磁盤中,當咱們重啓redis服務的時候,將會讀取該rdb文件恢復數據庫中的數據。html

1.二、如何生成rdb快照

手動生成rdb快照:redis

  • redis客戶端發送bgsave命令來建立rdb快照sql

  • redis客戶端發送save命令來建立rdb快照數據庫

  • redis客戶端發送shutdown命令,redis服務端會在收到命令後先產生rdb快照,再關閉服務服務器

自動生成rdb快照:app

  • redis基於redis配置文件的 save規則進行自動生成快照,具體的配置項請參考1.3框架

1.三、關於rdb持久化相關的配置

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(append only file ) -- 只追加文件持久化

2.一、什麼是aof(append only file)?

aof一樣是redis的持久化策略,採用該策略的時候,redis會將被執行的寫命令添加到aof文件的末尾,該文件被保留在磁盤中。當重啓redis服務的時候會優先(相對於rdb文件而言)讀取aof文件,完成對redis數據的恢復。

2.二、關於aof持久化相關的配置

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.一、rdb策略持久化的例子

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

4.二、aof策略持久化的例子

更新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...

相關文章
相關標籤/搜索