Redis(二),持久化

2020/09/16 数据库 共 2535 字,约 8 分钟

Redis是内存数据库,如果不进行持久化,一旦进程退出或宕机数据就会丢失

RDB

将数据写入.rdb(二进制文件)

save

  1. 优点:节约系统资源

  2. 缺点:直接调用 rdbSave,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求

bgsave

  1. 优点:fork出一个子进程,子进程负责调用rdbSave,并在保存完成之后向主进程发送信号,通知保存已完成。Redis服务器在bgsave执行期间仍然可以继续处理客户端的请求

  2. 缺点:由于会fork一个进程,因此更消耗内存

  3. 实现方式:
     # 原理
     1、Redis的save m n,是通过serverCron函数、dirty计数器、和lastsave时间戳来实现的。
        
     2、serverCron是Redis服务器的周期性操作函数,默认每隔100ms执行一次(redis.conf中默认:hz  10,表示1s内执行10次,也就是每100ms触发一次定时任务);
     该函数对服务器的状态进行维护,其中一项工作就是检查save m n配置的条件是否满足,如果满足就执行bgsave。
        
     3、dirty计数器是Redis服务器维持的一个状态,记录了上一次执行bgsave/save命令后,服务器状态进行了多少次修改(包括增删改);而当save/bgsave执行完成后,会将dirty重新置为0;
     注意dirty记录的是服务器进行了多少次修改,而不是客户端执行了多少修改数据的命令。例如,如果Redis执行了set mykey helloworld,则dirty值会+1;如果执行了sadd myset v1 v2 v3,则dirty值会+3
        
     4、lastsave时间戳也是Redis服务器维持的一个状态,记录的是上一次成功执行save/bgsave的时间。
        
     5、save m n的原理如下:每隔100ms,执行serverCron函数;在serverCron函数中,遍历save m n配置的保存条件,只要有一个条件满足,就进行bgsave。
    
     # 在redis.conf文件中配置
     # 1、多条件设置,满足一条就会生效,触发bgsave
     save 1000 1  # 1000秒内至少1个key发生变化,则重写rdb文件
     save 300 10  # 300秒内至少10个key发生变化...
     save 90 100  # 90秒内至少100个key发生变化...
        
     # 2、rdb的文件名,改为'dump-端口.rbd'
     dbfilename dump-${port}.rdb
        
     # 3、文件持久化目录,日志目录,改到分布式存储中或者放到较大的硬盘目录中。
     dir /opt/data/
        
     # 4、bgsave发生错误时停止写入
     stop-writes-on-bgsave-error yes
        
     # 5、采用压缩方式,不然生成的rdb文件可能很大。压缩后主从复制拷贝文件小,速度也快。
     rdbcompression yes
        
     # 6、在写入文件和读取文件时开启rdb文件检查
     rdbchecksum yes
    
  4. 其他触发机制
    1. 执行shutdown命令时,自动执行bgsave进行rdb持久化
    2. 在主从复制场景下,如果从节点执行全量复制操作,则主节点会执行 bgsave 命令,并将rdb文件发送给从节点

AOF

将写操作追加到.aof文件(类似log文件)

策略

  1. always:每条命令都会刷新到缓冲区,把缓冲区fsync到硬盘,对硬盘IO压力大。

  2. everysec:每秒把缓冲区fsync到硬盘,如果出现故障,会丢失1s(默认配置是1秒)的数据,一般使用这种。

  3. no:由操作系统来定什么时候fsync到硬盘中,缺点是不可控。

AOF重写

  1. 作用:减少硬盘占用量、加快恢复速度

  2. 实现方式:

     # 原理
     1、调用bgrewriteaof,fork一个子进程,子进程带有主进程的数据副本
        
     2、之后的写操作命令都会被添加到旧aof文件(考虑性能此操作应禁止)以及aof_rewrite_buf_blocks重写缓冲中
        
     3、在目前版本中,REDIS_AOF_REWRITE_ITEMS_PER_CMD常量的值为64,
     当键中包含的值超过64个,设置键值对的命令将会被拆开
        
     4、当子进程rewrite结束后,父进程收到子进程退出信号,把重写缓冲添加到rewrite后的文件中,旧文件关闭随即删除。
     在整个rewrite过程中只有这个步骤对父进程造成阻塞,将影响降到了最低。
        
     5、aofUpdateCurrentSize统计aof文件的大小,更新server.aof_rewrite_base_size,用于接下来判断aof增长率
        
     6、bgrewriteaof的时候如果同时存在bgsave在备份,会推迟这次操作,待到bgsave结束后的下一次serverCron才会触发
    
     # 在redis.conf文件中配置
     # 1、打开aof功能
     appendonly yes
        
     # 2、‘当前aof文件’超过‘上次重写时aof文件’百分比时触发重写
     auto-aof-rewrite-percentage 100
        
     # 3、‘当前aof文件’超过设定值时触发重写,注意2和3须同时满足
     auto-aof-rewrite-min-size 64mb
        
     # 4、重命名aof文件名,以端口号区分
     appendfilename "appendonly-${port}.aof"
        
     # 5、使用everysec策略
     appendfsync everysec
        
     # 6、在aof重写的时候,不做旧aof的append操作,这里出于性能考虑
     no-appendfsync-on-rewrite yes
        
     # 7、redis在恢复时,忽略最后一条可能被截断的指令
     aof-load-truncated yes
    

总结

  1. RDB恢复速度快;但如果数据备份时宕机,会丢失两次持久之间的数据,数据量较大,而且备份时占用双倍内存

  2. AOF文件越来越大,且恢复较慢;一般情况下设置每秒fsync,数据完整性与一致性较高,宕机只会丢失一秒的数据

  3. 建议RDB和AOF同时开启,但是恢复时Redis会优先使用从AOF来还原数据库,如果AOF关闭,则从RDB中恢复

  4. Redis4新增了混合模式,当前数据以rdb写入,追加操作以aof写入。既不阻塞主进程,恢复速度又快,但不兼容之前的版本

     # 在redis.conf文件中配置
     aof-use-rdb-preamble yes
    

文档信息

Search

    Table of Contents