非常感謝http://blog.csdn.net/zhu_tianwei/article/details/44893055
Redis由于支持非常豐富的內存數據結構類型,如何把這些復雜的內存組織方式持久化到磁盤上是一個難題,所以Redis的持久化方式與傳統數據庫的方式有比較多的差別,Redis一共支持四種持久化方式,分別是:1.定時快照方式(Snapshotting)2.基于語句追加文件的方式(Append-only file)3.虛擬內存(vm)4.Diskstore方式在設計思路上,前兩種是基于全部數據都在內存中,即小數據量下提供磁盤落地功能,而后兩種方式則是作者在嘗試存儲數據超過物理內存時,即大數據量的數據存儲,截止到本文,后兩種持久化方式仍然是在實驗階段,并且vm方式基本已經被作者放棄,所以實際能在生產環境用的只有前兩種,換句話說Redis目前還只能作為小數據量存儲(全部數據能夠加載在內存中),海量數據存儲方面并不是Redis所擅長的領域。下面分別介紹下這幾種持久化方式:一、定時快照方式(Snapshotting)快照是默認的持久化方式。這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名為dump.rdb。可以通過配置設置自動做快照持久化的方式。我們可以配置redis在n秒內如果超過m個key被修改就自動做快照,下面是默認的快照保存配置:
[plain] view plain copy PRint?不過DiskStore有個缺點,就是有可能發生兩個不同的Key生成一個相同的SHA1%20Hash值,這樣就有可能出現丟失數據的問題。不過這種情況發生的幾率比較少,所以是可以接受的。根據作者的意圖,未來可能使用B+tree來替換這種高度依賴文件系統的實現方法。
另外,Redis持久化磁盤IO方式及其帶來的問題
有Redis線上運維經驗的人會發現Redis在物理內存使用比較多,但還沒有超過實際物理內存總容量時就會發生不穩定甚至崩潰的問題,有人認為是基于快照方式持久化的fork系統調用造成內存占用加倍而導致的,這種觀點是不準確的,因為fork%20調用的copy-on-write機制是基于操作系統頁這個單位的,也就是只有有寫入的臟頁會被復制,但是一般你的系統不會在短時間內所有的頁都發生了寫入而導致復制,那么是什么原因導致Redis崩潰的呢?答案是Redis的持久化使用了Buffer%20IO造成的,所謂Buffer%20IO是指Redis對持久化文件的寫入和讀取操作都會使用物理內存的Page%20Cache,而大多數數據庫系統會使用Direct%20IO來繞過這層Page%20Cache并自行維護一個數據的Cache,而當Redis的持久化文件過大(尤其是快照文件),并對其進行讀寫時,磁盤文件中的數據都會被加載到物理內存中作為操作系統對該文件的一層Cache,而這層Cache的數據與Redis內存中管理的數據實際是重復存儲的,雖然內核在物理內存緊張時會做Page%20Cache的剔除工作,但內核很可能認為某塊Page%20Cache更重要,而讓你的進程開始Swap%20,這時你的系統就會開始出現不穩定或者崩潰了。我們的經驗是當你的Redis物理內存使用超過內存總容量的3/5時就會開始比較危險了。下圖是Redis在讀取或者寫入快照文件dump.rdb后的內存數據圖:總結:1.根據業務需要選擇合適的數據類型,并為不同的應用場景設置相應的緊湊存儲參數。2.當業務場景不需要數據持久化時,關閉所有的持久化方式可以獲得最佳的性能以及最大的內存使用量。3.如果需要使用持久化,根據是否可以容忍重啟丟失部分數據在快照方式與語句追加方式之間選擇其一,不要使用虛擬內存以及diskstore方式。4.不要讓你的Redis所在機器物理內存使用超過實際內存總量的3/5。
轉至:
http://blog.csdn.net/freebird_lb/article/details/7778981
http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage
新聞熱點
疑難解答