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. [nodejs] 同步/异步创建多层目录

    背景 有时项目里需要同时创建多层目录的功能,但低版本的nodejs并没有提供快捷的api 尽管在v10.12.0版本 mkdir() 第二个参数支持recursive 参数,为true时能递归创建,但 ...

  2. numpy+sklearn 手动实现逻辑回归【Python】

    逻辑回归损失函数: from sklearn.datasets import load_iris,make_classification from sklearn.model_selection im ...

  3. Java集合:ArrayList (JDK1.8 源码解读)

    ArrayList ArrayList几乎是每个java开发者最常用也是最熟悉的集合,看到ArrayList这个名字就知道,它必然是以数组方式实现的集合 关注点 说一下ArrayList的几个特点,也 ...

  4. ubuntu server 18.04 网络配置

    从17.10开始放弃在/etc/network/interfaces里固定IP的配置 配置文件是:/etc/netplan/50-cloud-init.yaml .用缩进来表示层级关系 冒号之后要有个 ...

  5. 模糊c-means算法的c++实现

    首先输入点的个数,维度,分类数目 我的代码FCM中主要过程如下: 1:(init_c函数)随机初始化聚类中心 2:(comp_dis函数)计算每个点到每个聚类距离 dis[i][j] 表示i点到j聚类 ...

  6. C++多线程队列实现

    C++多线程队列实现 C++多线程队列学习 介绍 在项目中,进行多线程队列实现是一个比较麻烦的事, 找到了一个实现比较好的多线程队列实现, 自己做了一点修改更加适应自己的项目, 记录下来, 有需要的自 ...

  7. Hard filters (by GATK)

    Filter Symbol T. Definition QualByDepth QD 2.0 The variant confidence (from the QUAL field) divided ...

  8. MySQL根据业务场景归纳常用SQL语句

    素材表数据:user[{"id":1,"name":"x"},{"id":2,"name":&quo ...

  9. 解析HTML、JS与PHP之间的数据传输

    在电商网站搭建过程中,前端经常会向后端请求数据,有时候通过HTML.JS和PHP文件的处理来实现数据的连通.通常情况下,用户在HTML中做关键字操作,JS对提交的表单进行数据处理,向后端发起ajax请 ...

  10. 蘑菇街CEO陈琪上市致辞:科技是生产力 美丽也是生产力

    雷帝网 乐天 12月7日报道 蘑菇街CEO陈琪今日在纽交所上市致辞时表示,蘑菇街的使命是让时尚触手可及,立志成为最领先的时尚目的地,并把"科技是生产力,美丽也是生产力"作为蘑菇街价 ...