Redis - 缓存持久化原理以及数据过期策略

Redis - 缓存持久化原理以及数据过期策略

1.RDB持久化原理

1.1 RDB是什么?

RDB(Redis DataBase)是将Redis指定的时间间隔内将内存中的数据集快照写入磁盘,也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdbRedis在进行数据持久化的过程中,会先将数据写入到一个临时RDB文件中,持久化过程结束后会将这个临时文件替换上次持久化好的文件。通过这种特性我们可以随时来进行备份,因为快照文件总是完整可用的。

1.2 RDB持久化配置

 我们找到redis.conf文件,修改以下配置:

# 时间策略
save 900 1     # 表示900s内有1条写入命令,就触发产生一次快照,可以理解为就进行一次备份
save 300 10    # 表示300s内有10条写入命令,就产生快照
save 60 10000  # 表示60s内有10000条写入命令,就产生快照
# save "" 禁用RDB
# redis servercron 类似于linux的crontab,默认每隔100毫秒执行一次,用于检测上述配置规则是否触发快照备份

# 文件名称
dbfilename dump.rdb

# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes

# 是否压缩
rdbcompression yes

# 导入时是否检查
rdbchecksum yes

# 文件保存路径
dir /usr/local/redis/redis-4.0.6

 修改配置后启动Redis服务,可以看到这里就是加载RDB文件的过程,并且在当前目录下我们可以看到用于持久化的RDB文件。并且在关闭时也会进行RDB持久化操作。
在这里插入图片描述
在这里插入图片描述
 实际生产环境中每个时段的读写请求肯定不是均衡的,为此Redis提供一种根据规定时间内操作次数来触发一次备份到磁盘的操作,这就是上面配置文件中save配置的含义。

1.3 RDB持久化触发方式

 RDB持久化触发方式主要分为两种:

  1. 手动触发:手动触发主要涉及两个命令
     a) save:阻塞当前Redis服务器,直到持久化完成,线上应该禁止使用。
     b) bgsave:该触发方式会fork一个子进程,由子进程负责持久化过程,所以阻塞只会发生在fork子进程而不是阻塞Redis服务。
  2. 自动触发:
     a) 根据save m n配置规则自动触发。
     b) 节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发bgsave。
     c) 执行debug reload时。
     d) 执行shutdown时,若未开启AOF持久化方式也会自动触发。

2.AOF持久化原理

2.1 AOF是什么?

AOF(Append Only File)是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍。

2.2 AOF持久化配置

 同样修改的是redis.conf文件:

# 是否开启aof
appendonly yes

# 文件名称
appendfilename "appendonly.aof"

# 同步方式
appendfsync everysec

# aof重写期间是否同步
no-appendfsync-on-rewrite no

# 重写触发配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 文件重写策略
aof-rewrite-incremental-fsync yes

# 加载aof时如果有错如何处理
aof-load-truncated yes # yes表示如果aof尾部文件出问题,写log记录并继续执行。no表示提示写入等待修复后写入

2.3 AOF同步模式

AOF主要是通过appendfsync配置同步模式,主要有三种:

  1. always:每个时间事件循环都将AOF_BUF缓冲区的所有内容写入到AOF文件,并且同步AOF文件,这是最安全的方式,但磁盘操作和阻塞延迟,是IO开支较大。
  2. everysec:每秒同步一次,性能和安全都比较折中的方式,也是Redis推荐的方式。如果遇到物理服务器故障,有可能导致最近一秒内aof记录丢失(可能为部分丢失)。
  3. no:Redis不直接调用文件同步,而是交给操作系统来处理。操作系统根据buffer填充情况/通道空闲时间等择机触发同步。这是一种普通的文件操作方式,性能较好。在物理服务器故障时,数据丢失量会因OS配置有关。处于no模式下的flushAppendOnlyFile调用无须执行同步操作

2.4 AOF重写

 我们可以发现之前的配置文件中有一个机制相关的配置rewrite,这里关于AOF重写的运行原理我们可以做一个大概的了解。
 在重写即将开始时,Redis会创建(fork)一个重写子进程。这个子进程会读取现有的AOF文件,并将其包含的指令进行分析压缩写入到一个临时文件中。与此同时,主进程会将新接收到的写指令一边添加进内存缓冲区中,一边写入到原有的AOF文件中,这样做可以保证原有的AOF文件的可用性。当重写子进程完成重写工作后,会通过给主进程发送信号让主进程将内存中缓存中写指令追加到新AOF文件中。追加结束后,Redis就会将新AOF文件代替旧AOF文件,之后再有新的写指令重复整个流程。

3.RDB与AOF持久化方案比较以及选择

3.1 RDB与AOF持久化方案比较

 上面我们了解了Redis提供的两种持久化方案:

  1. RDB持久性以指定的时间间隔执行数据集的时间点快照。
  2. AOF持久性记录服务器接收的每个写操作,在服务器启动时再次执行,重建原始数据集。使用与Redis协议本身相同的格式以仅追加方式记录命令。


 既然有两种持久化方案,那我们就来比较一下两种方案的优缺点。
