Redis 的 maxmemory 和 dbnum 默认值都是多少?对于最大值会有限制吗?

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介:

Redis 的 maxmemory 和 dbnum 默认值都是多少?对于最大值会有限制吗?

一、Redis 的默认配置
了解 Redis 的都知道,Redis 服务器状态有很多可配置的默认值。

例如:数据库数量,最大可用内存,AOF 持久化相关配置和 RDB 持久化相关配置等等。我相信,关于 AOF 持久化和 RDB 持久化的配置大家都很熟悉,但是关于数据库数量和最大可用内存,是不是恰恰很容易被大家忽略?

当 Redis 实例部署在正式环境时,我们可能会根据系统业务或者服务器配置来对 redis.conf 配置文件里的一些选项进行修改。可能此时我们的潜意识都会觉得,大部分东西都是越多越好:数据库数量越多,那么我们就可以一个业务对应一个数据库,再繁杂的业务也不怕不够用;最大可用内存越大,那么我们就可以往 Redis 里存放越多的数据。

那么,数据库数量是不是真的可以无限大,Redis 没做限制么?是不是真的越多越好用?

最大可用内存是不是设置成越大越好?Redis 会不会对此也有限制呢?

下面我们来分析看看。

二、最大可用内存 maxmemory:
1、Redis 源码里的默认最大可用内存:REDIS_DEFAULT_MAXMEMORY
在 redis.h 里我们可以看到最大可用内存 REDIS_DEFAULT_MAXMEMORY 的默认值是0,即最大可用内存默认没有设置最大值。

如果 maxmemory == 0 ,那么不管用户存放多少数据到 Redis 中,Redis 也不会对可用内存进行检查,直到 Redis 实例因内存不足而崩溃也无作为。

但是 Redis 其实不是没有做任何限制,对于 32 位实例,Redis 就做了限制。如果你在 32 位的服务器上部署 Redis 实例,它的最大可用内存将限制在 3 GB。

为什么是 3 GB?

因为 32 位的机器最大只支持 4GB 的内存,而系统本身就需要一定的内存资源来支持运行,所以 32 位机器限制最大 3 GB 的可用内存是非常合理的,这样可以避免因为内存不足而导致 Redis 实例崩溃。

我们可以在 redis.c 里看到 32 位限制 3 GB 的源码:

/* 32 bit instances are limited to 4GB of address space, so if there is

  • no explicit limit in the user provided configuration we set a limit
  • at 3 GB using maxmemory with 'noeviction' policy'. This avoids
  • useless crashes of the Redis instance for out of memory. */
    // 对于 32 位实例来说,默认将最大可用内存限制在 3 GB

if (server.arch_bits == 32 && server.maxmemory == 0) {

redisLog(REDIS_WARNING,"Warning: 32 bit instance detected but no memory limit set. Setting 3 GB maxmemory limit with 'noeviction' policy now.");
server.maxmemory = 3072LL*(1024*1024); /* 3 GB */
server.maxmemory_policy = REDIS_MAXMEMORY_NO_EVICTION;

}
2、Redis 配置文件的最大可用内存选项:maxmemory
当然了,用户可以通过 redis.conf 配置文件的 maxmemory  选项来设置最大可用内存。

但是,如果用户在配置文件开启了 maxmemory 选项,那么 Redis 会限制这个值不能小于 1M。

/ Warning the user about suspicious maxmemory setting. /
// 检查不正常的 maxmemory 配置
if (server.maxmemory > 0 && server.maxmemory < 1024*1024) {

redisLog(REDIS_WARNING,"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?", server.maxmemory);

}
此时,我们都知道:

对于最大可用内存的最大限制:只有对 32位 实例才会限制在 3 GB,对于 64 位实例是完全没有限制的。
对于最大可用内存的最小限制:当用户开启了 redis.conf 配置文件的 maxmemory 选项,那么 Redis 将限制选项的值不能小于 1 MB 。
3、最大可用内存该如何设置?
当然是越大越好了,但是前提我们要考虑一下服务器会用来做什么。

假如我们的机器只用来部署一个 Redis 实例,那么大概留个 1 GB 的内存资源来支撑系统本身的运行即可。

但是如果我们部署多个 Redis 实例,或者还要部署其他系统,那么就要好好计算一翻了;如果设置的最大可用内存过大了,就会导致 Redis 实例因为内存不足而崩溃了。

三、数据库数量 dbnum:
1、Redis 源码里的默认数据库数量:REDIS_DEFAULT_DBNUM
在 redis.h 里我们可以看到 Redis 默认的数据库数量 REDIS_DEFAULT_DBNUM 为16。

2、Redis 配置文件的数据库数量选项:databases
用户可以通过 redis.conf 配置文件的 databases 选项来设置数据库数量。

3、redis 是否会限制数据库数量的大小?
1)在初始化服务器状态(redisServer)时,直接读取默认值 REDIS_DEFAULT_DBNUM。

2)在读取配置文件时,读取 databases 配置项,并做下一步判断。

rewriteConfigNumericalOption(state,"databases",server.dbnum,REDIS_DEFAULT_DBNUM);

server.dbnum = atoi(argv[1]);
if (server.dbnum < 1) {

err = "Invalid number of databases"; goto loaderr;

}
到此我们都知道:

