概述redis
Redis的強大性能很大程度上都是由於全部數據都是存儲在內存中的,數據庫
然而當Redis重啓後,全部存儲在內存中的數據將會丟失,在不少狀況緩存
下是沒法容忍這樣的事情的。因此,咱們須要將內存中的數據持久化!安全
典型的須要持久化數據的場景以下:服務器
將Redis做爲數據庫使用;app
將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
配置文件不起做用是由於重啓的時候沒有加配置文件的參數,例如:
redisserver /tsh/redis3.0.0/redis.conf
append only file(AOF模式)
修改配置文件redis.conf,appendonly yes
重啓服務,必定有加上配置文件的參數
此時在 src目錄下生成文件appendonly.aof,這個文件記錄了每一步
的操做,效率稍慢可是更安全