REdis之maxmemory解读
redis.conf中的maxmemory定义REdis可用最大物理内存,有多种书写方式,以下均为合法:
maxmemory 1048576 maxmemory 1048576B maxmemory 1000KB maxmemory 100MB maxmemory 1GB maxmemory 1000K maxmemory 100M maxmemory 1G |
没有带单位尾巴的为字节数,以B结尾的表示相应的大小。但需要注意KB和K、MB和M、GB和G是不同的,如1K表示1000字节,而1KB则为1024字节。如果maxmemory值为0,表示不做限制。
如果是32位系统,当maxmemory值为0时,redis启动时会记录WARN日志:
Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now. |
并强制将最大内存设置为3GB,同时将内存策略设置为MAXMEMORY_NO_EVICTION(超出maxmemory后,所有写操作失败,读操作成功):
server.maxmemory = 3072LL*(1024*1024); /* 3 GB */ server.maxmemory_policy = MAXMEMORY_NO_EVICTION; |
如果设置的maxmemory小于1MB,则redis启动时记录如下日志:
WARNING: You specified a maxmemory value that is less than 1MB (current value is %llu bytes). Are you sure this is what you really want? |
相关的源代码如下:
/* Convert a string representing an amount of memory into the number of * bytes, so for instance memtoll("1Gb") will return 1073741824 that is * (1024*1024*1024). * * On parsing error, if *err is not NULL, it's set to 1, otherwise it's * set to 0. On error the function return value is 0, regardless of the * fact 'err' is NULL or not. */ long long memtoll(const char *p, int *err) { const char *u; char buf[128]; long mul; /* unit multiplier */ long long val; unsigned int digits;
if (err) *err = 0;
/* Search the first non digit character. */ u = p; if (*u == '-') u++; while(*u && isdigit(*u)) u++; if (*u == '\0' || !strcasecmp(u,"b")) { // 调用strcasecmp不区分大小比较 mul = 1; } else if (!strcasecmp(u,"k")) { mul = 1000; // 不带尾巴B或b的 } else if (!strcasecmp(u,"kb")) { mul = 1024; // 带尾巴B或b的 } else if (!strcasecmp(u,"m")) { mul = 1000*1000; // 不带尾巴B或b的 } else if (!strcasecmp(u,"mb")) { mul = 1024*1024; // 带尾巴B或b的 } else if (!strcasecmp(u,"g")) { mul = 1000L*1000*1000; // 不带尾巴B或b的 } else if (!strcasecmp(u,"gb")) { mul = 1024L*1024*1024; // 带尾巴B或b的 } else { if (err) *err = 1; return 0; }
/* Copy the digits into a buffer, we'll use strtoll() to convert * the digit (without the unit) into a number. */ digits = u-p; if (digits >= sizeof(buf)) { if (err) *err = 1; return 0; } memcpy(buf,p,digits); buf[digits] = '\0';
char *endptr; errno = 0; val = strtoll(buf,&endptr,10); if ((val == 0 && errno == EINVAL) || *endptr != '\0') { if (err) *err = 1; return 0; } return val*mul; }
// 有关REdis内存策略的实现,请参见REdis源码文件evict.c。 |
如果没有禁用config命令,则可用它动态实时修改maxmemory的值,如将maxmemory设置为15GB:
redis-cli -h 192.168.31.8 -p 6379 config set maxmemory 15GB |
如果要查看maxmemory的值,有如下两种方法:
redis-cli -h 192.168.31.8 -p 6379 config get maxmemory 或 redis-cli -h 192.168.31.8 -p 6379 info memory | grep maxmemory |
由于REdis一般占大内存,所以通常需要关闭系统的OOM,方法为将“/proc/sys/vm/overcommit_memory”的值设置为1(通常不建议设置为2),也可以使用命令sysctl设置,如:sysctl vm.overcommit_memory=1,但注意一定要同时修改文件/etc/sysctl.conf,以便得系统重启后仍然生效:
# vi /etc/sysctl.conf vm.overcommit_memory=1 |
修改sysctl.conf后,需要执行“sysctl -p”以使生效。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?