【概念】【Redis】Redsi的持久化机制【P12】

RDB

  • 简介
    RDB是Redis用来进行持久化的一种方式,是把当前内存中的数据集快照写入磁盘,也就是快照(数据库中所有键值对数据)。恢复时是将快照文件直接读到内存里。
  • 两种触发方式
    • 手动触发
      • save:
        该命令会阻塞redis,在sava期间,不能执行其他命令,直到持久化完成。
      • bgsave:
        该命令不会阻塞redis,在后台进行的。该触发方式会fork一个子进程,由子进程负责持久化,因此阻塞只会发生在fork子进程的时候。
    • 自动触发
  • # 时间策略 save 900 1 #表示900 秒内如果至少有 1 个 key 的值变化,则保存 save 300 10 #表示300 秒内如果至少有 10 个 key 的值变化,则保存 save 60 10000 #表示60 秒内如果至少有 10000 个 key 的值变化,则保存 # 设置快照的文件名,默认是 dump.rdb dbfilename dump.rdb # 设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。默认是和当前配置文件保存在同一目录。也就是说通过在配置文件中配置的 save 方式,当实际操作满足该配置形式时就会进行 RDB 持久化,将当前的内存快照保存在 dir 配置的目录中,文件名由配置的 dbfilename 决定。 dir /home/work/app/redis/data/ # 默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。如果Redis重启了,那么又可以重新开始接收数据了 stop-writes-on-bgsave-error yes # 默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。 rdbcompression yes # 默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。 rdbchecksum yes

除了根据redis配置文件配置规则自动触发,还有下面三种触发方式:
1、从节点全量复制时,主节点发送一个rdb文件给从节点完成复制操作时,主节点会触发bgsave。
2、执行debug reload时自动触发RDB持久化。
3、执行shutdown时,若没有开启aof 也会触发RDB持久化。

  • RDB持久化流程
    在这里插入图片描述
    这里注意的是 fork 操作会阻塞,导致Redis读写性能下降。我们可以控制单个Redis实例的最大内存,来尽可能降低Redis在fork时的事件消耗。以及上面提到的自动触发的频率减少fork次数,或者使用手动触发,根据自己的机制来完成持久化。
  • RDB优缺点
    • 优点
    1. RDB 是紧凑的二进制文件,比较适合备份,全量复制等场景
    2. RDB 恢复数据远快于 AOF
    • 缺点
    1. RDB 无法实现实时或者秒级持久化;
    2. 新老版本无法兼容RDB 格式。

AOF

  • 简介
    使用AOF持久化时,Redis会将每一个收到的写命令都通过write函数追加到文件中,类似于MySQL的binlog。当Redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。当然由于OS会在内核中缓存write做的修改,所以可能不是立即写到磁盘上。这样AOF方式的持久化也还是有可能会丢失部分修改。
  • 配置AOF
  • # 是否开启aof appendonly yes # 文件名称 appendfilename "appendonly.aof" # 同步方式 appendfsync everysec #always:每次命令写入aof_buffer后都会调用fsync同步到aof文件,fsync完成后线程才返回。线程每次都会等fsync完成后才返回,性能较差,数据安全性最高 #everysec:命令先写入aof_buffer,然后调用系统write操作,write操作完成后线程就返回,由后台专门的线程每秒执行一次fsync操作。推荐使用;最多丢失2s内的数据。 #no:命令先写入到aof_buffer,然后调用系统write操作,write操作后线程返回,fsync操作由操作系统负责,时间不确定。fsync由系统负责,数据安全性无法确保,并且会加大每次fsync同步到硬盘的数据量。不推荐 # aof重写期间是否同步 no-appendfsync-on-rewrite no # 重写触发配置 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 加载aof时如果有错如何处理 aof-load-truncated yes #如果该配置启用,在加载时发现aof尾部不正确是,会向客户端写入一个log,但是会继续执行,如果设置为 `no` ,发现错误就会停止,必须修复后才能重新加载。 # 文件重写策略 aof-rewrite-incremental-fsync yes
  • AOF原理
    采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。
    AOF的整个流程大体分为两步,一步是命令的实时写入(如果是 appendfsync everysec 配置,会有1s损耗),第二步是对aof文件的重写(重写是直接把当前内存的数据生成对应命令)。
    对于增量追加到文件这一步主要的流程是:命令写入=》追加到aof_buf =》同步到aof磁盘。那么这里为什么要先写入buf在同步到磁盘呢?如果实时写入磁盘会带来非常高的磁盘IO,影响整体性能。
    aof重写的目的是为了减少aof文件的大小,可以手动(bgrewriteaof)或者自动触发(根据配置规则触发)。
    在这里插入图片描述
  • 在重写期间,由于主进程依然在响应命令,为了保证最终备份的完整性;因此它依然会写入旧的AOF file中,如果重写失败,能够保证数据不丢失。
  • 为了把重写期间响应的写入信息也写入到新的文件中,因此也会为子进程保留一个buf,防止新写的file丢失数据。
  • 重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析、命令合并。
  • AOF文件直接采用的文本协议,主要是兼容性好、追加方便、可读性高可认为修改修复。
  • AOF的优缺点
    • 优点
    1. 可以更好地保护数据不丢失;
    2. appen-only 模式写入性能比较高;
    3. 适合做灾难性的误删除紧急恢复。
    • 缺点
    1. 对于同一份文件,AOF 文件要比 RDB 快照大;
    2. AOF 开启后,会对写的 QPS 有所影响,相对于 RDB 来说 写 QPS 要下降;
    3. 数据库恢复比较慢, 不合适做冷备。

