美文网首页
Redis 学习二 持久化

Redis 学习二 持久化

作者: __Y_Q | 来源:发表于2023-12-11 17:32 被阅读0次

    在进行第二次学习前, 首先说明下 redis 安装目录 bin 下的文件说明

    • redis-benchmark redis性能测试工具
    • redis-check-aof AOF文件修复工具
    • redis-check-rdb RDB文件修复工具
    • redis-cli 命令行工具
    • redis-sentinel 集群管理工具
    • redis-server 服务进程指令

    本次学习的是 Redis 的持久化. 大多是理论知识.

    Redis 持久化

    Redis 的持久化大致分为3种.

    1. RDB 快照
    2. AOF 重写
    3. 混合持久化.

    下面将会对这三种持久化的方式进行学习.

    1. Redis 持久化之 RDB

    在默认情况下, Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中, 使用者可以对 Redis 进行设置, 让它在 N 秒内数据集至少有 M 个改动 这一条件被满足时, 自动保存一次数据集.

    save 60 1000, 这个设置会让 Redis 在满足 60 秒内至少有 1000 个键被改动 这一条件时, 自动保存一次数据集.

    使用者还可以手动执行命令来生成 RDB 快照, 操作方式为: 进入 Redis 客户端执行命令 save 或者 bgsave 就可以生成 dump.rdb 文件. 每次命令执行都会将所有的 Redis 内存快照保存到一个新的 rdb 文件里, 并覆盖原有的 rdb快照文件.

    上面说到了 savebgsave. 这两个命令是用来做什么的呢?

    • save 是同步的, 会阻塞
    • bgsave 是异步的, 不会阻塞. 属于写时复制. 在生成快照的同时, 依然可以正常处理写的命令.

    bgsave 子进程是由主进程 fork 生成的, 可以共享主进程的所有内存数据, bgsave子进程运行后, 开始读取主进程的内存数据,并把它写入到 RDB 文件, 此时如果主进程对这些数据也是读操作, 那么主进程和 bgsave 进程互不影响, 但是主进程要修改一块数据, 那么这块数据就会被复制一份, 生成改数据的副本, 然后 bgsave 子进程会把这个副本写入到 RDB 文件, 而在这个过程中, 主进程仍然可以直接修改原来的数据.

    save 和 bgsave 的对比

    命令 save bgsave
    IO 类型 同步 异步
    是否阻塞 redis 其他命令 否, 但是在生成子进程时, 调用 fork 函数会有短暂阻塞
    复杂度 O(n) O(n)
    优点 不会消耗额外内存 不阻塞客户端命令
    缺点 阻塞客户端命令 需要 fork 子进程, 消耗内存

    配置自动生成 rdb 文件, 后台使用的是 bgsave 方式.

    2. Redis 持久化之 AOF

    如果 redis 因为某些原因而造成故障停机, 那么服务器就会丢失最近写入, 且仍未保存到快照中的那些数据. 从 1.1 版本开始, Redis 增加了另一种持久化的方式, 就是 AOF. 它将修改的每一条指令都记录进 appendonly.aof 文件中.

    AOF 全称 append-only file

    打开 AOF 功能: 在配置文件中找到 appendonly 设置为 yes, 重启后执行写入数据的命令, 就会看到在设置RDB的目录中生成了一个 appendonly.aof 文件.

    现在测试一下. 执行命令 set zhangsan4 4444, 然后退出命令模式, 执行 cat appendonly.aof 查看.
    输出的内容为:

    *3
    $3
    set
    $9
    zhangsan4
    $4
    4444
    
    解读: 一条命令一般是以 * 开头, 
    *3              表示当前命令有3部分组成.
    $3              表示 set 命令有3个字符的长度
    set             表示具体执行的命令
    $9              表示 key 的长度
    zhangsan4   表示实际的key
    $4              表示 value 的长度
    4444            表示实际的value
    

    这是一种 resp 协议格式数据. *号后面的数据代表命令有多少个参数, $号后面的数字代表这个参数有几个字符.

    在进行数据恢复的时候, 就会将这个文件内数据逐条进行恢复.

    每当 Redis 执行一个改变数据集的命令时, 这个命令就会被追加到 AOF 文件的末尾. 这样的话, 每当 Redis 重新启动时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的.

    2.1 AOF 的策略
    1. appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全.
    2. appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据.
    3. appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择.

    推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性. 策略的修改, 也同样在配置文件中.

    2.2 AOF 的重写

    AOF 文件里可能会有太多无用的指令, 所以 AOF会定期根据内存的最新数据来生成 AOF 文件.
    例如执行了如下几条命令

    1 127.0.0.1:1234> incr readcount 
    2 (integer) 1
    3 127.0.0.1:1234> incr readcount 
    4 (integer) 2 
    5 127.0.0.1:1234> incr readcount 
    6 (integer) 3 
    7 127.0.0.1:1234> incr readcount 
    8 (integer) 4 
    9 127.0.0.1:1234> incr readcount 
    10 (integer) 5
    

    那么执行重写后 AOF 文件里变成

    1 *3 
    2 $3 
    3 SET 
    4 $2 
    5 readcount 
    6 $1 
    7 5
    

    AOF 自动重写频率配置

    auto‐aof‐rewrite‐min‐size 64mb //aof文件至少要达到64M才会自动重写, 文件太小恢复速度本来就 很快,重写的意义不大 
    auto‐aof‐rewrite‐percentage 100 //aof文件自上一次重写后文件大小增长了100%则再次触发重写
    

    当然 AOF还支持手动重写, 进入到 Redis 客户端执行bgrewriteaof 进行 AOF 重写.

    AOF 重写 Redis 会 fork 出一个子进程去做.(与 bgsave 命令类似), 不会对 Redis 正常命令处理有太多影响.

    RDB 与 AOF 的区别

    命令 RDB AOF
    启动优先级
    体积
    恢复速度
    数据安全性 容易丢失数据 根据策略决定

    在生产环境的话, 两者都可以启用, Redis 启动时如果既有 rdb 文件又有 aof 文件, 则优先选择 aof 文件恢复数据, 因为 aof 一般来说数据更全一点.

    3. Redis 混合持久化

    当重启 Redis 时, 一般很少使用 rdb 来恢复内存状态, 因为会丢失大量数据. 我们通常使用 aof 的方式. 但是 aof 性能相对 rdb 来说要会慢很多, 这样在 Redis 实例很大的情况下, 启动需要花费很长时间, Redis 4.0 后 为了解决这个问题, 带来了一个新的持久化选项, 那就是混合持久化.

    混合持久化的开启方式.(前提是 AOF 已经开启)

    aof‐use‐rdb‐preamble yes
    

    如果开启了混合持久化, aof 在重写时, 不再是单存的将内存数据转换为 resp 命令写入 aof 文件, 而是将重写这一刻之前的内存作为 rdb 快照处理, 并且将 rdb 快照内容和增量的 aof 修改内存数据的命令存在一起. 都写入新的 aof 文件, 新的文件一开始名字不是 appendonly.aof, 而是等重写完后新的 aof 文件才会进行重命为 appendonly.aof并覆盖原有的 aof 文件, 完成新旧两个aof文件的替换.

    Redis 数据备份策略

    1. 写定时调度脚本, 每隔一小时都复制一份rdbaof的备份到一个目录中去, 仅仅保留最近48小时的备份.
    2. 每天都保留一份当日的数据备份到一个目录中, 可以保留最近1个月的备份.
    3. 每次复制备份的时候, 都把太久的备份删除.
    4. 每晚将当前机器上的备份,复制一份到其他机器上, 防止机器损坏.

    相关文章

      网友评论

          本文标题:Redis 学习二 持久化

          本文链接:https://www.haomeiwen.com/subject/ubhpgdtx.html