Redis之数据库实现

本文主要介绍Redis服务器数据库的设计与实现,说明保存数据库的方法,保存键值对的方法,以及针对数据库添加、删除、查找、更新操作的实现方法,并且还会说明对过期键的处理方式。

I、服务器中的数据库

Redis服务器将所有的数据库都保持在redisServer结构的db数组中,每个db数组都是一个redisDb结构,每个redisDb都表示一个数据库:

II、切换数据库

客户端可以通过SELECT命令来切换目标数据库。

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

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

通过修改redisClient.db指针,让它指向服务器中的不同数据库,从而实现切换数据库的功能,这就是SELECT命令的实现原理。

III、数据库键空间

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

typedef struct redisDb {
    //数据库键空间,保存所有键值对
    dict *dict;
} redisDb;

数据库的键空间是一个字典,所有对数据库的操作,都是以字典操作来实现的,如数据库的添加、删除、更新、取值等。

IV、设置键的生存时间或过期时间

4.1 设置过期键命令

通过EXPIRE命令或PEXPIRE命令,客户端可以以秒或毫秒为单位为数据库中的某个键设置生存时间(TTL,Time To Live)。

客户端还可以通过EXPIREAT命令或PEXPIREAT命令,以秒或毫秒为单位设置过期时间,这个过期时间是一个UNIX时间戳。

TTL命令和PTTL命令接受一个带有生存时间或过期时间的键,返回这个键的剩余生存时间。

4.2 保存过期时间

redisDb结构的expires字典保存了数据库中所有键的过期时间,称这个字典为过期字典

typedef struct redisDb {
    //过期字典,保存着键的过期时间
    dict *expires;
} redisDb;

下图展示了这个结构:

4.3 移除过期时间

PERSIST命令可以移除一个键的过期时间,其是PEXPIREAT命令的反操作。

V、过期键删除策略

5.1 三种基本删除策略

1、定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键过期时间到达时,执行对键的删除操作。

定时删除策略对内存是最友好的,因为其可以保证过期键尽可能快的被删除,并释放过期键所占内存。

但其对CPU时间是不友好的, 在过期键比较多的情况下,删除过期键这一行为可能会占用相当一部分CPU时间。如果有当量的命令请求等待服务器处理,那么服务器应该优先将CPU时间处理客户端请求,而不是在删除过期键上面。

2、惰性删除:放任过期键不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期则删除,如果不过期,则返回该键。

与上面的分析类似,惰性删除策略对CPU时间来说是最友好的,但对内存是不友好的

3、定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,都是由算法决定的。

定期删除策略是前面两种删除策略的整合和折中
每隔一段时间执行一次删除操作,并限制删除操作的时长和频率,以减少删除操作对CPU时间的影响。
通过定期删除有效减少了因为过期键而带来的内存浪费。

5.2 Redis的过期键删除策略

Redis服务器采用惰性删除和定期删除两种策略,通过配合使用这两种删除策略,可以很好的在合理使用CPU时间和避免内存浪费之间取得平衡。

VI、AOF,RDB和复制功能对过期键的处理

RDB持久化、AOF持久化以及复制功能是如何处理数据库中的过期键的?

6.1 生成RDB文件

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

6.2 载入RDB文件

如果服务器开启了RDB功能,则服务器将对RDB文件进行载入:
· 如果服务器以主服务器模式运行,那么在载入RDB文件时,程序会对文件中保存的键进行检查,未过期的键会被载入到数据库中,而过期键会被忽略。
所以过期键对载入RDB文件的主服务器不会造成影响。

· 如果服务器以从服务器模式运行,那么在载入RDB文件时,文件中保存的所有键不论是否过期,都会被载入到数据库中,但是因为主从服务器在进行数据同步的时候,从服务器就会重新更新为与主服务器一致,而这时也会删除过期键
因此,过期键对载入RDB文件的从服务器也不会造成影响。

6.3 AOF文件写入

当服务器以AOF持久化模式运行时,如果数据库中的某个键已经过期,还没有被惰性删除或定期删除,则AOF文件不会因为这个过期键而产生任何影响,这是因为当过期键被惰性删除或定期删除之后,程序会向AOF文件追加一条DEL命令

6.4 AOF重写

在执行AOF重写的过程中,程序会对数据库中的键进行检查,已过期的键不会被重写到AOF文件中。

6.5 复制

当服务器运行在复制模式下,从服务器的过期键删除动作由主服务器控制
· 主服务器在删除一个过期键之后,会显式的向所有从服务器发送一个DEL命令;
· 从服务器在执行客户端发送的读命令时,即使碰到过期键也不会将过期键删除,而是正常返回;
· 从服务器只有在接到主服务器发来的DEL命令之后,才会删除过期键;

通过由主服务器来控制从服务器统一的删除过期键,可以保证主从服务器数据的一致性

例如,有下图的主从服务器结构:

当客户端向从服务器发送GET message时,从服务器正常返回过期键:

当有客户端向主服务器发送GET message时,主服务器发现message过期,会删除message键,向客户端返回nil,并向从服务器发送DEL message

最后的主从服务器结构为:

【参考】
[1] 《Redis设计与实现》

欢迎转载,转载请注明出处wenmingxing Redis之数据库实现

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351