混合持久化机制

基本上都不会是单独使用每一种方式解决持久化的。因为都存在问题。4.0版本的混合持久化默认关闭的,通过aof-use-rdb-preamble配置参数控制,yes则表示开启,no表示禁用,5.0之后默认开启。混合持久化是通过bgrewriteaof完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据,
优点: 混合持久化结合了RDB持久化 和 AOF 持久化的优点, 由于绝大部分都是RDB格式,加载速度快,同时结合AOF,增量的数据以AOF方式保存了,数据更少的丢失。
缺点: 兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该aof文件,同时由于前部分是RDB格式,阅读性较差

RDB和AOF的对比

  • redis提供了rdb持久化方案,为什么还要aof?
    优化数据丢失问题,rdb会丢失最后一次快照后的数据,aof丢失不会超过2秒的数据
  • 如果aof和rdb同时存在,听谁的?
    aof
  • rdb和aof优势劣势
    rdb 适合大规模的数据恢复,对数据完整性和一致性不高 ,在一定间隔时间做一次备份,如果redis意外down机的话,就会丢失最后一次快照后的所有操作aof 根据配置项而定。
    官方建议 两种持久化机制同时开启,如果两个同时开启 优先使用aof持久化机制

Redis 淘汰策略有哪些?

Redis 可以看作是一个内存数据库,通过 Maxmemory 指令配置 Redis 的数据集使用指定量的内存。设置 Maxmemory 为 0,则表示无限制。当内存使用达到 Maxmemory 极限时,需要使用某种淘汰算法来决定清理掉哪些数据,以保证新数据的存入。

  • Redis的淘汰策略
    • noeviction:禁止驱逐数据,也就是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失,这也是系统默认的一种淘汰策略。
    • allkeys-lru:从数据集中挑选最近最少使用的数据淘汰,该策略要淘汰的key面向的是全体key集合,而非过期的key集合。
    • volatile-lru:除了淘汰机制采用LRU,策略基本上与volatile-lru相似,从设置过期时间的数据集中挑选将要过期的数据淘汰,ttl值越大越优先被淘汰。
    • allkeys-random:从数据集中选择任意数据淘汰。
    • volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。当内存达到限制无法写入非过期时间的数据集时,可以通过该淘汰策略在主键空间中随机移除某个key。
    • volatile-ttl:除了淘汰机制采用LRU,策略基本上与volatile-lru相似,从设置过期时间的数据集中挑选将要过期的数据淘汰,ttl值越大越优先被淘汰。
    • # redis.conf #配置Redis的内存大小 maxmemory 100mb # 配置淘汰策略 maxmemory-policy volatile-lru
原文地址:https://www.cnblogs.com/zzsuje/p/12888740.html