一、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 <bytes> 选项来设置最大可用内存。

但是,如果用户在配置文件开启了 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 个其实是挺多的了,我们连一半都用不到,尴尬尴尬~

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

  1. 【CSS中width、height的默认值】

    对于初学者来说,CSS中的width.height的默认值是很神奇的,因为经常看到如下这样的代码:明明只给一个#father标签(红色的div)设置了一个width,为啥它在浏览器中显示出来是有一个固 ...

  2. Java成员变量默认值

    Java中明确规定:1.如果是引用型的,比如:String,还有类对象,他们的默认值都是:null:2.而如果是值类型:double,int,long,float,char等等,他们都是:0:还有一个 ...

  3. select2 取值 遍历 设置默认值

    select2 取值 遍历 设置默认值 本章内容主要介绍Select2 的初始化,获取选中值,设置默认值,三个方法.Select2 美化了单选框,复选框和下拉框,特别是下拉框多选的问题.但同时,Sel ...

  4. socket tcp缓冲区大小的默认值、最大值

    Author:阿冬哥 Created:2013-4-17 Blog:http://blog.csdn.net/c359719435/ Copyright 2013 阿冬哥 http://blog.cs ...

  5. 【Linux】tcp缓冲区大小的默认值、最大值

    Author:阿冬哥 Created:2013-4-17 Blog:http://blog.csdn.net/c359719435/ Copyright 2013 阿冬哥 http://blog.cs ...

  6. newFixedThreadPool的默认值

    可以点进去,每个的默认值都是不同的

  7. spring 配置文件属性设置默认值以及读取环境变量值

    在 Spring 中为 javabean 注入属性文件中的属性值一般人都知道的,可以通过 org.springframework.beans.factory.config.PropertyPlaceh ...

  8. redis的maxmemory设置以及淘汰策略介绍

    转载地址:http://www.2cto.com/database/201507/420889.html redis的maxmemory参数用于控制redis可使用的最大内存容量.如果超过maxmem ...

  9. Celery-4.1 用户指南: Configuration and defaults (配置和默认值)

    这篇文档描述了可用的配置选项. 如果你使用默认的加载器,你必须创建 celeryconfig.py 模块并且保证它在python路径中. 配置文件示例 以下是配置示例,你可以从这个开始.它包括运行一个 ...

随机推荐

  1. 阿里云ECS(Ubuntu)单节点Kubernetes部署

    参考资料: kubernetes官网英文版 kubernetes官网中文版 前言 这篇文章是比较久之前写的了,无聊翻了下博客发现好几篇博文排版莫名其妙的变了... 于是修改并完善了下.当初刚玩k8s的 ...

  2. vs编译器中不允许使用scanf()的情况

    问题1描述: vs编译器中,不允许使用scanf()函数. error C4996: 'scanf': This function or variable may be unsafe. Conside ...

  3. ArcGIS Server的安装

    1.双击ArcGIS Server安装目录下的Setup.exe. 2.点击“Next”. 3.选择“I accept the license agreement”,点击“Next”. 4.点击“Ch ...

  4. GCDAsyncSocket 笔记

    https://www.dzliving.com/2019/03/26/gcdasyncsocket-%E7%9A%84%E5%B0%81%E8%A3%85%E4%B8%8E%E4%BD%BF%E7% ...

  5. Java 获取 IP

    /** * 获取访问者IP. * 在一般情况下使用 Request.getRemoteAddr() 即可,但是经过 nginx 等反向代理软件后,这个方法会失效. */ private String ...

  6. flask中的表单文件上传

    在表单中上传文件时,一定要加入 enctype="multipart/form-data" 属性 为什么要加入这个属性呢: enctype就是encodetype就是编码类型的意思 ...

  7. 使用RandomString方法后,结果返回相同的随机数解决办法

    所遇问题: 在做超市管理系统的登录项目时,在对“随机数的产生”出现一个问题,在产生多个随机数的时候,出现了产生了多个一样的随机数,具体代码如下: /// <summary> /// 生成随 ...

  8. 字符串学习笔记(一)---- String介绍

    一.String类的特点 1.字符串对象一旦被初始化就不会被改变: (1)常见问题 a public static void main(String[] args) { String a = &quo ...

  9. 查看手机wifi密码

    方法一 手机共享wifi,获得二维码,之后解码获得密码. 二维码解吗工具: https://jiema.wwei.cn/ 方法二 手机扫描wifi共享的二维码后,会有提示信息,其中会显示出密码.

  10. Visual Studio Code 1.44 设置简体中文界面语言(小白图文教程)

    作为一款微软出品的编辑器,安装完毕后,默认界面竟然不是中文!而更“丧心病狂”的是菜单里竟然连“设置”或“设置语言”这种PC软件常见选项也没有!!这种设计对小白而言简直 反!!!人!!!类!!! (默认 ...