写点什么

Redis 学习笔记 09:数据库

发布于: 2021 年 01 月 21 日
Redis 学习笔记 09:数据库

我是架构精进之路,点击上方“关注”,坚持每天为你分享技术干货,私信我回复“01”,送你一份程序员成长进阶大礼包。


一、数据库简介

1、Redis 服务器

struct redisServer{	... ...	redisDb *db;//数组,保存服务器中的所有数据库	int dbnum;//服务器数据库的数量	... ...}
复制代码

每个客户端都有自己的目标数据库,所以需要有一个目标数据库,默认为 0 号数据库,客户端通过 SELECT 命令切换。

struct redisClient{	... ...	redisDb *db;//客户端当前正在使用的数据库	... ...}
复制代码

2、redisDb

struct redisDb{	... ...    dict *dict;//数据库键空间,保存数据库中所有的键值对,被称为键空间(key space)    dict *expires;//过期时间	... ...}
复制代码

键空间和用户所见的数据库是对应的

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

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

该图展示了一个拥有 3 个键的数据库,这三个键分别是列表键、哈希键和字符串键。



3、一些基础操作

因为键空间是一个字典,所以所有针对数据库的操作,都是在通过对键空间字典进行操作来实现的,包括添加、删除、更新、取值等。

还有一些针对数据库本身的命令,比如 FLUSHDB(清空整个数据库)、DBSIZE(数据库键数量)等。

4、额外维护

读取一个键时

  •  维护键空间命中(hit)和不命中(miss)次数读操作和写操作都要对键进行读取在 INFO stats 中的 keyspace_hits 和 keyspace_misses 中查看

  • 更新键的 LRU,最后一次使用时间用于计算键的限制时间

  • 删除过期键

更新一个键时

  • 维护脏键计数器(对其+1)触发服务器的持久化及复制操作

  • 发送相应的数据库通知在服务器开启了数据库通知功能时

二、键的生存

1、生存时间/过期时间

客户端可以(通过 EXPIRE/PEXPIRE)设置某个键的生存时间(time to live, TTL), 服务器会自动删除生存时间为 0 的键

  • SETEX 可以在设置字符串键的同事为其设置过期时间,仅用于字符串键,单原理与上述命令一致

  • 强调能活多久

客户端可以(通过 EXPIREAT/PEXPIREAT)设置某个键的过期时间(UNIX 时间戳), 当这个时间来临时,服务器会自动删除这个键

  • 强调活到啥时候

在这个键的生存过程中,可以通过命令查看这个键距离自动删除还有多久

虽然这里一共提到了 4 个命令,但是实际上 Redis 底层只实现了 PEXPIREAT,其他命令都是通过调用该命令实现的

其他一些相关命令:

  • PERSIST:解除键和过期时间在过期字典中的关系

  • TTL/PTTL:TTL 返回这个键还能生存的时间(秒级别)、PTTL 毫秒级别,底层都是用的 PTTL

2、判断是否过期


3、删除策略

定时删除:设置一个定时器,在过期时间来临时,立即删除

  • 内存友好,CPU 不友好

  • 定时器的实现:时间事件,较为低效

惰性删除:只有从键空间获取键时,判断其是否过期,若过期则删除

  • CPU 友好,内存不友好

定期删除:每隔一段时间服务器对数据库进行检查

  • 可通过限制删除操作执行的时长和频率来控制其对 CPU 的影响

  • 有效减少了因为过期键导致的内存浪费

4、Redis 采用的删除策略

惰性删除+定期删除

惰性实现

  • expireIfNeeded,作为一个过滤器,在命令真正执行之前,过滤掉过期的输入键

  • 所有命令需要考虑键存在和不存在两种情况

定期实现

  • 通过 serverCron 执行 activeExpireCycle 函数,这个函数是在规定时间内,分多次遍历服务器中的各个数据库,从 expires 字典中随机检查一部分键的过期时间并删除其中已经过期的。

5、持久化与过期键

Redis 是内存数据库,它将数据状态存储在内存里面,但是如果数据不保存在磁盘里面,一旦服务器进程退出,服务器中的数据库状态也会消失

5.1 Redis 持久化

RDB:将 Redis 在内存中的数据库状态保存在磁盘里,避免数据意外丢失

AOF:通过保存 Redis 服务器所执行的写命令来记录数据库状态的

5.2 RDB 持久化与过期键

生成 RDB 文件时

  • 程序会对数据库中的键进行检查,已过期的不会被保存到新的 RDB 文件中,所以已过期的键不会对 RDB 文件造成影响

载入 RDB 文件时

  • 作为主服务器,过期键不会被载入到服务器中

  • 作为从服务器,文件中所有的键会被载入,但是在主从进行同步时,又会处理掉这一部分

5.3 AOF 持久化与过期键

重写机制:通过保存被执行的写命令来执行数据库状态的,所以随着服务器运行时间的流逝、AOF 文件中的内容会越来越多,文件体积越来越大。为了解决 AOF 文件膨胀的问题,提供了重写功能。

  • 实现方式简述:通过读取数据库中键现在的值,然后用一条命令去记录键值对,以此来替代之前记录这个键值对的多条命令

AOF 文写入

  • 只有当过期键被删除时,程序会向 AOF 文件追加一条 Del 命令

AOF 文件重写

  • 在执行重写时,程序会对数据库中的键进行检查,已过期的键不会被保存到重写后的文件中

5.4 (主从服务器)复制

从服务器的过期键删除动作由服务器控制,目的是保持主从一致。

  • 主服务器在对过期键进行删除的时候,会对所有从服务器发送一个 del 命令,从服务器之后接到这个名利之后才会删除

  • 从服务器在执行读命令时,碰到过期键也会像处理未过期键一样返回

6、数据库通知

让客户端通过订阅给定的频道或模式,获知数据库中键的变化以及命令的执行情况。

  • 键空间通知(key-space notification): 某个键执行了什么命令

  • 键事件通知(key-event notification): 某个命令被什么键执行了


- END -


作者:架构精进之路,专注软件架构研究,技术学习与个人成长,关注并私信我回复“01”,送你一份程序员成长进阶大礼包。



Thanks for reading!


发布于: 2021 年 01 月 21 日阅读数: 20
用户头像

坚持分享接地气儿的架构技术文章! 2018.02.26 加入

同名微信公众号「架构精进之路」,专注软件架构研究,技术学习与职业成长!坚持原创总结、沉淀和分享,希望能带给大家一些引导和启发,感谢各位的支持(关注、点赞、分享)!

评论

发布
暂无评论
Redis 学习笔记 09:数据库