Redis 设计与实现:数据库
本文的分析都是基于 Redis 6.0 版本源码
redis 6.0 源码:https://github.com/redis/redis/tree/6.0
服务器中的数据库
Redis 服务器将绝大部分的信息都保存在 server.h/redisServer。redis 的数据是保存在 redisServer 中的 redisDb 结构中。
struct redisServer {
// ...
redisDb *db; // 数据库列表
// ...
int dbnum; // 数据库数量
// ...
}
db中每个redisDb结构代表一个数据库。- 在初始化服务器时,程序会根据服务器状态的
dbnum属性来决定应该创建多少个数据库。 dbnum属性的值由服务器配置的database选项决定,默认情况下,该选项的值为16,所以Redis服务器默认会创建16个数据库。

数据库键空间
Redis 是一个键值对数据库服务器,服务器中的每个数据库都由一个 server.h/redisDb 结构表示.
其中,redisDb 的 dict 字典属性保存了数据库中的所有键值对,我们将这个字典称为键空间(key space):
typedef struct redisDb {
dict *dict;
// ...
} redisDb;
dict 中的数据跟我们平常操作的键值对是一一对应的:
- dict 的 key 就是数据库中的 key,字符串类型
- dict 的 值 就是数据库中的 值,这个值可以是
string、hash、zset、set、list中的任何一种
示例
如果我们在数据库中,执行以下命令:
redis > SET str_key str_value
OK
redis > RPUSH list_key a b c
(integer) 3
新添加的两个 key 的结构如下图所示:

