linux下redis执行bgsave时,报overcommit_memory错误问题

标签: 操作系统 linux overcommit_memory redis | 发表时间:2015-06-08 10:17 | 作者:信海龙
出处:http://www.bo56.com
现象

一台机器如果内存用完,在进行bgsave时,可能会报错。错误信息大概如下:

[1946] 23 Mar 15:21:02.308 # 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的bgsave命令时,redis会fork一个进程把redis中的内存数据写入磁盘。这样的好处是,copy on write,有效的节省了内存占用。但是,bgsave时,如果有数据变更,一样需要申请内存。当申请内存时,如果发现内存不够,可能就会报上面的错误。

内核参数overcommit_memory

参数vm.overcommit_memory控制着linux的内存分配策略。
这个参数有三个值: 0 1 2
0 表示启发式处理。会尽量减少swap的使用,root可以分配比一般用户略多的内存。默认值。
1 表示一直允许overcommit。一般用户科学计算。
2 表示不允许超过CommitLimit值。根据vm.overcommit_ratio定义的值,允许分配超出物理内存加上交换内存的请求。vm.overcommit_ratio参数是一个百分比,加上内存量决定内存可以超量分配多少内存。例如,vm.overcommit_ratio值为50,而内存有1GB,那么这意味着在内存分配请求失败前,加上交换内存,内存将允许高达1.5GB的内存分配请求。

之所以允许申请大于内存的malloc,其中一个原因是,malloc后,并不一定马上使用。

相关英文文档阅读
overcommit_memory
Overcommit and OOM

设置方法

很简单,按提示的操作(将vm.overcommit_memory 设为1)即可:
有三种方式修改内核参数,但要有root权限:
(1)编辑/etc/sysctl.conf ,改vm.overcommit_memory=1,然后sysctl -p 使配置文件生效
(2)sysctl vm.overcommit_memory=1
(3)echo 1 > /proc/sys/vm/overcommit_memory
设置完后,可以通过 sysctl -n vm.overcommit_memory 验证设置是否生效。

延伸阅读

OOM

当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。
当oom-killer发生时,linux会选择杀死哪些进程?选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该函数会计算每个进程的点数(0~1000)。点数越高,这个进程越有可能被杀死。每个进程的点数跟oom_score_adj有关,而且oom_score_adj可以被设置(-1000最低,1000最高)。

查看内存总量和已用内存

grep -i commit /proc/meminfo
看到CommitLimit和Committed_As参数。
CommitLimit是一个内存分配上限,CommitLimit = 物理内存 * overcommit_ratio(默认50,即50%) + swap大小
Committed_As是已经分配的内存大小。

相关 [linux redis bgsave] 推荐:

linux下redis执行bgsave时,报overcommit_memory错误问题

- - 博学无忧
一台机器如果内存用完,在进行bgsave时,可能会报错. 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 BGSAVE因为内存不足 fork 失败导致目标 Redis 无法访问的问题 - piperck - 博客园

- -
中秋的时候正在外面愉快的在外卖喝着咖啡玩电脑. 突发 redis 报警从 sentry 应用端曝出的错误. 于是又开始愉快的处理问题了,看上去像是执行 rdb 快照持久化的时候出现的问题,上到 redis 机器查看日志定位详细问题. 可以很明显的发现应该是尝试 fork 的时候内存不够,并没有被 linux 内核放行.

Redis持久化实践及灾难恢复模拟 « Hey! Linux.

- -
一、对Redis持久化的探讨与理解. 目前Redis持久化的方式有两种: RDB 和 AOF. 首先,我们应该明确持久化的数据有什么用,答案是用于重启后的数据恢复. Redis是一个内存数据库,无论是RDB还是AOF,都只是其保证数据恢复的措施. 所以Redis在利用RDB和AOF进行恢复的时候,都会读取RDB或AOF文件,重新加载到内存中.

redis进程OOM被linux内核kill问题调查 - 简书

- -
运维人员收到zabbix告警说codis集群usa-9节点所在机器,原swap 4G 空间只剩下80k. 其立即登录该机器增加了约6G的swap空间. 接着收到某个应用的500错误告警,错误堆栈里提到codis该usa-9节点 “JedisConnectionException: Unexpected end of stream”,再次登录usa-9拿到 linux的系统日志如下:.

Redis 负载监控——redis-monitor

- - ITeye资讯频道
redis-monitor是一个Web可视化的 redis 监控程序. 使用 Flask 来开发的,代码结构非常简单,适合移植到公司内网使用. redis 服务器信息,包括 redis 版本、上线时间、 os 系统信息等等. 实时的消息处理信息,例如处理 command 数量、连接总数量等. 内存占用、 cpu 消耗实时动态图表.

Redis 起步

- - 博客园_首页
Rdis和JQuery一样是纯粹为应用而产生的,这里记录的是在CentOS 5.7上学习入门文章:. Redis是一个key-value存储系统. 和Memcached类似,但是解决了断电后数据完全丢失的情况,而且她支持更多无化的value类型,除了和string外,还支持lists(链表)、sets(集合)和zsets(有序集合)几种数据类型.

redis 配置

- - 谁主沉浮
# 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写). # 内存配置大小写是一样的.比如 1gb 1Gb 1GB 1gB. # daemonize no 默认情况下,redis不是在后台运行的,如果需要在后台运行,把该项的值更改为yes. # 当redis在后台运行的时候,Redis默认会把pid文件放在/var/run/redis.pid,你可以配置到其他地址.

Cassandra代替Redis?

- - Tim[后端技术]
最近用Cassandra的又逐渐多了,除了之前的360案例,在月初的QCon Shanghai 2013 篱笆网也介绍了其使用案例. 而这篇 百万用户时尚分享网站feed系统扩展实践文章则提到了Fashiolista和Instagram从Redis迁移到Cassandra的案例. 考虑到到目前仍然有不少网友在讨论Redis的用法问题,Redis是一个数据库、内存、还是Key value store?以及Redis和memcache在实际场景的抉择问题,因此简单谈下相关区别.

redis 部署

- - CSDN博客云计算推荐文章
一、单机部署 tar xvf redis-2.6.16.tar.gz cd redis-2.6.16 make make PREFIX=/usr/local/redis install  #指定安装目录为/usr/local/redis,默认安装安装到/usr/local/bin. # chkconfig: 2345 80 10       #添加redhat系列操作系统平台,开机启动需求项(运行级别,开机时服务启动顺序、关机时服务关闭顺序) # description:  Starts, stops redis server.

nagios 监控redis

- - C1G军火库
下载check_redis.pl. OK: REDIS 2.6.12 on 192.168.0.130:6379 has 1 databases (db0) with 49801 keys, up 3 days 14 hours - connected_clients is 1, blocked_clients is 0 | connected_clients=1 blocked_clients=0.