Redis 服务器将所有的数据库都保存在服务器状态redisServer结构的db数组中,db数组的每个项都是一个redisDB:

struct redisServer{
//一个数组保存着服务器中的所有数据库
redisDb *db;
//数据库的个数
int dbnum;
}

dbnum:服务器初始化时,程序根据dbnum 来决定应创建多少少数据库,由服务器配置的database选项决定,默认16.

在服务器内部,客户端状态redisClient结构的db属性记录了客户端当前目标数据库,这个属性指向redisDb结构的指针:

typedef struct redisClient{
//记录客户端当前正在使用的数据库
redisDb *db;
} redisClient;

redisClient指针指向redisServer 数组的其中一个元素,而被指向的元素就是客户端的目标数据库。

redisBd结构的dict地点保存了数据库中的所有键值对,我们将这个字典称为键空间。

键空间的键也就是数据库的键,每个键都是一个字符串对象。

键空间的值也是数据库的值,每个值可以是字符串对象、列表对象、哈希表对象、集合对象和有序集合对象中的任意一种Redis对象。

Redis命令对数据库进行读写时,服务器不仅对键执行指定的读写操作,还会执行一些额外的维护工作:

1、读取一个键后,服务器会根据键是否存在来更新服务器键空间命中次数或键空间不命中次数。

2、读取一个键之后,服务器会更新键的LRU(最后一次使用时间),这个值用于计算键的空闲时间。

3、如果服务器在读取一个键时发现该键已经过期,那么服务器会先删除这个过期键,然后再执行余下的操作。

4、如果客户端使用Watch命令监视某个键,那么服务器再对被监视的键进行修改后,会将这个键标记为脏,从而让事务程序注意到这个键已经被修改过。

5、服务器每次修改一个键之后,都会对脏键计数器的值加一,这个计数器会触发服务器的持久化以及赋值操作。

6、如果服务器开启了数据库通知功能,那么在对键进行修改后,服务器将按配置发送相应的数据库通知。

设置过期时间

命令 EXPIRE key ttl 设置键生存时间为ttl秒

命令 PEXPIRE  key ttl 设置键生存时间为ttl毫秒

命令EXPIREAT key timestamp 命令 设置键key过期时间为timestamp秒数时间戳

命令 PEXPIREAT key timestamp 设置键key过期时间为timestamp所指定的毫秒时间戳

1、EXPIRE命令可以转换为 PEXPIRE命令

def EXPIRE(key,ttl_in_sec);
ttl_in_ms = sec_to_ms(ttl_in_sec)
PEXPIRE(key,ttl_in_ms)

2、PEXPIRE命令转换为PEXPIREAT命令

def PEXPIRE(key,ttl_in_ms)
now_ms = get_current_unix_timestamp_in_ms();
PEXPIREAT(key,now_ms+ttl_in_ms)

3、EXPIREAT命令转换为PEXPIREAT命令

def EXPIREAT(key,expire_time_in_asc)
expire_time_in_ms = sec_to_ms(expire_time_in_sec)
PEXPIREAT(key,expire_time_in_ms)

redisDB 结构的expires字典保存了数据库所在键的过期时间(过期字典),

1、过期字典的键是一个指针指向键空间的某个键对象。

2、过期字典的值是一个long类型的整数(毫秒精度的UNIX时间戳)。

过期删除策略

1、定时删除,在设置过期时间的同时,创建定时器,到期立即删除(内存友好,CPU不友好)。

2、惰性删除,下一次查询时,查询是否过期,过期删除,(内存不友好,CPU友好)。

3、定期删除,每隔一段时间执行一次。

Redis的删除策略使用了 惰性删除和定期删除两种。

在执行SAVE或者BGSAVE命令生成RDB文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新创建的RDB文件中,因此数据库包含过期键不会对新生成的RDB文件造成影响。

在载入RDB文件时,如果服务器以主服务器模式运行,载入RDB文件时会对键进行检查,未过期的键加载到数据库中,过期键忽略。从服务器模式运行时,文件中保存的所有键被加载,主从同步时,从服务器过期键被清空。

AOF文件写入时,如果过期键未清理,AOF文件不会因为过期键而产生影响,过期键被删除后,程序会向AOF文件追加DEL命令,来显示的记录该键已被删除。

AOF重写时,程序会对数据库中的键检查,已过期的键不会被保存到重写后的AOF文件中。

服务器在复制模式下,服务器的过期键由主服务器控制:主服务器在删除过期键后会向从服务器发送一条DEL命令,从服务在未收到命令前,客户端的读命令会像对未过期键处理方式一样,直到接到DEL命令,从过期键才会删除。


每天学一点,总会有收获。

说明:尊重作者知识产权,文中内容参考《Redis设计与实现》,仅在此做学习与大家分享。

