深入浅析Redis—单机数据库的实现

本文深入探讨Redis数据库的实现,包括RDB和AOF持久化机制,以及过期键的惰性删除和定期删除策略。在RDB持久化中,SAVE和BGSAVE用于创建快照,而在AOF持久化中,记录了所有写操作,通过文件写入和AOF重写保持数据一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

第 9 章:数据库

第 10 章:RDB持久化

第 11 章:AOF持久化


第 9 章:数据库

数据库数组:

  • 初始化为16个数据库,可以通过select命令更改当前数据库

  • 常用命令:FLUSHDB 删除当前数据库所有键值对、RANDOMKEY 返回一个随机的键、DBSIZE 返回键空间包含的键值对的数量、RENAME 重命名

键空间:

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

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

expires字典:

  • 过期字典的键是一个指针,这个指针指向键空间中的某个键对象(也即是某个数据库键)。

  • 过期字典的值是一个long long类型的整数,这个整数保存了键所指向的数据库键的过期时间——一个毫秒精度的 UNIX时间戳(expire、pexpire、expireat命令的时间都会转换成pexpireat)

  • 常见命令:

    • EXPIRE PEXPIRE 设置键的生存时间 单位秒/微秒;

    • EXPIREAT PEXPIREAT 设置键的过期时间 单位秒/微秒

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

    • PERSISIT 移除一个键的过期时间

过期键删除策略:

  • 定时删除(内存最友好,CPU最不友好):在设置键的过期时间的同时,创建一个定时器(timer ),让定时器在键的过期时间来临时,立即执行对键的删除操作。

  • 惰性删除(CPU最友好,内存最不友好):放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。

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

  • 在这三种策略中,第一种和第三种为主动删除策略,而第二种则为被动删除策略。

Redis中配合使用惰性和定期删除策略

惰性删除策略的实现:

  • 过期键的惰性删除策略由db.c/expireIfNeeded函数实现,所有读写数据库的Redis命令在执行之前都会调用expireIfNeeded函数对输入键进行检查:

    • 如果输人键已经过期,那么expireIfNeeded函数将输入键从数据库中删除。

    • 如果输人键未过期,那么expireIfNeeded 函数不做动作。

定期删除策略的实现:

  • 过期键的定期删除策略由redis.c/activeExpireCycle函数实现,每当Redis的服务器周期性操作redis.c/serverCron函数执行时,activeExpireCycle函数被调用,它在规定的时间内,分多次遍历服务器中的各个数据库,从数据库的expires字典中随机检查一部分键的过期时间,并删除其中的过期键。

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

RDB:

  • 在启动Redis服务器时,如果服务器开启了RDB功能,那么服务器将对RDB文件进行载入:

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

    • 如果服务器以从服务器模式运行,那么在载人RDB文件时,文件中保存的所有键不论是否过期,都会被载入到数据库中。不过,因为主从服务器在进行数据同步的时候,从服务器的数据库就会被清空,所以一般来讲,过期键对载入RDB文件的从服务器也不会造成影响。

第 10 章:RDB持久化

创建:

###

  • SAVE:会阻塞Redis服务器进程,知道RDB文件创建完毕,在创建期间Reids服务器不能接受任何请求;

  • BGSAVE:

    • BGSAVE会派生出一个子进程然后由子进程负责创建RDB文件;

    • 在BGSAVE执行的时候,不允许再执行SAVE、BGSAVE等指令;

  • 自动BGSAVE:

    • serverCron函数默认每个100ms执行一次,该函数会对正在运行的服务器进行维护,它的其中一项工作就是坚持server选项所设置的保存条件是否已经满足,满足就会自行BGSAVE;

    • 使用dirty属性记录自上次save之后数据库中数据的修改次数,lastsave记录上次成功执行save命令的时间

载入:

  • 会在Redis服务器启动时自动执行,如果检测到RDB文件存在,就会自动载入;

  • 并且如果开启了AOF持久化,会优先使用AOF来还原数据库

第 11 章:AOF持久化

AOF实现原理:

  • 文件写入:

    • Redis的服务器进程就是一个事件循环( loop),这个循环中的文件事件负责接收客户端的命令请求,以及向客户端发送命令回复,而时间事件则负责执行像serverCron函数这样需要定时运行的函数。

    • 因为服务器在处理文件事件时可能会执行写命令,使得一些内容被追加到aof_buf缓冲区里面,所以在服务器每次结束一个事件循环之前,它都会调用flushAppendOnlyFile函数,考虑是否需要将aof_buf缓冲区中的内容写入和保存到AOF 文件里面,这个过程可以用以下伪代码表示:

AOF重写:

  • 将多个命令整合进一个命令

  • BGREWRITEAOF:为了解决由子进程执行重写导致的数据库状态不一致情况,设置了一个AOF重写缓冲区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值