今天学习一下redis的备份机制。redis备份的方式有两种,一种是快照rdb机制,一种是记录所有redis命令的aof机制。RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。
RDB备份:
redis在进行rdb备份的时候会单独fork出来一个子进程,主进程在这次备份没有io操作不影响正常工作,redis会把当前数据写入一个临时文件,然后在备份完成后替换之前的备份文件。rdb备份是一个周期性备份。默认的备份周期是
save 900 1 // 在900s内修改或写入一次,则保存
save 300 10 // 在300s内修改10次则保存
save 60 10000 // 在60s内修改10000次则保存
满足这个条件redis就会进行自动备份,当然这是默认的,你也可以根据需求修改。
RDB 数据恢复
将备份文件(dump.rdb)移动到redis安装目录并启动服务会自动恢复此文件的数据。
Redis服务器在载入RDB文件期间会处于阻塞状态,直到数据恢复完成为止

优势:
不阻塞主进程:生成RDB文件时,redis主进程会fork()一个子进程来处理所有保存工作
恢复数据快:RDB在恢复大数据集时速度比AOF快

劣势:
RDB无法做到实时持久化:在一定时间做一次备份,会丢失间隔时间产生的数据
老版本RDB文件与新版本RDB文件存在不兼容的情况
AOF备份:
开启AOF方式:在redis.conf

appendonly yes

一些配置:
aof_buf:打开AOF开关后每次执行一个写命令,都会把写命令以请求协议格式保存到aof_buf缓冲区
aof_buf写入&同步的时机:
appendfsync always:将aof_buf里的内容写入并同步到AOF文件中。真正实时的把指令存入了磁盘。
appendfsync everysec:上次同步时间距离现在超过1秒时将aof_buf里的内容写入到AOF文件中。
appendfsync no:将aof_buf里的内容写入到AOF文件中,但是不对AOF文件进行同步操作(page_cache,没有真正写入磁盘),写入到磁盘文件的时机由操作系统决定

---------------------------------------------------------分割------------------------------------------------------

默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。
这里再说一下aof重写,
执行AOF重写的时机(redis.conf):
auto-aof-rewrite-percentage 100:表示上次重写后的体量增加了100%后执行AOF重写
auto-aof-rewrite-min-size 64mb:在AOF文件提交超过64MB后执行AOF重写

1.在重写即将开始之际,redis会创建(fork)一个“重写子进程”,进行重写。AOF重写,不是对原AOF文件进行读取,而是直接读取库中的数据,进行重写。用将一个key的多个数据,写成一条命令的方式来减少数据。

2、与此同时,主工作进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。

3、当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中

4、当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中了。

AOF持久化机制的优势
使用 AOF 持久化会让 Redis 变得非常耐久(much more durable):你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。

AOF持久化机制的劣势
对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
在redis4.0更新之后,新增了RDB-AOF混合方式,也一起看一下吧。

开启混合持久化

4.0版本的混合持久化默认关闭的,通过aof-use-rdb-preamble配置参数控制,yes则表示开启,no表示禁用,默认是禁用的,可通过config set修改。

混合持久化备份方式的过程
混合持久化同样也是通过aof备份的方式完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据。

数据恢复
当我们开启了混合持久化时,启动redis依然优先加载aof文件,aof文件加载可能有两种情况如下:

aof文件开头是rdb的格式, 先加载 rdb内容再加载剩余的 aof。

aof文件开头不是rdb的格式,直接以aof格式加载整个文件。

优点:

混合持久化结合了RDB持久化 和 AOF 持久化的优点, 由于绝大部分都是RDB格式,加载速度快,同时结合AOF,增量的数据以AOF方式保存了,数据更少的丢失。

缺点:

兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该aof文件,同时由于前部分是RDB格式,阅读性较差

七、过期策略
redis过期key并不是过期时间一到就会立即删除,redis使用的是定时删除、惰性删除两种策略

1.定期删除

有过期时间的key放在单独的字典中
每100ms随机抽取20个key,删除其中过期的key,如果过期的key超过1/4,则会继续重复上述行为,否则,等待下100ms再随机抽取20key,执行删除
2.惰性删除

获取key时,检查是否过期,若过期立即删除。
八、淘汰策略
有了以上过期策略的说明后,就很容易理解为什么需要淘汰策略了,因为不管是定期采样删除还是惰性删除都不是一种完全精准的删除,就还是会存在key没有被删除掉的场景,所以就需要内存淘汰策略进行补充。

八种淘汰策略:

noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键

allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键

volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键

allkeys-random:加入键的时候如果过限,从所有key随机删除

volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐

volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键

volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键

allkeys-lfu:从所有键中驱逐使用频率最少的键