Redis学习笔记(七) 数据库的更多相关文章

  1. Redis学习笔记之数据库(一)

     说句实话,redis这个软件要学习的东西实在多,多到,看的多了就容易迷失,而且还记不住.个人觉得靠记忆去学习一个知识肯定是比较糟糕的,所以还是要带着理解的,最终变成自己的东西,那这个东西才是自己的. ...

  2. StackExchange.Redis学习笔记(三) 数据库及密码配置 GetServer函数

    这一章主要写一些StackExchange.Redis的配置及不太经常用到的函数 数据库连接 下面是我的连接字符串,里面指定了地址,密码,及默认的数据库 Redis启动后默认会分成0-15个数据库,不 ...

  3. Redis学习笔记七:独立功能之排序

    sort 命令可以对列表键.集合键或有序集合键的值进行排序.sort 命令并不修改数据库值,只是输出有序. 127.0.0.1:6379> rpush numbers 9 8 7 6 1 2 3 ...

  4. Redis学习笔记七:主从集群

    单机,单节点,单实例的Redis会有什么问题呢? 容易导致单点故障,那么如何解决呢? 可以通过主备方式 同时可以实现读写分离 这里的每个节点是全量的,镜像的. 单节点的容量有限而且单点的压力比较大,如 ...

  5. Redis学习笔记八:集群模式

    作者:Grey 原文地址:Redis学习笔记八:集群模式 前面提到的Redis学习笔记七:主从复制和哨兵只能解决Redis的单点压力大和单点故障问题,接下来要讲的Redis Cluster模式,主要是 ...

  6. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  7. Redis学习笔记~目录

    回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...

  8. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

  9. Redis学习笔记一:数据结构与对象

    1. String(SDS) Redis使用自定义的一种字符串结构SDS来作为字符串的表示. 127.0.0.1:6379> set name liushijie OK 在如上操作中,name( ...

  10. Redis学习笔记之ABC

    Redis学习笔记之ABC Redis命令速查 官方帮助文档 中文版本1 中文版本2(反应速度比较慢) 基本操作 字符串操作 set key value get key 哈希 HMSET user:1 ...

随机推荐

  1. ATmega328P定时器详解

    写这篇文章,纯粹是想为博客拉点点击量.在博客园,游客访问好像是不计入阅读量的,而作为一个十八线博主,注册用户的访问应该以搜索引擎为主,博客园首页为次,个位数的粉丝就别谈了. 所以,希望各位从搜索引擎点 ...

  2. HTML+CSS教程(五)外联样式、组选择器、圆角边框、样式优先级、伪类、盒子模型、元素溢出

    一.外联样式 通过link标签引入外部css文件夹中的xxx.css文件到head标签中 例: 二. 1.组选择器 选择器名称1,选择器名称2,选择器名称3,…{属性:属性值;属性;属性值} 例: & ...

  3. 取代 Python 多进程!伯克利开源分布式框架 Ray

    Ray 由伯克利开源,是一个用于并行计算和分布式 Python 开发的开源项目.本文将介绍如何使用 Ray 轻松构建可从笔记本电脑扩展到大型集群的应用程序. 并行和分布式计算是现代应用程序的主要内容. ...

  4. MacOs下安装Kong网关

    写在前面: 持续记录一下自己在解决api网关kong上的各种问题. 1.关于Kong网关 这是官网地址:https://konghq.com/ 2.通过brew安装postgres 因为kong的数据 ...

  5. c++使用cin、cout与c中使用scanf、printf进行输入输出的效率问题

    在c++中,我们使用cin和cout进行输入输出会比用scanf和printf更加简洁和方便,但是当程序有大量IO的时候,使用cin和cout进行输入输出会比用scanf和printf更加耗时, 在数 ...

  6. 引入OpenCV导致私有内存巨大

    引入OpenCV导致私有内存巨大 opencvC++VS2015 说明 在调试程序的时候 发现自己的程序在VS的调试窗口占用很高, 花时间关注了一下这个问题, 手动写了小的程序复现这个问题,最终确定了 ...

  7. 自定义fastjson对枚举类型的序列化及反序列化过程

    通常,fastjson在序列化及反序列化枚举时,一般以下几种策略: 1).根据枚举的name值序列化及反序列化(默认) 2).根据枚举的ordinal序列化及反序列化 3).根据枚举的toString ...

  8. Everything 本地磁盘文件搜索工具下载!

    如何运用布尔算子? AND(且)是缺省使用的布尔算子. 例如:如果要搜索 foo 和 bar 同时出现的文件:foo bar 如果从两者之中任一个都可以,则用 | 介于两者之间. 例如:如果要搜索.j ...

  9. #Week4 Logistic Regression

    一.Classification 主要讨论二元分类. 线性回归处理分类问题显然不靠谱,所以采用逻辑回归. 二.Hypothesis Representation 假设函数变为\(h_\theta(x) ...

  10. Codeforce-Ozon Tech Challenge 2020-D. Kuroni and the Celebration(交互题+DFS)

    After getting AC after 13 Time Limit Exceeded verdicts on a geometry problem, Kuroni went to an Ital ...