1. 程式人生 > 其它 >1.redis記憶體不夠導致資料丟失

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然後執行

  方法二:使用交換記憶體並不是一個完美的方案,最好的辦法就是擴大實體記憶體。