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