redis 的兩種持久化方式及原理

    Redis是一種高級key-value數據庫。它跟memcached類似,不過數據可以持久化,而且支持的數據類型很豐富。有字符串,鏈表,集 合和有序集合。支持在服務器端計算集合的並,交和補集(difference)等,還支持多種排序功能。所以Redis也可以被看成是一個數據結構服務器。

    Redis的所有數據都是保存在內存中,然後不定期的通過異步方式保存到磁盤上(這稱爲“半持久化模式”);也可以把每一次數據變化都寫入到一個append only file(aof)裏面(這稱爲“全持久化模式”)。

第一種方法filesnapshotting默認redis是會以快照的形式將數據持久化到磁盤的(一個二進制文件,dump.rdb,這個文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之內,redis至少發生M次修改則redis抓快照到磁盤。當然我們也可以手動執行save或者bgsave(異步)做快照。

工作原理簡單介紹一下:當redis需要做持久化時,redis會fork一個子進程;子進程將數據寫到磁盤上一個臨時RDB文件中;當子進程完成寫臨時文件後,將原來的RDB替換掉,這樣的好處就是可以copy-on-write

還有一種持久化方法是Append-onlyfilesnapshotting方法在redis異常死掉時,最近的數據會丟失(丟失數據的多少視你save策略的配置),所以這是它最大的缺點,當業務量很大時,丟失的數據是很多的。Append-only方法可以做到全部數據不丟失,但redis的性能就要差些。AOF就可以做到全程持久化,只需要在配置文件中開啓(默認是no),appendonly yes開啓AOF之後,redis每執行一個修改數據的命令,都會把它添加到aof文件中,當redis重啓時,將會讀取AOF文件進行“重放”以恢復到redis關閉前的最後時刻。

LOG Rewriting隨着修改數據的執行AOF文件會越來越大,其中很多內容記錄某一個key的變化情況。因此redis有了一種比較有意思的特性:在後臺重建AOF文件,而不會影響client端操作。在任何時候執行BGREWRITEAOF命令,都會把當前內存中最短序列的命令寫到磁盤,這些命令可以完全構建當前的數據情況,而不會存在多餘的變化情況(比如狀態變化,計數器變化等),縮小的AOF文件的大小。所以當使用AOF時,redis推薦同時使用BGREWRITEAOF

AOF文件刷新的方式,有三種,參考配置參數appendfsync :appendfsync always每提交一個修改命令都調用fsync刷新到AOF文件,非常非常慢,但也非常安全;appendfsync everysec每秒鐘都調用fsync刷新到AOF文件,很快,但可能會丟失一秒以內的數據;appendfsync no依靠OS進行刷新,redis不主動刷新AOF,這樣最快,但安全性就差。默認並推薦每秒刷新,這樣在速度和安全上都做到了兼顧。

可能由於系統原因導致了AOF損壞,redis無法再加載這個AOF,可以按照下面步驟來修復:首先做一個AOF文件的備份,複製到其他地方;修復原始AOF文件,執行:$ redis-check-aof –fix ;可以通過diff –u命令來查看修復前後文件不一致的地方;重啓redis服務。

LOG Rewrite的工作原理:同樣用到了copy-on-write:首先redis會fork一個子進程;子進程將最新的AOF寫入一個臨時文件;父進程增量的把內存中的最新執行的修改寫入(這時仍寫入舊的AOF,rewrite如果失敗也是安全的);當子進程完成rewrite臨時文件後,父進程會收到一個信號,並把之前內存中增量的修改寫入臨時文件末尾;這時redis將舊AOF文件重命名,臨時文件重命名,開始向新的AOF中寫入。

最後,爲以防萬一(機器壞掉或磁盤壞掉),記得定期把使用 filesnapshotting 或 Append-only 生成的*rdb *.aof文件備份到遠程機器上。我是用crontab每半小時SCP一次。我沒有使用redis的主從功能 ,因爲半小時備份一次應該是可以了,而且我覺得有如果做主從有點浪費機器。這個最終還是看應用來定了。


發佈了101 篇原創文章 · 獲贊 51 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章