redis持久化


概述

Redis的強大性能很大程度上都是因為所有數據都是存儲在內存中的,

然而當Redis重啟后,所有存儲在內存中的數據將會丟失,在很多情況

下是無法容忍這樣的事情的。所以,我們需要將內存中的數據持久化!

典型的需要持久化數據的場景如下:

將Redis作為數據庫使用;

將Redis作為緩存服務器使用,但是緩存miss后會對性能造成

很大影響,所有緩存同時失效時會造成服務雪崩,無法響應。

本文介紹Redis所支持的兩種數據持久化方式。

Redis數據持久化

Redis支持兩種數據持久化方式:RDB方式和AOF方式。前者會根據配置

的規則定時將內存中的數據持久化到硬盤上,后者則是在每次執行寫命

令之后將命令記錄下來。兩種持久化方式可以單獨使用,但是通常會將

兩者結合使用。

RDB方式

RDB方式的持久化是通過快照的方式完成的。當符合某種規則時,會將

內存中的數據全量生成一份副本存儲到硬盤上,這個過程稱作”快

照”,Redis會在以下幾種情況下對數據進行快照:

根據配置規則進行自動快照;

用戶執行SAVE, BGSAVE命令;

執行FLUSHALL命令;

執行復制(replication)時。

執行快照的場景

根據配置自動快照Redis允許用戶自定義快照條件,當滿足條件時自動執行快照,快照規

則的配置方式如下:

1 save 900 1

2 save 300 10

3 save 60 10000

每個快照條件獨占一行,他們之間是或(||)關系,只要滿足任何一個

就進行快照。上面配置save后的第一個參數T是時間,單位是秒,第二

個參數M是更改的鍵的個數,含義是:當時間T內被更改的鍵的個數大於

M時,自動進行快照。比如save 900 1的含義是15分鍾內(900s)被更改

的鍵的個數大於1時,自動進行快照操作。

執行SAVE或BGSAVE命令

除了讓Redis自動進行快照外,當我們需要重啟,遷移,備份Redis時,

我們也可以手動執行SAVE或BGSAVE命令主動進行快照操作。

SAVE命令:當執行SAVE命令時,Redis同步進行快照操

作,期間會阻塞所有來自客戶端的請求,所以放數據庫數據較多

時,應該避免使用該命令;

BGSAVE命令: 從命令名字就能看出來,這個命令與SAVE

命令的區別就在於該命令的快照操作是在后台異步進行的,進行

快照操作的同時還能處理來自客戶端的請求。執行BGSAVE命令

后Redis會馬上返回OK表示開始進行快照操作,如果想知道快照

操作是否已經完成,可以使用LASTSAVE命令返回最近一次成功

執行快照的時間,返回結果是一個Unix時間戳。

執行FLUSHALL命令

當執行FLUSHALL命令時,Redis會清除數據庫中的所有數據。需要注意

的是:不論清空數據庫的過程是否觸發 了自動快照的條件,只要自動快照條件不為空,Redis就會執行一次快照操作,當沒有定義自動快照

條件時,執行FLUSHALL命令不會進行快照操作。

執行復制

當設置了主從模式時,Redis會在復制初始化是進行自動快照。

快照原理

Redis默認會將快照文件存儲在Redis當前進程的工作目錄的dump.rdb文

件中,可以通過配置文件中的dir和dbfilename兩個參數分別指定快照

文件的存儲路徑和文件名,例如:

1 dbfilename dump.rdb

2 dir /opt/soft/redis-3.0.4/cache

快照執行的過程如下:

1. Redis使用fork函數復制一份當前進程(父進程)的副本(子進

程);

2. 父進程繼續處理來自客戶端的請求,子進程開始將內存中的數

據寫入硬盤中的臨時文件;

3. 當子進程寫完所有的數據后,用該臨時文件替換舊的RDB文

件,至此,一次快照操作完成。

需要注意的是:

在執行fork是時候操作系統(類Unix操作系統)會使用寫時復制