RDB

  1. 优点:
     a) RDB最大限度地提高了Redis的性能,生成RDB文件时父进程只需fork子线程去处理保存工作,父进程不需要参与磁盘I/O。
     b) 恢复大数据集时速度比AOF更快。
     c) RDB是快照文件,数据紧凑体积小。
  2. 缺点:
     a) 由于备份频率低,则服务出现故障时数据丢失的概率更大。
     b) RDB经常需要fork才能使用子进程持久存储在磁盘上。数据集很大时fork可能会非常耗时。

AOF

  1. 优点:
     a) 可自定义配置同步模式,备份频率更高,数据更加安全。默认采用everysec策略,在保持良好性能的同时即使服务故障也只会丢失一秒钟的数据。
     b) AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,可读性更高。
     c) 当AOF文件太大时,Redis能够在后台自动重写。 重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。(例如:INCR 1 执行1万次 => INCRBY 10000 执行一次)
  2. 缺点:
     a) 相同数据集的情况下,AOF文件通常比RDB文件大(RDB备份数据,AOF备份写命令)
     b) 根据不同的fsync策略,AOF可能比RDB慢。默认情况下,每秒fsync性能很高。但是在大量写命令载入时,RDB效率可能更高。

3.2 RDB与AOF持久化方案选择

 我们先看一下Redis故障数据恢复的一个流程。
在这里插入图片描述
 对于RDBAOF如何选择这个问题,其实一般来说若我们需要达到更高的数据安全性,可同时启用两种持久化方式。如果可以能够接收分钟单位级别的数据丢失,则只需启用RDB。另外RDB生成的快照文件也更利于数据备份,恢复效率也更高。
 在真正使用时我们可以采用RDB和AOF持久化同时启用,当然如果我们拥有补回丢失数据的途径可以关闭持久化通过其他方式去重写数据。

4.数据过期清除策略

4.1 Redis提供的三种过期策略

 在我们使用Redis时,很多时候都会给缓存Key设置上Expire过期时间,那么当缓存过期后Redis是否会清理当前Key所占有的内存空间?若不会,那么数据量一直增加之后空间占用过大或者慢了的问题如何解决?若会,那是如何去清理这些过期数据的呢?其实Redis对于过期数据是会进行清除的,它提供了三种过期策略,这里我们详细了解下。

  1. 惰性删除 :Key过期时不进行删除操作,每次获取Key时会先检查是否过期,若已经过期则删除。
     优点:这种方式本质就是不会主动去管理过期Key,当Key过期后下次还有操作对当前Key进行操作再去检查是否过期之后删除。这种方式对CPU十分友好,不会浪费过多的CPU资源去主动处理这些过期数据资源。
     缺点:若一个Key不再使用,这种Key数量变多后则会造成大量的内存浪费甚至内存泄漏。
  2. 定时删除:设置Key过期时间的同时,创建一个定时器(Timer)。定时器会在键过期时间到达时立即对键进行删除。
     优点:内存会及时得到释放。
     缺点:为每一个Key都创建定时器,量多之后严重影响性能。
  3. 定期删除:每隔一段时间对数据库进行一次检查,删除里面的过期Key。至于删除多少过期键以及要检查多少个数据库,则由算法决定。 即设置一个定时任务,比如10分钟删除一次过期的key。间隔小则占用CPU,间隔大则浪费内存。定期删除可通过redis.conf配置文件修改执行周期以及触发界值(hz:默认10,即10次/s ,100ms一次。值越大频率越快消耗性能越大;maxmemory:当内存占用超过该值设定,主动触发清除策略)。
     优点:通过限制删除操作的周期频率,来减少删除操作对CPU的占用。
     缺点:比较折中的方案,内存友好方面不如定时删除,CPU消耗方面不如惰性删除。需合理设置操作周期。
    定期删除处理流程大致如下:
      a) 每秒对随机的20个Key进行过期检测。
      b) 删除所有已经过期的Key。
      c) 若多于25%的Key过期,则重复步奏a。.

4.2 Redis采用的过期策略

Redis服务实际是采用惰性删除定期删除两种策略:通过这两种删除策略配合使用,服务器可以更好地在合理使用CPU和避免内存浪费之间维持平衡。这里大致了解一下这两种过期策略的流程。

  1. 惰性删除流程:在进行getsetnx等操作时,会先检查Key是否过期。若过期则删除Key,然后执行相应操作;若未过期则直接执行相应操作。(实现:通过expireIfNeeded函数,当我们操作key的时候进行判断key是否过期)

  2. 定期删除流程:首先遍历每个Redis数据库(redis.conf中配置的"database"数量,默认为16),然后检查当前库中指定个数Key(默认是每个库检查20个Key)。若当前库中没有任何Key设置过期时间,直接执行下一个库的遍历,若有则随机获取一个设置了过期时间的Key并检查该Key是否过期,如果过期删除当前Key。同时会判断定期删除操作是否已经达到指定时长,若已经达到则直接退出定期删除任务。(实现:通过activeExpireCycle函数,serverCron函数执行时,activeExpireCycle函数就会被调用,规定的时间里面分多次遍历服务器的expires字典随机检查一部分Key的过期时间,并删除其中的过期Key)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章