問題的發現及解決過程:
1.Redis主從復制(一主一從)環境在客戶端用命令查看主從狀態
在slave上輸入命令顯示如下:
在master上輸入命令顯示如下:
從顯示可以看出主從關系出現問題,然后查看slave的redis.log有如下報錯:
以為是IP及端口問題,經檢查后發現非此問題。於是在網上查看一些別人的解決方法,但試過后都無效。於是查看master的redis.log有如下報錯:
說明內存不足,無法為fork子進程分配內存,這就是主從出現問題的原因。
解決方法:
在master上的操作:
vim /etc/sysctl.conf
vm.overcommit_memory = 1 #在文件里添加該行后然后執行sysctl -p命令,該行的解釋請看參考鏈接 https://blog.csdn.net/zqz_zqz/article/details/53384854 或下面的知識點擴展
此時再查看主從關系:
slave顯示:
master顯示:
說明主從關系已經恢復正常,再查看redis.log發現已經不再報錯。
知識點擴展:
1.vm.overcommit_memory 參數說明如下:
Linux對大部分申請內存的請求都回復"yes",以便能跑更多更大的程序。因為申請內存后,並不會馬上使用內存,將這些不會使用的空閑內存分配給其它程序使用,以提高內存利用率,這種技術叫做Overcommit。一般情況下,當所有程序都不會用到自己申請的所有內存時,系統不會出問題,但是如果程序隨着運行,需要的內存越來越大,在自己申請的大小范圍內,不斷占用更多內存,直到超出物理內存,當linux發現內存不足時,會發生OOM killer(OOM=out-of-memory)。它會選擇殺死一些進程(用戶態進程,不是內核線程,哪些占用內存越多,運行時間越短的進程越有可能被殺掉),以便釋放內存。當oom-killer發生時,linux會選擇殺死哪些進程?選擇進程的函數是oom_badness函數(在mm/oom_kill.c中),該函數會計算每個進程的點數(0~1000)。點數越高,這個進程越有可能被殺死。每個進程的點數跟(/proc/<pid>/oom_adj)oom_score_adj有關,而且oom_score_adj可以被設置(-1000最低,1000最高)。當發生oom killer時,會將記錄在系統日志/var/log/messages中。
這時候就是內存不足,到了這里,操作系統要怎么辦,就要祭出我們的主角“overcommit_memory”參數了(/proc/sys/vm/overcommit_memory);
vm.overcommit_memory = 0 啟發策略
比較 此次請求分配的虛擬內存大小和系統當前空閑的物理內存加上swap,決定是否放行。系統在為應用進程分配虛擬地址空間時,會判斷當前申請的虛擬地址空間大小是否超過剩余內存大小,如果超過,則虛擬地址空間分配失敗。因此,也就是如果進程本身占用的虛擬地址空間比較大或者剩余內存比較小時,fork、malloc等調用可能會失敗。
vm.overcommit_memory = 1 允許overcommit
直接放行,系統在為應用進程分配虛擬地址空間時,完全不進行限制,這種情況下,避免了fork可能產生的失敗,但由於malloc是先分配虛擬地址空間,而后通過異常陷入內核分配真正的物理內存,在內存不足的情況下,這相當於完全屏蔽了應用進程對系統內存狀態的感知,即malloc總是能成功,一旦內存不足,會引起系統OOM殺進程,應用程序對於這種后果是無法預測的。
vm.overcommit_memory = 2 禁止overcommit
根據系統內存狀態確定了虛擬地址空間的上限,由於很多情況下,進程的虛擬地址空間占用遠大於其實際占用的物理內存,這樣一旦內存使用量上去以后,對於一些動態產生的進程(需要復制父進程地址空間)則很容易創建失敗,如果業務過程沒有過多的這種動態申請內存或者創建子進程,則影響不大,否則會產生比較大的影響 。這種情況下系統所能分配的內存不會超過上面提到的CommitLimit大小,如果這么多資源已經用光,那么后面任何嘗試申請內存的行為都會返回錯誤,這通常意味着此時沒法運行任何新程序。
2./etc/sysctl.conf添加vm.overcommit_memory=1一行相當與修改了/proc/sys/vm/overcommit_memory(默認是0)文件(參考鏈接 http://blog.51cto.com/yjw1983/1914916),所以我認為你可以不在/etc/sysctl.conf添加vm.overcommit_memory一行,直接修改/proc/sys/vm/overcommit_memory文件亦可
3.該問題解決兩天后在slave發現如下報錯:
亦是內存不足導致,采用如上方法即可解決
4.此參數是redis優化的一個關鍵參數,如果主從硬件配置相同,建議主從都修改此參數。
5.redis建議根據業務選擇大於redis.conf中auto-aof-rewrite-min-size兩倍的內存,例如該值為20G,建議內存為64G。auto-aof-rewrite-min-size的大小建議根據持久化文件的大小來進行優化。