付諸實踐,RDB 方式持久化的開啟與配置
RDB 方式持久化的開啟與配置
Redis 默認的持久化方式是 RDB ,并且默認是打開的。RDB 的保存有方式分為主動保存與被動保存。主動保存可以在 redis-cli 中輸入 save 即可;被動保存需要滿足配置文件中設(shè)定的觸發(fā)條件,目前官方默認的觸發(fā)條件可以在 redis.conf 中看到:
save?900?1?save?300?10?save?60?10000?復(fù)制代碼
其含義為:
服務(wù)器在900秒之內(nèi),對數(shù)據(jù)庫進行了至少1次修改?服務(wù)器在300秒之內(nèi),對數(shù)據(jù)庫進行了至少10次修改。?服務(wù)器在60秒之內(nèi),對數(shù)據(jù)庫進行了至少10000次修改。?復(fù)制代碼
滿足觸發(fā)條件后,數(shù)據(jù)就會被保存為快照,正是因為這樣才說 RDB 的數(shù)據(jù)完整性是比不上 AOF 的。
觸發(fā)保存條件后,會在指定的目錄生成一個名為 dump.rdb 的文件,等到下一次啟動 Redis 時,Redis 會去讀取該目錄下的 dump.rdb 文件,將里面的數(shù)據(jù)恢復(fù)到 Redis。
這個目錄在哪里呢?
我們可以在客戶端中輸入命令config get dir查看:
gannicus@$?src/redis-cli?127.0.0.1:6379>?config?get?dir?1)?"dir"?2)?"/home/gannicus/Documents/redis-5.0.0"?127.0.0.1:6379>??復(fù)制代碼
返回結(jié)果中的"/home/gannicus/Documents/redis-5.0.0"就是存放 dump.rdb 的目錄。
Redis 版本說明
在測試之前,說明一下前提。redis 是直接從官網(wǎng)下載的壓縮包,解壓后得到的 redis-x.x.x 文件夾,比如我的是 redis-5.0.0,然后進入文件夾,在 redis-5.0.0 項目根目錄使用make命令安裝。
RDB 被動觸發(fā)保存測試
剛才提到它分為主動保存與被動觸發(fā),現(xiàn)在我們來測試一下被動觸發(fā)。首先啟動 redis-server,然后再打開客戶端 redis-cli ,先增添幾條記錄:
127.0.0.1:6379>?set?lca?1?OK?127.0.0.1:6379>?set?lcb?1?OK?127.0.0.1:6379>?set?lcc?1?OK?127.0.0.1:6379>?set?lcd?1?OK?127.0.0.1:6379>?set?lce?1?OK?127.0.0.1:6379>?set?lcf?1?OK?127.0.0.1:6379>?set?lcg?1?OK?127.0.0.1:6379>?set?lch?1?OK?127.0.0.1:6379>?set?lci?1?OK?127.0.0.1:6379>?set?lcj?1?OK?127.0.0.1:6379>?set?lck?1?OK?127.0.0.1:6379>?set?lcl?1?OK?127.0.0.1:6379>?set?lcm?1?OK?復(fù)制代碼
可以看到,總共添加了 13 條記錄:
127.0.0.1:6379>?keys?*??1)?"lca"??2)?"lcd"??3)?"lcg"??4)?"lce"??5)?"lcb"??6)?"lcm"??7)?"lcf"??8)?"lci"??9)?"lcl"?10)?"lcc"?11)?"lck"?12)?"lcj"?13)?"lch"?127.0.0.1:6379>??復(fù)制代碼
然后發(fā)現(xiàn)redis-server端的日志窗口中出現(xiàn)了如下的提示:
21971:M?21?Oct?2018?16:52:44.062?*?10?changes?in?300?seconds.?Saving...?21971:M?21?Oct?2018?16:52:44.063?*?Background?saving?started?by?pid?22552?22552:C?21?Oct?2018?16:52:44.066?*?DB?saved?on?disk?21971:M?21?Oct?2018?16:52:44.165?*?Background?saving?terminated?with?success?復(fù)制代碼
從英文提示中可以大概讀懂這些內(nèi)容,它檢測到 300 秒內(nèi)有 10 條記錄被改動,剛才我們添加了 13 條數(shù)據(jù)記錄,滿足 redis.conf 中對于 RDB 數(shù)據(jù)保存的條件,所以這里執(zhí)行數(shù)據(jù)保存操作,并且提示開辟了一個 22552 的進程出來執(zhí)行保存操作,最后提示保存成功。
并且在目錄內(nèi)看到有 dump.rdb 文件生成。
現(xiàn)在將redis進程kill,哪些數(shù)據(jù)會被保存?
通過命令 kill -9 pid ( pid 是進程編號)模擬 Redis 異常關(guān)閉,然后再啟動 Redis ,我們來看一看,到底是只保存了 10 條記錄還是 13 條全都保存下來了?
127.0.0.1:6379>?keys?*??1)?"lcb"??2)?"lcj"??3)?"lcd"??4)?"lch"??5)?"lci"??6)?"lcc"??7)?"lcf"??8)?"lce"??9)?"lca"?10)?"lcg"?127.0.0.1:6379>??復(fù)制代碼
重啟后查看記錄,發(fā)現(xiàn) 13 條記錄中只有 10 條記錄會被保存,這也印證了之前所說,RDB 方式的數(shù)據(jù)完整性是不可靠的,除非斷掉的那一刻正好是滿足觸發(fā)條件的條數(shù)。
關(guān)閉 RDB
剛才提到了,它是默認啟用的,如果你不需要它可以在配置文件中將這 3 個配置注釋掉,并新增 save ""即可:
save?""?#?save?900?1?#?save?300?10?#?save?60?10000?復(fù)制代碼
保存配置文件后需要重新啟動 Redis 服務(wù)才會生效,然后繼續(xù)添加十幾條記錄:
127.0.0.1:6379>?keys?*??1)?"lcb"?...?23)?"lca"?24)?"lcg"?127.0.0.1:6379>??復(fù)制代碼
在之前已有 10 條的基礎(chǔ)上我再增加了 14 條記錄,這次同樣要通過kill來模擬 Redis 異常關(guān)閉,再啟動服務(wù)看一看,數(shù)據(jù)是否還被保存:
127.0.0.1:6379>?keys?*??1)?"lcb"??2)?"lcj"??3)?"lcd"??4)?"lch"??5)?"lci"??6)?"lcc"??7)?"lcf"??8)?"lce"??9)?"lca"?10)?"lcg"?127.0.0.1:6379>??復(fù)制代碼
發(fā)現(xiàn)后面添加的 14 條記錄并沒有被保存,恢復(fù)數(shù)據(jù)的時候僅僅只是恢復(fù)了之前的 10 條。并且觀察 Redis 服務(wù)端窗口日志,并未發(fā)現(xiàn)像之前一樣的觸發(fā)保存的提示,證明 RDB 方式已經(jīng)被關(guān)閉。
RDB 主動保存測試
通過配置文件關(guān)閉被動觸發(fā),那么主動關(guān)閉是否還會生效呢?
在 Redis 客戶端( redis-cli )通過del命令刪除幾條記錄,然后輸入save命令執(zhí)行保存操作:
127.0.0.1:6379>?keys?*??1)?"lcc"??2)?"lch"??3)?"lcb"??4)?"lci"??5)?"lce"??6)?"lcj"??7)?"lcg"??8)?"lca"??9)?"lcd"?10)?"lcf"?127.0.0.1:6379>?del?lca?lcb?lcc?(integer)?3?127.0.0.1:6379>?save?OK?127.0.0.1:6379>??復(fù)制代碼
可以看到redis-server的日志有新的提示:22598:M 21 Oct 2018 17:22:31.365 * DB saved on disk,它告訴我們數(shù)據(jù)已經(jīng)保存。
那么繼續(xù)模擬異常關(guān)閉,再打開服務(wù),看一看是否真的保存了這些操作:
127.0.0.1:6379>?keys?*?1)?"lci"?2)?"lcj"?3)?"lcd"?4)?"lcg"?5)?"lcf"?6)?"lce"?7)?"lch"?127.0.0.1:6379>??復(fù)制代碼
果不其然,這幾個刪除操作都被保存了下來,恢復(fù)過來的數(shù)據(jù)中已經(jīng)沒有那 3 條記錄了,證明主動關(guān)閉不受 配置文件的影響。
除了save還有其他的保存方式么?
save 和 bgsave 保存
有的,Redis 提供了save和bgsave這兩種不同的保存方式,并且這兩個方式在執(zhí)行的時候都會調(diào)用rdbSave函數(shù),但它們調(diào)用的方式各有不同:
save 直接調(diào)用 rdbSave方法 ,阻塞 Redis 主進程,直到保存完成為止。在主進程阻塞期間,服務(wù)器不能處理客戶端的任何請求。
bgsave 則 fork 出一個子進程,子進程負責(zé)調(diào)用 rdbSave ,并在保存完成之后向主進程發(fā)送信號,通知保存已完成。因為 rdbSave 在子進程被調(diào)用,所以 Redis 服務(wù)器在 bgsave 執(zhí)行期間仍然可以繼續(xù)處理客戶端的請求。
save 是同步操作,bgsave 是異步操作。
bgsave命令的使用方法和save命令的使用方法是一樣的:
127.0.0.1:6379>?keys?*?1)?"lci"?2)?"lcj"?3)?"lcd"?4)?"lcg"?5)?"lcf"?6)?"lce"?7)?"lch"?127.0.0.1:6379>?del?lci?lcj??(integer)?2?127.0.0.1:6379>?bgsave?Background?saving?started?127.0.0.1:6379>?keys?*?1)?"lcd"?2)?"lcg"?3)?"lcf"?4)?"lce"?5)?"lch"?127.0.0.1:6379>??復(fù)制代碼
shutdown 保存
事實上,shutdown命令也是可以保存數(shù)據(jù)的,驚不驚喜。它會在關(guān)閉前將數(shù)據(jù)保存下來,意不意外?
127.0.0.1:6379>?set?app?1?OK?127.0.0.1:6379>?set?apps?1?OK?127.0.0.1:6379>?keys?*?1)?"apps"?2)?"lcd"?3)?"lcg"?4)?"lcf"?5)?"app"?6)?"lce"?7)?"lch"?127.0.0.1:6379>?shutdown?not?connected>?quit?gannicus@$??復(fù)制代碼
然后 Redis 服務(wù)就被關(guān)閉掉了。我們需要重新啟動 Redis 服務(wù),到客戶端中看一看是否生效:
gannicus@$?src/redis-cli?127.0.0.1:6379>?keys?*?1)?"lce"?2)?"lcf"?3)?"lcd"?4)?"lch"?5)?"lcg"?復(fù)制代碼
竟然沒有生效,刺不刺激?這是為什么呢?明明官方文檔之shutdown就說會保存了才退出的,你騙人~
注意到,文檔中有一句
恍然大悟,原來是要在持久化被打開的情況下,通過shutdown命令關(guān)閉才不會丟失數(shù)據(jù),那么就到配置文件中將那幾個save的配置項打開吧:
#???save?""?save?900?1?save?300?10?save?60?10000?復(fù)制代碼
然后再開啟 Redis 服務(wù),再嘗試一遍(過程為:添加 -> shutdown -> 重啟服務(wù) -> 查看):
127.0.0.1:6379>?set?app?1?OK?127.0.0.1:6379>?set?apps?1?OK?127.0.0.1:6379>?shutdown?not?connected>?quit?gannicus@$?src/redis-cli?127.0.0.1:6379>?keys?*?1)?"lce"?2)?"lch"?3)?"app"?4)?"lcf"?5)?"apps"?6)?"lcd"?7)?"lcg"?127.0.0.1:6379>??復(fù)制代碼
這下終于弄明白了。
數(shù)據(jù)庫 Redis
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。