针对Redis数据库实现,主要包括RedisDB的存储结构,以及通知功能和RDB持久化功能 + AOF持久化功能。另外还包括一些独立功能模块的实现 + 发布订阅模式redis

设置键的过期策略:

  • 定时删除:如果一个键设置了过期时间,那么就为其创建一个定时器,在定时器结束后,立刻对该键执行删除操作
  • 惰性删除:在访问该键时,判断其过期时间是否达到了,如果已经过期的话,那么执行删除操作
  • 定期删除:每隔一段时间,对数据库中的键进行一次遍历,删除其中的过期键

其中,定时删除即使删除过期键,但是它为每个键都设置过期时间,使得CPU负载变高,导致服务器的响应时间和吞吐量受到影响;惰性删除虽然不用为每个键设置定时器,但是如果一个键长时间没有被访问的话,那么实际上并没有删除,这样会造成大量过期键占用内存;定时删除算是一种折中的实现,每隔一段时间对数据库进行遍历,从而删除其中的过期键(在服务器中具体通过serverCron来执行,一般是每100ms调用一次)

  • 调用惰性删除的具体过程:
    • 首先检查key是否已经过期,如果已经过期直接将其删除
    • 删除命令写入到AOF文件及其附属节点(因为涉及到主从复制和AOC持久化)
    • 返回0代表键没有过期,返回1代表过期

Redis的持久化功能

对于Redis而言,其作为一款高效的数据库类型,所有的数据实际上都是存储在内存中的,这种模式的缺点在于一旦服务器关闭那么所有的数据都会掉电丢失。Redis为了解决该问题,提供了两种持久化的机制:RDB以及AOF两种方式。将内存中的数据保存到磁盘文件中,随后等到服务器下次开启时重载数据

RDB快照形式实现持久化

  • RDB有俩命令用于数据存储:SAVE和BGSAVE
    • SAVE:

首先回创建一个临时文件,然后再初始化IO,并通过RIO将数据写入到临时文件中。如果写入成功,则对临时文件改名并覆盖先前的文件;
RIO函数实际上就是进行数据写入的,负责要设置校验和、Redis文件标识和版本号,并写系统相关信息。之后遍历所有的数据库,写入当前数据类型、数据库编号还有数据库大小、过期键个数等等。再数据写入完成后,还需要加入结束符以及CRC64位的校验和

  • BGSAVE:

Bgsave命令是直接开一个进程,然后通过该进程执行数据存储过程,是属于后台存储过程。如果此时后台正在进行RDB存储,那么直接返回错误;如果后台在进行AOF存储,则将rdb_bgasve_scheduled参数设置为1,标识此时正在进行AOF持久化。然后在系统中添加一个日程计划,使得服务器定期检查该参数情况判断是否还在执行AOF持久化,随后再执行BGSAVE。
对于BGsave而言,当前进程进行数据存储过程,会先fork一个子进程并在子进程中执行操作,之后父进程保版本以及内存使用等信息。

  • RDB总结:RDB对redis对外提供的读写服务,影响非常小,可以让redis保持高性能,因为redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可;相对于AOF持久化机制来说,直接基于RDB数据文件来重启和恢复redis进程,更加快速;

AOF实现

  • AOF的fsync策略:

    • always : 每次写入一条命令,立刻将这个数据写入到磁盘涨,性能很低
    • everysec: 每秒将操作系统缓存中的数据刷到磁盘中,一般在生产环境中使用
    • no : 仅仅redis负责将数据写入到缓存中就不再管理,后续时操作系统自行刷盘
  • AOF的优势在于:

    1. AOF每隔一秒,通过后台进程执行一次fsync()操作,最多只会丢失一秒的数据
    2. AOF以输入命令的方式进行写入,不需要进行磁盘寻址的操作,写入性能很高
    3. AOF能够实现后台重写操作,创建一份恢复数据的最小日志出来,再创建日志文件时,老的日志文件还是照常写入
    4. AOF适合做灾难性和误删除以及紧急恢复
  • AOF重写的过程:(需要操作AOF缓冲区、以及AOF后台重写缓冲区)

    • redis server需要fork出有一个子进程
    • 子进程基于当前内存的数据,构建日志并开辟一个临时的AOF文件写入日志
    • redis主进程接收到写操作之后,在内存中写入日志,同时新的日志也将继续写入旧的AOF日志中
    • 子进程接完新的日志文件之后,redis主进程将内存中的新日志再次追加到新的AOF文件中
    • 用新的日志文件替换旧的日志文件
    • 何时触发这个重写过程 : 先判断当前AOF文件的大小是否大于执行重写的最小大小,如果大于那么判断器增长系数是否超过了设置,如果超过就执行;病再服务器定期事件中判断AOF后台重写是否完成,如果完成那么AOF后台重写缓冲区写入AOF文件,并覆盖原有的AOF文件;
  • 综合使用AOF以及RDB两种持久化的方式,通过AOF来保证数据不丢失,作为数据恢复的第一选择;通过RDB实现不同程度的冷备,再AOF文件丢失的情况下,使用RDB继续宁快速恢复;