轉:
Redis需要多少內存預留-內存占用多少才安全
上一篇文章,我已經嘗試過,用設置的方式,去限制redis內存的占用大小,結果發現是不可行的。(redis不會區分冷熱數據,保留冷數據在硬盤上)。那么如果要正常運行redis,就需要知道,redis最多可以占用多少內存,保留多少內存。
結論:
極限情況:留出一倍內存。比如你的redis數據占用了8G內存,那么你還需要再預留8G空閑內存。也就是內存需求是16G。內存占用率低於50%是最安全的。
普通情況:正常情況下,在序列化周期內,不會更改所有數據,只會有部分數據更改,那么,預留出可能產生的更改部分的空間,就行。如果實在要說一個數據的話,內存占用率低於75%都是安全的。
比如我們這個游戲服務器的,N台數據服務器之一的截圖:
如上圖,16G的內存,已經使用了64%了。但是實際上,在fork序列化的時候,只多占用了200多M的內存而已。因為只變動了200多M。 也就是說,使用內存使用率即便達到80%,也是安全的。因為Copy-On-Write就需要200M而已。
以下是擴展閱讀,原文鏈接: https://searchdatabase.techtarget.com.cn/7-21572/
多留一倍內存是最安全的。
重寫AOF文件和RDB文件的進程(即使不做持久化,復制到Slave的時候也要寫RDB)會fork出一條新進程來,采用了操作系統的Copy-On-Write策略(如果父進程的內存沒被修改,子進程與父進程共享Page。如果父進程的Page被修改, 會復制一份改動前的內容給新進程),留意Console打出來的報告,如”RDB: 1215 MB of memory used by copy-on-write”。
在系統極度繁忙時,如果父進程的所有Page在子進程寫RDB過程中都被修改過了,就需要兩倍內存。
按照Redis啟動時的提醒,設置 vm.overcommit_memory = 1 ,使得fork()一條10G的進程時,因為COW策略而不一定需要有10G的free memory.
當最大內存到達時,按照配置的Policy進行處理, 默認policy為volatile-lru, 對設置了expire time的key進行LRU清除(不是按實際expire time)。如果沒有數據設置了expire time或者policy為noeviction,則直接報錯,但此時系統仍支持get之類的讀操作。 另外還有幾種policy,比如volatile-ttl按最接近expire time的,allkeys-lru對所有key都做LRU。
原來2.0版的VM(將Value放到磁盤,Key仍然放在內存),2.4版后又不支持了。(ps. 這是個坑。我以前記得有這么個東西)