1.redis內存不夠導致數據丟失


redis丟失數據案例

  背景介紹: 

我們的一台redis服務器,硬件配置為4核,4G內存。redis持久話方案是RDB。前面幾個月redis使用的

  內存在1G左右。在一次重啟之后,redis只恢復了部分數據,這時查看redis.log文件,看到如下錯誤:

[23635] 25 Jul 08:30:54.059 * 10000 changes in 60 seconds. Saving...
[23635] 25 Jul 08:30:54.059 # Can't save in background: fork: Cannot allocate memory

  這時,想起redis啟動時的警告 

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.

  翻譯: 

警告:過量使用內存設置為0!在低內存環境下,后台保存可能失敗。為了修正這個問題,
請在/etc/sysctl.conf 添加一項 'vm.overcommit_memory = 1' ,
然后重啟(或者運行命令'sysctl vm.overcommit_memory=1' )使其生效。

  vm.overcommit_memory不同值說明

  • 0:表示檢查是否有足夠的內存可用,如果是,允許分配,如果內存不夠,拒絕該請求,並返回一個錯誤應用程序。
  • 1:允許分配超出物理內存加上交換內存的請求
  • 2:內核總是返回true

  redis的數據會寫機制分為兩種

  • 同步回寫save命令,redis主進程直接寫數據到磁盤。當數據量大時,這個命令將阻塞,響應時間長
  • 異步回寫bgsave命令,redis主進程fork一個子進程,復制主進成的內存並通過子進程回寫數據到磁盤

  由於RDB文件寫的時候fork一個子進程。相當於復制一個內存鏡像。當時系統內存是4G,而redis占用了近3G的內存,因此肯定會報內存無法分配。如果vm.overcommit_memory設置為0,在可用內存不足的情況先,就無法分配新的內存。如果vm.overcommit_memory設置為1,那么redis將使用交換內存。

  解決方案:

  方法一:修改內核參數vim /etc/sysctl。設置vm.overcommit_memory=1然后執行

  方法二:使用交換內存並不是一個完美的方案,最好的辦法就是擴大物理內存。

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM