Redis-持久化

Redis-持久化

文章目录

  • Redis-持久化
    • RDB
      • 简介
      • 触发
      • 缺点
    • AOF
      • 简介
      • 过程
      • 重写触发条件
      • 重写过程
    • RDB-AOF优缺点
      • AOF

redis和memcache的一个区别就在于数据的持久化,因为数据是保存在内存的,一旦重启,数据就会丢失,那么为了增强数据的可靠性,redis实现了数据的持久化,持久化有两种,一直是rdb,一种是aof,redis4.0后开启了两种混用的持久化方式

RDB

简介

RDB持久化是通过快照的形式进行持久化,当符合一定条件

save m n
以save 900 1为例,表明当900秒内至少有一个键发生改变时候,redis触发bgsave操作。

即可即持久化到磁盘

触发

RDB生成快照可自动促发,也可以使用命令手动触发,以下是redis触发执行快照条件,后续会对每个条件详细说明:

  1. 客户端执行命令save和bgsave会生成快照;
  2. 根据配置文件save m n规则进行自动快照;
  3. 主从复制时,从库全量复制同步主库数据,此时主库会执行bgsave命令进行快照;
  4. 客户端执行数据库清空命令FLUSHALL时候,触发快照;
  5. 客户端执行shutdown关闭redis时,触发快照;

save和bgsave的区别:

  • save会造成阻塞,redis在生成快照过程中不会接受其他客户端的请求
  • bgsave不会造成阻塞,后台fork 一个子进程(fork子进程过程中会阻塞)生成快照

Redis-持久化_第1张图片

缺点

  • 可能会损失最后一次的数据

AOF

简介

AOF就是将每次执行redis命令拼接到日志文件,开启AOF持久化会对性能有一定的影响,但是大部分情况下这个影响是可以接受的,我们可以使用读写速率高的硬盘提高AOF性能。与RDB持久化相比,AOF持久化数据丢失更少,其消耗内存更少(RDB方式执行bgsve会有内存拷贝)。

过程

redisAOF持久化过程可分为以下阶段:

1.追加写入

redis将每一条写命令以redis通讯协议添加至缓冲区aof_buf,这样的好处在于在大量写请求情况下,采用缓冲区暂存一部分命令随后根据策略一次性写入磁盘,这样可以减少磁盘的I/O次数,提高性能。

2.同步命令到硬盘

当写命令写入aof_buf缓冲区后,redis会将缓冲区的命令写入到文件,redis提供了三种同步策略,由配置参数appendfsync决定,下面是每个策略所对应的含义:

  • no:不使用fsync方法同步,而是交给操作系统write函数去执行同步操作,在linux操作系统中大约每30秒刷一次缓冲。这种情况下,缓冲区数据同步不可控,并且在大量的写操作下,aof_buf缓冲区会堆积会越来越严重,一旦redis出现故障,数据丢失严重。
  • always:表示每次有写操作都调用fsync方法强制内核将数据写入到aof文件。这种情况下由于每次写命令都写到了文件中, 虽然数据比较安全,但是因为每次写操作都会同步到AOF文件中,所以在性能上会有影响,同时由于频繁的IO操作,硬盘的使用寿命会降低。
  • everysec:数据将使用调用操作系统write写入文件,并使用fsync每秒一次从内核刷新到磁盘。 这是折中的方案,兼顾性能和数据安全,所以redis默认推荐使用该配置。

3.文件重写(bgrewriteaof)

当开启的AOF时,随着时间推移,AOF文件会越来越大,当然redis也对AOF文件进行了优化,即触发AOF文件重写条件(后续会说明)时候,redis将使用bgrewriteaof对AOF文件进行重写。这样的好处在于减少AOF文件大小,同时有利于数据的恢复。

为什么重写?比如先后执行了“set foo bar1 set foo bar2 set foo bar3” 此时AOF文件会记录三条命令,这显然不合理,因为文件中应只保留“set foo bar3”这个最后设置的值,前面的set命令都是多余的,下面是一些重写时候策略:

  • 重复或无效的命令不写入文件
  • 过期的数据不再写入文件
  • 多条命令合并写入(当多个命令能合并一条命令时候会对其优化合并作为一个命令写入,例如“RPUSH list1 a RPUSH list1 b" 合并为“RPUSH list1 a b” )

重写触发条件

AOF文件触发条件可分为手动触发和自动触发:

手动触发:客户端执行bgrewriteaof命令。

自动触发:自动触发通过以下两个配置协作生效:

  • auto-aof-rewrite-min-size: AOF文件最小重写大小,只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。
  • auto-aof-rewrite-percentage:当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比,如100代表当前AOF文件是上次重写的两倍时候才重写。

redis开启在AOF功能开启的情况下,会维持以下三个变量

  • 记录当前AOF文件大小的变量aof_current_size。
  • 记录最后一次AOF重写之后,AOF文件大小的变量aof_rewrite_base_size。
  • 增长百分比变量aof_rewrite_perc。

每次当serverCron(服务器周期性操作函数)函数执行时,它会检查以下条件是否全部满足,如果全部满足的话,就触发自动的AOF重写操作:

  • 没有BGSAVE命令(RDB持久化)/AOF持久化在执行;
  • 没有BGREWRITEAOF在进行;
  • 当前AOF文件大小要大于server.aof_rewrite_min_size的值;
  • 当前AOF文件大小和最后一次重写后的大小之间的比率等于或者大于指定的增长百分比(auto-aof-rewrite-percentage参数)

重写过程

Redis-持久化_第2张图片

RDB-AOF优缺点

优点:

  1. RDB 是一个非常紧凑(compact)的文件,体积小,因此在传输速度上比较快,因此适合灾难恢复。
  2. RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
  3. RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。

缺点:

  1. RDB是一个快照过程,无法完整的保存所以数据,尤其在数据量比较大时候,一旦出现故障丢失的数据将更多。
  2. 当redis中数据集比较大时候,RDB由于RDB方式需要对数据进行完成拷贝并生成快照文件,fork的子进程会耗CPU,并且数据越大,RDB快照生成会越耗时。
  3. RDB文件是特定的格式,阅读性差,由于格式固定,可能存在不兼容情况。

AOF

优点:

  1. 数据更完整,秒级数据丢失(取决于设置fsync策略)。
  2. 兼容性较高,由于是基于redis通讯协议而形成的命令追加方式,无论何种版本的redis都兼容,再者aof文件是明文的,可阅读性较好。

缺点:

  1. 数据文件体积较大,即使有重写机制,但是在相同的数据集情况下,AOF文件通常比RDB文件大。
  2. 相对RDB方式,AOF速度慢于RDB,并且在数据量大时候,恢复速度AOF速度也是慢于RDB。
  3. 由于频繁地将命令同步到文件中,AOF持久化对性能的影响相对RDB较大,但是对于我们来说是可以接受的。

你可能感兴趣的:(秋招)