(copy-on-write)策略,即fork函數發生的一刻,父進程和子進

程共享同一塊內存數據,當父進程需要修改其中的某片數據(如執

行寫命令)時,操作系統會將該片數據復制一份以保證子進程不受

影響,所以RDB文件存儲的是執行fork操作那一刻的內存數據。所

以RDB方式理論上是會存在丟數據的情況的(fork之后修改的的那

些沒有寫進RDB文件)。通過上述的介紹可以知道,快照進行時時不會修改RDB文件的,只有完

成的時候才會用臨時文件替換老的RDB文件,所以就保證任何時候RDB文

件的都是完整的。這使得我們可以通過定時備份RDB文件來實現Redis數

據的備份。RDB文件是經過壓縮處理的二進制文件,所以占用的空間會

小於內存中數據的大小,更有利於傳輸。

Redis啟動時會自動讀取RDB快照文件,將數據從硬盤載入到內存,根據

數量的不同,這個過程持續的時間也不盡相同,通常來講,一個記錄

1000萬個字符串類型鍵,大小為1GB的快照文件載入到內存需要20-30秒

的時間。

示例

下面演示RDB方式持久化,首先使用配置有如下快照規則:

1 save 900 1

2 save 300 10

3 save 60 10000

4 dbfilename dump.rdb

5 dir /opt/soft/redis-3.0.4/cache

的配置文件/opt/soft/redis-3.0.4/conf/redis.conf啟動Redis服務:

然后通過客戶端設置一個鍵值:

1 [qifuguang@Mac~]$ /opt/soft/redis-3.0.4/src/redis-cli -p 6379

2 127.0.0.1:6379> set test-rdb HelloWorld

3 OK

4 127.0.0.1:6379> get test-rdb

5 "HelloWorld"6 127.0.0.1:6379>

現在強行kill Redis服務:

現在到/opt/soft/redis-3.0.4/cache目錄看,目錄下出現了Redis的快

照文件dump.rdb:

1 [qifuguang@Mac/opt/soft/redis-3.0.4/cache]$ ls

2 dump.rdb

現在重新啟動Redis:

然后再用客戶端連接,檢查之前設置的key是否還存在:

4

3

2

1 3.0.4/src/redis-cli -p 6379

127.0.0.1:6379> get test-r

"HelloWorld"

127.0.0.1:6379>

[qifuguang@Mac~]$ /opt

可以發現,之前設置的key在Redis重啟之后又通過快照文件dump.rdb恢

復了。

AOF方式在使用Redis存儲非臨時數據時,一般都需要打開AOF持久化來降低進程

終止導致的數據丟失,AOF可以將Redis執行的每一條寫命令追加到硬盤

文件中,這已過程顯然會降低Redis的性能,但是大部分情況下這個影

響是可以接受的,另外,使用較快的硬盤能提高AOF的性能。

開啟AOF

默認情況下,Redis沒有開啟AOF(append only file)持久化功能,可

以通過在配置文件中作如下配置啟用:

1 appendonly yes

開啟之后,Redis每執行一條寫命令就會將該命令寫入硬盤中的AOF文

件。AOF文件保存路徑和RDB文件路徑是一致的,都是通過dir參數配

置 , 默 認 文 件 名 是 : appendonly.aof , 可 以 通 過 配 置

appendonlyfilename參數修改,例如:

1 appendonlyfilename appendonly.aof

AOF持久化的實現

AOF純文本的形式記錄了Redis執行的寫命令,例如在開啟AOF持久化的

情況下執行如下命令:

1 [qifuguang@Mac/opt/soft/redis-3.0.4]$ ./src/redis-cli

2 127.0.0.1:6379>

3 127.0.0.1:6379>

4 127.0.0.1:6379>

5 127.0.0.1:6379> set aof1 value1

6 OK

7 127.0.0.1:6379> set aof2 value2

8 OK

9 127.0.0.1:6379>

然后查看/opt/soft/redis-3.0.4/cache/appendonly.aof文件:

1 [qifuguang@Mac/opt/soft/redis-3.0.4/cache]$ cat appendonly.aof

2 *23 $6

4 SELECT

5 $1

6 0

7 *3

8 $3

9 set

10 $4

11 aof1

12 $6

13 value1

14 *3

15 $3

16 set

17 $4

18 aof2

19 $6

20 value2

文件中的內容正是Redis剛才執行的命令的內容,內容的格式就先不展

開敘述了。

AOF文件重寫

假設Redis執行了如下命令:

1 [qifuguang@Mac/opt/soft/redis-3.0.4]$ ./src/redis-cli

2 127.0.0.1:6379>

3 127.0.0.1:6379>

4 127.0.0.1:6379>

5 127.0.0.1:6379> set k v1

6 OK

7 127.0.0.1:6379> set k v2

8 OK

9 127.0.0.1:6379> set k v3

10 OK

11 127.0.0.1:6379>

如果這所有的命令都寫到AOF文件的話,將是一個比較蠢行為,因為前

面兩個命令會被第三個命令覆蓋,所以AOF文件完全不需要保存前面兩個文件,事實上Redis確實就是這么做的。刪除AOF文件中無用的命令的

過程成為”AOF重寫”,AOF重寫可以在配置文件中做相應的配置,當滿

足配置的條件時,自動進行AOF重寫操作。配置如下:

1 auto-aof-rewrite-percentage 100

2 auto-aof-rewrite-min-size 64mb

第一行的意思是,目前的AOF文件的大小超過上一次重寫時的AOF文件的

百分之多少時再次進行重寫,如果之前沒有重寫過,則以啟動時AOF文

件大小為依據。

第二行的意思是,當AOF文件的大小大於64MB時才進行重寫,因為如果

AOF文件本來就很小時,有幾個無效的命令也是無傷大雅的事情。

這兩個配置項通常一起使用。

我們還可以手動執行BDREWRITEAOF命令主動讓Redis重寫AOF文件,執行

重寫命令之后查看現在的AOF文件:

1 [qifuguang@Mac/opt/soft/redis-3.0.4]$ cat cache/appendonly.aof

2 *2

3 $6

4 SELECT

5 $1

6 0

7 *3

8 $3

9 SET

10 $4

11 aof2

12 $6

13 value2

14 *3

15 $3

16 SET

17 $1

18 k

19 $2

20 v3

21 *322 $3

23 SET

24 $4

25 aof1

26 $6

27 value1

可以看到,文件中並沒有再記錄set k v1這樣的無效命令。

同步硬盤數據

雖然每次執行更改數據庫的內容時,AOF都會記錄執行的命令,但是由

於操作系統本身的硬盤緩存的緣故,AOF文件的內容並沒有真正地寫入

硬盤,在默認情況下,操作系統會每隔30s將硬盤緩存中的數據同步到

硬盤,但是為了防止系統異常退出而導致丟數據的情況發生,我們還可

以在Redis的配置文件中配置這個同步的頻率:

1 # appendfsync always

2 appendfsync everysec

3 # appendfsync no

第一行表示每次AOF寫入一個命令都會執行同步操作,這是最安全也是

最慢的方式;

第二行表示每秒鍾進行一次同步操作,一般來說使用這種方式已經足

夠;

第三行表示不主動進行同步操作,這是最不安全的方式。

總結:redis的持久化

Snapshotting(快照)RDB

修改配置文件,在指定時間內修改的鍵個數大於設定的值執行save,

參數:秒數,修改的鍵個數

例如:

save 20 1

save 900 1save 300 10

save 60 10000

配置文件不起作用是因為重啟的時候沒有加配置文件的參數,例如:

redis­server /tsh/redis­3.0.0/redis.conf

append only file(AOF模式)

修改配置文件redis.conf,appendonly yes

重啟服務,一定有加上配置文件的參數

此時在 src目錄下生成文件appendonly.aof,這個文件記錄了每一步

的操作,效率稍慢但是更安全


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM