• Redis持久化机制


    Redis持久化机制

    Redis的持久化有两种方式:RDB和AOF

    RDB

    RDB原理是将Redis在内存中的数据记录定时dump到磁盘上。

    1> 快照文件称为RDB文件,默认是保存在当前运行目录,也可在redis.conf中配置

    #是否压缩,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
    rdbcompression yes
    #RDB文件名称
    dbfilename dump.rdb
    #文件保存的路径目录
    dir ./
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2> RDB会在什么时候执行?

    自动触发:

    • 默认是服务停止时:Redis停机时会执行一次RDB,当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。

    • save m n :在m秒内,如果有n个键发生改变,则自动触发持久化,通过bgsave执行,如果设置多个、只要满足其—就会触发,配置文件有默认配置(可以注释掉)

      save 900 1 #900秒内,如果至少有1个key被修改,则执行bgsave
      save 300 10 #300秒内,如果至少有10个key被修改,则执行bgsave
      save “” #禁用RDB

    • flushall:用于清空redis所有的数据库,flushdb清空当前redis所在库数据(默认是0号数据库),会清空RDB文件,同时也会生成dump.rdb、内容为空

    • 主从同步:全量同步时会自动触发bgsave命令,生成rdb发送给从节点

    手动触发:

    [root@localhost ~]# redis-cli
    127.0.0.1:6379> save
    127.0.0.1:6379> bgsave
    Background saving started

    • save命令,使Redis处于阻塞状态,直到RDB持久化完成,才会响应其他客户端发来的命令。
    • bgsave命令,fork出一个子进程执行持久化,主进程只在fork过程中有短暂的阻塞,子进程创建之后,主进程就可以响应客户端请求了。子进程先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aSYTRkbb-1658827183649)(network-img/image-20220726144214834.png)]

    fork底层实现:

    进程操作的数据存储在物理内存上,但是所有进程不能直接操作物理内存,而是操作系统给每个进程分配虚拟内存,虚拟内存映射物理内存,进程只能操作虚拟内存,操作系统通过页表维护虚拟内存,进程基于页表到物理内存中读写数据。fork过程不是将内存数据拷贝一份给子进程,这样速度慢影响主进程效率,而是将主进程的页表拷贝一份给子进程,并将数据设置为只读,这样子进程也能和主进程操作同一片物理内存,从而实现与主进程空间共享。无需拷贝所有数据给子进程,速度快,主进程阻塞时间短。然后子进程就可以根据页表读取内存中数据写如磁盘,替换旧备份文件。

    子进程备份时主进程对数据进程改动,采用的是copy-on-write技术:

    • 当主进程执行读操作时,访问共享内存
    • 当主进程执行写操作时,则会涉及写操作的内存页,在新复制的内存页上进行写操作

    RDB方式bgsave的基本流程:

    • fork主进程得到一个子进程,共享内存空间
    • 子进程读取内存数据并写入新的RDB文件
    • 用新RDB文件替换旧的RDB文件。

    RDB的缺点?

    • 因为RDB执行间隔时间长,两次RDB之间写入数据时如果发生宕机,有数据丢失风险

    • fork子进程、压缩、写出RDB文件都比较耗时

    AOF

    AOF全称为Append Only File(追加文件)。Redis每一个写命令都会以追加方式记录在AOF文件

    1> AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:

    #是否开启AOF功能,默认是no
    appendonly yes
    #AOF文件的名称
    appendfilename "appendonly.aof"
    
    • 1
    • 2
    • 3
    • 4

    2> AOF同步策略,可通过redis.conf文件来配置:

    #表示每执行一次写命令,立即记录到AOF文件,最多丢—条
    appendfsync always
    #写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案,一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失
    appendfsync everysec
    #写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘,可能丢失较多数据
    appendfsync no
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    配置项刷盘时机优点缺点
    Always同步刷盘可靠性高,几乎不丢数据性能影响大
    everysec每秒刷盘性能适中最多丢失1S数据
    no操作系统控制性能最好可靠性较差,可能丢失大量数据

    3> AOF重写:AOF因为是记录命令,文件比RDB大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。

    Redis也会在触发阈值时自动去重写AOF文件。阈值也可以在redis.conf中配置:

    #AOF文件比上次文件增长超过多少百分比则触发重写
    auto-aof-rewrite-percentage 100
    #AOF文件体积最小多大以上才触发重写
    auto-aof-rewrite-min-size 64mb
    
    • 1
    • 2
    • 3
    • 4

    混合模式

    AOF | RDB对比:

    RDBAOF
    持久化方式定时对整个内存做快照记录每一次执行的命令
    数据完整性不完整,两次备份之间会丢失相对完整,取决于刷盘策略
    文件大小会有压缩,文件体积小记录命令,文件体积大
    宕机恢复速度很快
    数据恢复优先级低,数据完整性不如AOF高,数据完整性更高
    系统资源占用高,大量CPU和内存消耗。fork子进程、压缩、写出RDB文件都比较耗时,当数据集很大时,可能导致整个服务器停止服务几百毫秒,甚至1秒钟。低,主要是磁盘IO资源,但AOF重写时会占用大量CPU和内存资源
    使用场景可以容忍数分钟的数据丢失,追求更快的启动速度对数据安全性要求较高的场景

    RDB和AOF各有自己的优缺点,使用 RDB 持久化会有数据丢失的风险,但是恢复速度快,而使用 AOF 持久化可以保证数据完整性,但恢复数据的时候会很慢。于是从 redis4 之后新增了混合 AOF 和 RDB 的模式:RDB做全量备份,在RDB备份期间的写操作记录到AOF文件中,即AOF做增量持久化。

    当重写策略满足或手动触发重写的时候,fork 一个子线程将内存数据以 RDB 二进制格式写入 AOF 文件头部,那些在重写操作执行之后执行的 redis 命令,则以 AOF 持久化的方式追加到 AOF 文件的末尾。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QNZdLzfL-1658827183650)(network-img/image-20220726170705992.png)]

    这样的话,重启服务时会通过RDB 文件来重新构建内容,再使用 AOF 来重新执行近期的写指令,既保证了数据完整性,又提高了恢复的性能。

    aof-rdb 持久化机制默认是没有开启的,需要在 redis.conf 配置文件中配置开启,并开启 AOF 持久化。

    # 混合持久化开关
    aof-use-rdb-preamble yes
    
    • 1
    • 2

  • 相关阅读:
    近2天的小进步:框架优化-data封装
    魔改YOLOv5/YOLOv7高阶版(魔法搭配+创新组合)
    二叉树的建立和遍历
    Blender Shape Keys简明教程【Morph Target】
    【Java】循环语句for、while、do-while
    JAVA计算机毕业设计宠物寄养管理系统Mybatis+系统+数据库+调试部署
    GitLab忘记管理员密码处理和禁用注册功能
    《中国垒球》:决赛会师·占得先机
    ES6 --》JS运算符及数组扩展方法
    节能灯与led灯哪个对眼睛好?分享专业护眼的led灯
  • 原文地址:https://blog.csdn.net/weixin_46129192/article/details/125999319