从上面的示例图可以很清晰地知道 Redis 数据是如何组织的,增删改查也就是对 dict 的操作而已,此处就不详细说了。
Key 的过期时间
1. 数据结构
redisDb 中的 expires 属性保存了所有 key 的过期时间,我们姑且就称它为过期字典吧。
- 过期字典中的键,是一个指针,指向了真实数据的
key,不会浪费空间多保存一次 - 过期字典中的值,存的是具体的过期时间点,精确到毫秒的时间戳
typedef struct redisDb {
// ...
// 保存了所有 key 的过期时间
dict *expires;
// ...
} redisDb;
命令TTL、PTTL 都是去查这个过期字典的过期时间,然后减去当前时间,得到的就是剩余的时间啦。
2. 过期 key 的删除策略
一个 key 过期时间到了之后,是如何进行删除的呢?Redis 使用了一下两种策略:惰性删除、定期删除
惰性删除
惰性删除策略指的是:key 在过期之后,没有立即删除,而是在读写 key 的时候,才对过期的 key 进行删除。
代码实现在 db.c/expireIfNeeded 方法中。所有 key 的读写之前,都会先调用 expireIfNeeded 对 key 进行检查,如果已过期,则删除。
定期删除
定期删除策略指的是:Redis 每隔一段时间,随机从数据库中取出一定量的 key 进行检查,如果已过期,则进行删除。
代码实现在 expire.c/activeExpireCycle 方法中。
Redis 设计与实现:数据库的更多相关文章
- 探索Redis设计与实现9:数据库redisDb与键过期删除策略
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- Redis | 第4章 Redis中的数据库《Redis设计与实现》
目录 前言 1. Redis中的数据库 2. 数据库的键空间 3. 键的生成时间与过期时间 4. Redis中的过期键删除策略 5. AOF.RDB和复制功能对过期键的处理 5.1 生成 RDB 文件 ...
- Redis设计与实现2.1:数据库和事件
数据库和事件 这是<Redis设计与实现>系列的文章,系列导航:Redis设计与实现笔记 数据库 数据库的结构定义在 redis.h/redisServer 这个结构体中,这个结构体有许多 ...
- 《Redis设计与实现》- 数据库
1. 服务器中数据库结构 Redis 服务器将所有数据库都保存在服务器状态 redisServer 结构的 db 数组中,由 redisDb 结构代表一个数据库 struct redisServer ...
- Redis设计与实现——单机数据库的实现
数据库 服务器中的数据库 redisClient切换数据库 redis客户端默认目标数据库为0号数据库,可以通过SELECT命令来切换目标数据库. 客户端状态redisClient结构的db属性记录了 ...
- Redis设计与实现(一~五整合版)【搬运】
Redis设计与实现(一~五整合版) by @飘过的小牛 一 前言 项目中用到了redis,但用到的都是最最基本的功能,比如简单的slave机制,数据结构只使用了字符串.但是一直听说redis是一个很 ...
- 《Redis设计与实现》读书笔记
<Redis设计与实现>读书笔记 很喜欢这本书的创作过程,以开源的方式,托管到Git上进行创作: 作者通读了Redis源码,并分享了详细的带注释的源码,让学习Redis的朋友轻松不少: 阅 ...
- 重读redis设计与实现
重读了一遍redis设计与实现,这次收获也不错,把之前还有些疑惑的点:redis跳跃表的原理.redis持久化的方法.redis复制.redis sentinel.redis集群等,都重新熟悉了一遍, ...
- 如何使用redis设计关系数据库
目录 redis设计关系数据库 前言 设计用户信息表结构 hash存储记录 set存储id 图示 索引/查询: 1.select 查询所有记录 : 类似sql的select from table_na ...
- Redis笔记(3)多数据库实现
1.前言 本章介绍redis的三种多服务实现方式,尽可能简单明了总结一下. 2.复制 复制也可以称为主从模式.假设有两个redis服务,一个在127.0.0.1:6379,一个在127.0.0.1:1 ...
随机推荐
- sqli-labs-master less06
第六关与第五关步骤无区别,请参考 sqli-labs-master less05 及 Burp Suite暴力破解示例 区别:在第二步判断注入类型时发现 加单引号与不加单引号没有区别,加双引号时报错, ...
- Kubernetes Ingress-nginx使用
目录 简介 1. 部署Ingress-Controller 2. 使用Ingress规则 2.1 Ingress地址重写 2.2 配置HTTPS 2.3 黑白名单配置 2.4 匹配请求头 2.5 速率 ...
- python学习第五天 ----- 函数
1. 内置函数 例如: print, round 2.自定义函数: 通过def来定义 def funcname(parameter_list): pass ⑴.参数parameter_list可以没有 ...
- JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线
JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...
- 小白也能看懂的mySQL进阶【单表查询】
目录 1.查询基础 SELECT语句基础 列的查询 为列设定别名 常数的查询 过滤表中重复数据 根据WHERE语句来选择记录 注释的书写方法 算术运算符和比较运算符 算术运算符 需要注意NULL 比较 ...
- 小米ICPC第一场自闭记
这次终于找到了靠谱队友,比之前我做不出来==队友做不出来好太多了 昨天3人热身赛疯狂杀了8道题,感觉今天稳了 一开始就瞅了A题,发现似乎可以dp,看了看数据,1e7,大概想出了nsqrtn算法,想着肯 ...
- Python链式赋值执行顺序及执行方式的证明
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 在<关于Python链式赋值的赋值顺序问题& ...
- RedHat操作指令第2篇
六.RPM包管理命令 主要功能 查询RPM软件.包文件的相关信息 安装.升级.卸载RPM软件包 维护RPM数据库信息 查询RPM软件信息 查询已安装的RPM软件信息 格式:rpm -q[子选项] [软 ...
- 小程序image无法显示图片
图片路径中有中文 图片地址为http开头,图片只能在调试模式中显示,真机也必须开调试. 图片名称有空格 图片的后缀必须为小写的.png或者.jpg
- Spring RestTemplate具备负载均衡功能
在创建RestTemplate的Bean时使用@LoadBalanced注解, 就可以自动配置为使用ribbon.如下面的示例所示: @Configuration public class MyCo ...