2012-08-01 53 views
27

所有: 這裏是Redis的bgsave失敗,因爲叉無法分配內存

   total  used  free  shared buffers  cached 
Mem:   64433  49259  15174   0   3   31 
-/+ buffers/cache:  49224  15209 
Swap:   8197  184  8012 

我Redis的服務器使用了46G內存「免費-m」我的服務器內存的信息,幾乎15G的記憶中留下自由

據我所知,fork是copy的寫入,當有15G空閒內存時,應該不會失敗,這對malloc必要的內核結構來說已經足夠了。

此外,當redis服務器使用42G內存時,bgsave可以,叉也可以。

是否有任何vm參數可以調整以使fork返回成功?

謝謝。

+0

Get'double '更多的記憶 – surfer190 2017-05-19 11:34:11

回答

14

從PROC(5):

/proc/sys/vm/overcommit_memory 
       This file contains the kernel virtual memory accounting mode. Values are: 
       0: heuristic overcommit (this is the default) 
       1: always overcommit, never check 
       2: always check, never overcommit 
       In mode 0, calls of mmap(2) with MAP_NORESERVE set are not checked, and the default check is very weak, leading to the risk of getting a process "OOM-killed". Under Linux 2.4 
       any non-zero value implies mode 1. In mode 2 (available since Linux 2.6), the total virtual address space on the system is limited to (SS + RAM*(r/100)), where SS is the size 
       of the swap space, and RAM is the size of the physical memory, and r is the contents of the file /proc/sys/vm/overcommit_ratio. 
46

更具體地,從Redis FAQ

Redis的背景節省模式依賴於寫入時複製語義在現代操作系統叉:Redis的叉子(創建一個子進程),它是父進程的精確副本。子進程將磁盤上的數據庫轉儲並最終退出。從理論上講,孩子應該儘可能多地使用父母作爲副本的內存,但實際上要感謝大多數現代操作系統實現的寫入時複製語義,父進程和子進程將共享公用內存頁面。只有當它在孩子或父母中發生變化時,頁面纔會被複制。由於理論上所有的頁面可能會在孩子進程保存時發生變化,因此Linux無法預先知道孩子需要多少內存,所以如果overcommit_memory設置爲零,那麼分支將失敗,除非有足夠的空閒RAM需要真正複製所有父內存頁面,結果是如果您擁有3 GB的Redis數據集並且只有2 GB的空閒內存,則會失敗。

將overcommit_memory設置爲1表示Linux放寬並以更樂觀的分配方式執行分叉,而這確實是Redis需要的。作爲OS認爲它寫入到磁盤

的Redis並不需要儘可能多的內存,這樣可以先發制人失敗叉。

29

修改/etc/sysctl.conf,加上

vm.overcommit_memory=1 

然後通過

在FreeBSD重啓的sysctl: $ sudo的/etc/rc.d/sysctl重裝

在Linux: $ sudo sysctl -p /etc/sysctl.conf

相關問題