删除策略

  1. 定时删除
    • 操作:使用定时器,定时执行删除操作
    • 优点:节省内存
    • 缺点:数据量大的时候执行效率很慢,影响程序性能
  2. 惰性删除
    • 操作:访问时判断是否过期,过期删除
    • 优点:性能好
    • 缺点:内存会堆积大量数据
  3. 定期删除
    • 难以把控定期的时长和频率,容易造成定时删除和惰性删除的双缺点

redis中的删除策略

redis中的删除策略由定期和惰性删除组成
注意:定期删除,会在指定周期遍历数据库随机检查一部分过期键然后删除

持久化

redis中的操作都是基于内存的,所以服务器重启之后内存中的数据就会消失,为了避免该问题的发生,redis使用了两种持久化机制将数据刷到磁盘中

RDB持久化

操作对象:数据压缩后的二进制文件

操作命令:SAVE/BGSAVE

SAVE:阻塞服务器进程,在RDB文件创建完之前服务器不能处理任何命令请求

BGSAVE:fork出子进程创建RDB文件,父进程处理其他命令和SAVE命令互斥
工作节点:服务器启动时会将RDB文件载入

文件结构:REDIS|db_version|databases|EOF|check_sum

REDIS:文件头

db_version:RDB文件版本号

databases:SELECTDB|db_number|key_value_pairs

key_value_pairs:TYPE|key|value

EOF:正文结束标识符

check_sum:校验和,载入开始时计算一个值,结束后计算一个值,以此判断文件是否完整

触发机制

  1. 手动执行报告save命令
  2. redis.conf配置 save m n 表示在m秒内存在n次修改时触发bgsave
  3. 从节点执行全量复制时也会触发bgsave
  4. 使用debug reload命令重新加载redis时
  5. 执行shutdown并且没有开启AOF持久化时

优缺点

优点

  1. 是紧凑压缩的二进制文件,非常适合备份和全量复制等场景
  2. Redis加载RDB文件远快于AOF

AOF持久化

操作对象:redis服务器执行的写命令
实现步骤:每执行一条命令则追加到aof_buf中然后将aof_buf中的数据写入AOF文件中,并同步到磁盘
工作节点:服务器启动是创建一个伪客户端,然后依次执行AOF中的每一条命令

AOF重写

Q1:为什么要有重写?

A1:对一个key进行频繁的写操作会在AOF中存储大量的重复key和已过期key,为了解决这个问题衍生出的AOF重写

Q2:重写实现原理?

A2:fork一个子进程->创建新的AOF文件,读取键值并插入新的AOF文件中

Q3:重写期间万一还有新的键值生成,怎么处理aof和数据库中文件的一致性?

A3:为了防止此类问题的发生,redis创建了一个叫做rewrite_buf(重写子进程),在完成重写之后,会向父进程发送一个信号(在此期间服务器进程会阻塞),
父进程收到信号之后会调用一个信号函数该函数将rewrite_buf中的内容写入新的aof,并对其改名然后原子的覆盖现有AOF中的文件

Q4:AOF重写和bgsave命令可以同步执行吗?

A4:不可以的,如果执行AOF重写时,正在执行bgsave那么等bgsave执行完之后,才会执行AOF重写操作

AOF重写触发机制

  1. 手动触发:直接调用不过bgrewriteaof
  2. 配置 auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数

注意

        fork是一个重量级操作,因为fork操作会复制父进程的空间内存表,如果fork操作执行耗时在秒级将会拖慢Redis几万条命令的执行;
所以在线上环境应该严格控制每个redis实例的可用内存,并且降低fork的操作频率;同时子进程也是极其消耗cpu的,在线上环境尽量保证同一时刻只有一个子进程在执行重写操作。