一、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. nginx代理图片访问

    nginx代理图片访问 首先配置nginx的代理物理路径 我的是在E盘下面的image 1 #图片的代理 2 server { 3 listen 80; 4 #配置访问的域名 5 server_nam ...

  2. Python——Pandas库入门

    一.Pandas库介绍 Pandas是Python第三方库,提供高性能易用数据类型和分析工具 import pandas as pd Pandas基于NumPy实现,常与NumPy和Matplotli ...

  3. 1~n的之间的k个数组成和为n的方案数(动态规划)

    绯色的子弹 Description 众所周知,夏季奥林匹克运动会时隔56年第二次在东京举办,紧接着出来的<名侦探柯南 M24绯色的子弹>竟也是有奥运会的背景,最重要的是重归主线!!!(赤井 ...

  4. CentOS7系统下配置nginx及https安全站点

    本文主要演示在CentOS7系统下OpenSSL的使用方式,以及Nginx在测centOS下的证书配置方式 注意:生成服务器端证书时必须在CN字段中如实输入站点的访问地址 ,如果是域名就写域名,ip访 ...

  5. hello world: 我的博客写作思路

    1. 本人计算机专业,研究生刚毕业,即将入职金融科技领域,决定借博客园平台写自己的博客,原因如下: 从小白到大白,离不开各大学习平台和技术博客的指导和分享,是时候回馈了. 借此机会整理自己从本科.研究 ...

  6. 计算机网络学习笔记NO.2 物理层

    2.1 基本概念 2.1.1 物理层概念 物理层解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体. 物理层主要任务:确定与传输媒体接口有关的一些特性(定义标准) 机械特性:定 ...

  7. 项目踩坑实记 :2019年(SSM 架构)

    1.Bootstarp 相关 JS 结合 Bootstarp 初始化表格后,如果是 Ajax 请求获得返回数据,重新渲染数据到表格的话,用下面的函数. ChanInfTable 是表格的 id. 2. ...

  8. C/C++ 数据精确度的设置

    #include<iostream>#include<iomanip> //此库为代码最后一行快捷设置数据格式需要用的的库 #include<math.h>usin ...

  9. npm install报错:chromedriver@2.27.2 install: node install.js

    报错: 刚开始以为是 node 或 npm 版本问题,前前后后折腾了好久,终于解决了 解决: 如果执行过npm install,先删除 node_modules 文件夹,不然运行的时候可能会报错 执行 ...

  10. app扫描二维码登陆

    先说明一下实现原理: 如同微信扫描登陆一样,就是一种pc的自动登陆授权.在网站首页得有切换登陆的选项:密码登陆 扫码登陆 当用户切换到扫码登陆时,向服务器请求一次获得一个唯一的uukey 利用这个uu ...