zoukankan      html  css  js  c++  java
  • 一篇文章彻底理解Redis持久化:RDB和AOF

    为什么需要持久化?

    Redis对数据的操作都是基于内存的,当遇到了进程退出、服务器宕机等意外情况,如果没有持久化机制,那么Redis中的数据将会丢失无法恢复。有了持久化机制,Redis在下次重启时可以利用之前持久化的文件进行数据恢复。理解和掌握Redis的持久机制,对于Redis的日常开发和运维都有很大帮助,也是在大厂面试经常被问到的知识点。Redis支持的两种持久化机制:

    1. RDB:把当前数据生成快照保存在硬盘上。
    2. AOF:记录每次对数据的操作到硬盘上。

    接下来,我们详细了解一下这两种持久化机制。

    欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

    RDB持久化

    RDB(Redis DataBase)持久化是把当前Redis中全部数据生成快照保存在硬盘上。RDB持久化可以手动触发,也可以自动触发。

    手动触发

    savebgsave命令都可以手动触发RDB持久化。

    save命令

    执行save命令会手动触发RDB持久化,但是save命令会阻塞Redis服务,直到RDB持久化完成。当Redis服务储存大量数据时,会造成较长时间的阻塞,不建议使用。

    > save
    OK
    

    执行后,Redis的日志中记录:

     * DB saved on disk
    
    bgsave命令

    执行bgsave命令也会手动触发RDB持久化,和save命令不同是:Redis服务一般不会阻塞。Redis进程会执行fork操作创建子进程,RDB持久化由子进程负责,不会阻塞Redis服务进程。Redis服务的阻塞只发生在fork阶段,一般情况时间很短。

    > bgsave
    Background saving started
    

    执行后,Redis的日志中记录:

     * Background saving started by pid 2645
     * DB saved on disk
     * RDB: 0 MB of memory used by copy-on-write
     * Background saving terminated with success
    

    bgsave命令的具体流程如下图:

    bgsave命令流程

    1. 执行bgsave命令,Redis进程先判断当前是否存在正在执行的RDB或AOF子线程,如果存在就是直接结束。
    2. Redis进程执行fork操作创建子线程,在fork操作的过程中Redis进程会被阻塞。
    3. Redis进程fork完成后,bgsave命令就结束了,自此Redis进程不会被阻塞,可以响应其他命令。
    4. 子进程根据Redis进程的内存生成快照文件,并替换原有的RDB文件。
    5. 子进程通过信号量通知Redis进程已完成。

    欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

    自动触发

    除了执行以上命令手动触发以外,Redis内部可以自动触发RDB持久化。自动触发的RDB持久化都是采用bgsave的方式,减少Redis进程的阻塞。那么,在什么场景下会自动触发呢?

    1. 在配置文件中设置了save的相关配置,如sava m n,它表示在m秒内数据被修改过n次时,自动触发bgsave操作。
    2. 当从节点做全量复制时,主节点会自动执行bgsave操作,并且把生成的RDB文件发送给从节点。
    3. 执行debug reload命令时,也会自动触发bgsave操作。
    4. 执行shutdown命令时,如果没有开启AOF持久化也会自动触发bgsave操作。

    RDB优点

    RDB文件是一个紧凑的二进制压缩文件,是Redis在某个时间点的全部数据快照。所以使用RDB恢复数据的速度远远比AOF的快,非常适合备份、全量复制、灾难恢复等场景。

    RDB缺点

    每次进行bgsave操作都要执行fork操作创建子经常,属于重量级操作,频繁执行成本过高,所以无法做到实时持久化,或者秒级持久化。

    另外,由于Redis版本的不断迭代,存在不同格式的RDB版本,有可能出现低版本的RDB格式无法兼容高版本RDB文件的问题。

    欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

    AOF持久化

    AOF(Append Only File)持久化是把每次写命令追加写入日志中,当需要恢复数据时重新执行AOF文件中的命令就可以了。AOF解决了数据持久化的实时性,也是目前主流的Redis持久化方式。

    AOF持久化流程

    AOF流程如下图:

    AOF流程

    1. 命令追加(append):所有写命令都会被追加到AOF缓存区(aof_buf)中。
    2. 文件同步(sync):根据不同策略将AOF缓存区同步到AOF文件中。
    3. 文件重写(rewrite):定期对AOF文件进行重写,以达到压缩的目的。
    4. 数据加载(load):当需要恢复数据时,重新执行AOF文件中的命令。

    文件同步策略

    AOF持久化流程中的文件同步有以下几个策略:

    1. always:每次写入缓存区都要同步到AOF文件中,硬盘的操作比较慢,限制了Redis高并发,不建议配置。
    2. no:每次写入缓存区后不进行同步,同步到AOF文件的操作由操作系统负责,每次同步AOF文件的周期不可控,而且增大了每次同步的硬盘的数据量。
    3. eversec:每次写入缓存区后,由专门的线程每秒钟同步一次,做到了兼顾性能和数据安全。是建议的同步策略,也是默认的策略。

    触发文件重写

    AOF持久化流程中的文件重写可以手动触发,也可以自动触发。

    1. 手动触发:使用bgrewriteaof命令。
    2. 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage配置确定自动触发的时机。auto-aof-rewrite-min-size表示运行AOF重写时文件大小的最小值,默认为64MB;auto-aof-rewrite-percentage表示当前AOF文件大小和上一次重写后AOF文件大小的比值的最小值,默认为100。只用前两者同时超过时才会自动触发文件重写。

    欢迎关注微信公众号:万猫学社,每周一分享Java技术干货。

    AOF持久化配置

    对AOF持久化的具体流程有了了解后,我们来看一下如何配置AOF。AOF持久化默认是不开启的,需要修改配置文件,如:

    # appendonly改为yes,开启AOF
    appendonly yes
    # AOF文件的名字
    appendfilename "appendonly.aof"
    # AOF文件的写入方式
    # everysec 每个一秒将缓存区内容写入文件 默认开启的写入方式
    appendfsync everysec
    # 运行AOF重写时AOF文件大小的增长率的最小值
    auto-aof-rewrite-percentage 100
    # 运行AOF重写时文件大小的最小值
    auto-aof-rewrite-min-size 64mb
    

    微信公众号:万猫学社

    微信扫描二维码

    获得更多Java技术干货

  • 相关阅读:
    windows下python-nmap运行过程中出现的问题及解决办法
    命令行下cl.exe编译链接的问题及解决方法
    httrack: error while loading shared libraries: libhttrack.so.2的解决方法
    AES加解密非固定长度文本的用法
    John the Ripper password cracker试用
    ubuntu12.04使用root登陆的简单设置
    map按value查找相应元素
    ListCtrl添加右键菜单(ListCtrl类里编辑,给ListCtrl 发送NM_RCLICK消息)
    今天发现里一个非常好用的Listbox自绘类,带不同文字字体和图片,觉得很有必要记下来
    自绘listCtrl控件选中该行高亮(模拟windows)
  • 原文地址:https://www.cnblogs.com/heihaozi/p/12866948.html
Copyright © 2011-2022 走看看