Redis 不会限制 dbnum 的最大值。
但是会限制 dbnum 的最小值为 1。
4、数据库数量是不是越多越好?
Redis 数据库的数量无非就是想对应不同业务的数量,一个业务对应一个数据库,清晰明了;但是如果数据库数量太多,却可能会导致一些用户不易发现的问题!

例如删除过期键的 activeExpireCycle 函数中,就会对数据库数量有限制了:

一般情况下,函数只处理 REDIS_DBCORN_DBS_CALL 个数据库(即16个数据库)的过期键,除非上一次处理过期键遇到了时间限制,才会对所有数据库进行扫描;这其实就和 Redis 默认就是 16个数据库是一一对应的。

然后程序接着从数据库 0 - 15,一一遍历处理过期键:

/* We usually should test REDIS_DBCRON_DBS_PER_CALL per iteration, with

  • two exceptions:
  • 一般情况下,函数只处理 REDIS_DBCRON_DBS_PER_CALL 个数据库
  • 除非:
    *
  • 1) Don't test more DBs than we have.
  • 当前数据库的数量小于 REDIS_DBCRON_DBS_PER_CALL
  • 2) If last time we hit the time limit, we want to scan all DBs
  • in this iteration, as there is work to do in some DB and we don't want
  • expired keys to use memory for too much time.
  • 如果上次处理遇到了时间上限,那么这次需要对所有数据库进行扫描,
  • 这可以避免过多的过期键占用空间
    */

if (dbs_per_call > server.dbnum || timelimit_exit)

dbs_per_call = server.dbnum;

//.....

// 遍历数据库
for (j = 0; j < dbs_per_call; j++) {

int expired;
// 指向要处理的数据库
redisDb *db = server.db+(current_db % server.dbnum);
// ....

那么存在一种情况:

如果用户设置了 databases 20,而正常情况下,只有数据库 0 -15 这 16 个数据库的过期键得到定期删除策略的删除,而数据库 16 -19 这几个数据库不能通过定期删除策略删除掉过期键;只能等待惰性删除策略:即当数据库键被访问时才判断此键是否过期,过期了才删除此键。但是如果这些库的过期键很长一段时间都不被访问,那么会导致浪费不少宝贵的内存空间。

最后关于数据库数量的建议:

当然了,既然 Redis 将默认的数据库数量设置为 16,那么很多地方应该都会用到此来对数据库数量做一些限制,所以,我们正常情况下,尽量不要修改 Redis 的数据库数量;而且,我自己感觉 16 个其实是挺多的了,我们连一半都用不到,尴尬尴尬~ 😂

原文地址https://www.cnblogs.com/Howinfun/p/12787955.html

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
移动开发 NoSQL Redis
阿里云Redis lua命令支持及相关限制说明
介绍阿里云Redis对lua命令的支持
11353 1
|
5月前
|
缓存 NoSQL Redis
Redis性能优化问题之当Redis内存达到maxmemory后,淘汰数据的逻辑是怎样的
Redis性能优化问题之当Redis内存达到maxmemory后,淘汰数据的逻辑是怎样的
|
7月前
|
缓存 NoSQL 中间件
redis内存溢出报错--OOM command not allowed when used memory > 'maxmemory'
该内容是关于Redis缓存服务器的使用指南。通过Xshell连接IP地址为25.218.153.193或206的主机,进入/data/iuap/middleware/redis-30001/bin目录,使用`redis-cli`连接到IP为206的30003端口。登录时需`auth yonyou*123`,可运行`info`和`info memory`查看状态,`flushall`清理缓存。在清理前,要备份/data/iuap/middleware/redis-30003/data/下的.aof和.rdb文件,利用tar命令打包并移至/tmp目录。
|
存储 SQL 缓存
SpringBoot集成Redis业务功能 01、限制玩家积分的每日重置次数
SpringBoot集成Redis业务功能 01、限制玩家积分的每日重置次数
SpringBoot集成Redis业务功能 01、限制玩家积分的每日重置次数
|
数据采集 NoSQL 搜索推荐
Redis应用之限制访问频率
我们知道当网站的访问量突然很大的时候肯定会对服务器造成影响,甚至无法访问,如果是正常的访问那么很好说明业务量增大可以考虑系统的扩展,但是如果是搜索引擎爬虫频繁访问或是一些恶意访问,那这时候我们就应该限制这些访问的访问次数。redis刚好可以解决这个问题
Redis应用之限制访问频率
|
NoSQL Java API
通过REDIS实现限制API调用次数
通过REDIS实现限制API调用次数
756 0
|
存储 NoSQL 关系型数据库
Redis实战之限制操作频率
最近沉迷于业务开发无法自拔 ,有一段时间没有更新博文了,后续博文内容计划把一些业务场景下的实战方案,或者比较好的设计思路进行分享,就不像之前围绕着一个主题,消耗很多的时间去整理相关内容(憋大招),后续可能一篇的内容量就没那么丰富,但是尽可能针对一个点进行更细化,或者更深入的分析,通过不断分享和自我...
857 0
|
存储 NoSQL 网络协议
全内存的redis用习惯了?那能突破内存限制类redis产品ssdb呢?
原文:全内存的redis用习惯了?那能突破内存限制类redis产品ssdb呢?              首先说一下背景,在双十一的时候,我们系统接受X宝的订单推送,同事原先的实现方式是使用redis的List作为推送数据的承载,在非大促的场景下, 一切运行正常,内存占用大概3-4G,机器是16G内存。
1006 0