Redis说无法分配内存该怎么办?
近日我司生產環境的redis頻繁異常不可訪問,已經嚴重影響公司牛逼的產品起飛了,那么作為集設計、編碼、測試、運維于一身的全棧吹牛皮工程師,必須給它搞上一搞。
生產環境出了問題后,其實就是登錄失敗時提示token無效。根據老衲多年寫bug的經驗,第一時間就想到redis出了問題。登錄服務器,ps看了一眼redis的進程,沒問題。又free看了一眼內存,我的個乖乖,64g內存還剩幾百兆,這肯定不正常了啊。隨即打開了redis的日志,看到滿屏都是以下內容輸出,有那么一瞬,就像一萬只草泥馬從心頭奔過。
6663:M 10 Apr 03:42:42.077 * 1 changes in 900 seconds. Saving... 6663:M 10 Apr 03:42:42.077 # Can't save in background: fork: Cannot allocate memory 6663:M 10 Apr 03:42:48.086 * 1 changes in 900 seconds. Saving... 6663:M 10 Apr 03:42:48.086 # Can't save in background: fork: Cannot allocate memory 6663:M 10 Apr 03:42:54.097 * 1 changes in 900 seconds. Saving... 6663:M 10 Apr 03:42:54.097 # Can't save in background: fork: Cannot allocate memory 6663:M 10 Apr 03:43:00.006 * 1 changes in 900 seconds. Saving... 6663:M 10 Apr 03:43:00.006 # Can't save in background: fork: Cannot allocate memory不過就這個日志來說,確實提示的也很清楚了,redis的fork進程沒有辦法分配到內存,這和我們查詢到內存只有幾百兆的情況也能吻合。天大地大,生產最大。不管三七二十八,先恢復環境訪問。于是乎重啟了rediis,系統能夠正常的登錄了。
你以為到這里就結束了嗎?當然不可能,作為一個新時代的四有青年,我怎么可能僅僅滿足恢復生產環境訪問這么簡單的地步呢?過兩天萬一又不可訪問了,而恰巧那會兒我正在和霸飛忒燒烤大腰子,那豈不是顯得我不尊重大腰子了。
還是看看redis的日志怎么說吧。打開剛剛啟動的redis的日志,有一行warning瞬間引起了老衲的注意(得虧不是FBI WARNING)。
21515:M 10 Apr 16:31:10.232 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.redis已經在啟動的時候提前告訴使用者了,你最好給我把vm.overcommit_memory設置成1,要不然系統內存不夠分配了,我可不能保證我能在后臺給你把數據給你保存成功。這不是就和我們redis報錯Cannot allocate memory不謀而合了嘛。來看看vm.overcommit_memory是個神馬,它是linux內存分配策略的配置參數,有以下3個值:
0:表示操作系統內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,并把錯誤返回給應用進程。
1:表示操作系統內核允許分配所有的物理內存,而不管當前的內存狀態如何。
2: 表示操作系統內核允許分配超過所有物理內存和交換空間總和的內存。
而且redis很貼心的告訴了使用者,最好把vm.overcommit_memory設置成1,然后重啟服務器,或者執行命令sysctl vm.overcommit_memory=1讓其立即生效,但是重啟后又還原。
既然redis都把飯喂到嘴邊了,那你還不吃就不能怪誰了。話不多說,先來一波操作。在/etc/sysctl.conf中添加vm.overcommit_memory=1,生產環境暫時先不重啟服務器。緊接著執行命令sysctl vm.overcommit_memory=1讓其立即生效,這樣來說即使某個月黑風高的夜晚,服務器重啟了,這個配置也不會被還原。
當然這臺服務器上不僅僅運行redis一個中間件服務,還有其他的服務,如果任由redis去無限制的申請內存,那么也會影響到其他中間件服務的運行。因此還需要在針對于redis自身進行最大內存的限制。
編輯/etc/redis.conf,找到maxmemory項,設置redis最大可以使用到的內存,單位為字節。重啟redis服務使其生效。
這一波操作下來,redis運行一段時間沒見出問題,通過日志查詢,也未見Cannot allocate memory的錯誤了,我又可以和我們的小伙伴一起快樂地去玩耍了。
總結
以上是生活随笔為你收集整理的Redis说无法分配内存该怎么办?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于加密后门
- 下一篇: Redis缓存击穿,穿透,雪崩等问题