Redis-持久化
标签:Redis

持久化

Redis所有数据保持在内存中,对数据的更新将异步的保存到磁盘上。

持久化方式:

  1. 快照
    1. MySQL Dump
    2. Redis RDB
  2. 写日志
    1. MySQL Binlog
    2. Hbase HLog
    3. Redis AOF

1. RDB

1.1 save命令

执行 save 命令就可以将数据保存到RDB(二进制)文件中,但是save命令是同步的,会发生阻塞。

文件策略:如果存在老的RDB文件,则新文件将会替换老的文件,复杂度为 O(n)

1.2 bgsave命令

执行 bgsave命令之后,会创建一个子线程,但fork这个过程还是会阻塞的,然后一步进行创建RDB文件,此时如果有新的 客户端发送请求,将会响应的。注意子进程执行完后返回的是 bgsave successfully

bgsave的文件策略和复杂度与save命令是相同的。

1.4 对比

命令 save bgsave
阻塞 是(阻塞发生在fork)
复杂度 O(n) O(n)
优点 不会消耗额外内存 不阻塞客户端命令
缺点 阻塞客户端命令 需要fork,消耗内存

1.5 自动生成RDB

上面的save满足任何一种都将会执行bgsave操作。

相关配置:

  1. dbfilename dump.rdb 文件名默认叫dump.rdb ——> dbfilename dump-${port}.rdb
  2. dir ./ :文件存在哪,默认在当前目录 ——> dir /bigdiskpath
  3. stop-wtites-on-bgsave-error yes:当bgsave出现错误时,停止, 一般使用默认
  4. rdbcompression yes :对rdb文件进行压缩 ,一般使用默认
  5. rdbchecksum yes : 对rdb进行校验和检验,一般使用默认

1.6 触发机制

  1. 全量复制 : 主从复制时会自动生成
  2. debug reload : debug级别的重启,不会将数据清除
  3. shutdown : 关闭也会生成

1.7 弊端

耗时,耗性能:

不可控,丢失数据:

2. AOF

当我们执行一条命令时,会同步的追加到AOF文件中去。

当redis宕机后,可以通过AOF重现原来的数据

2.1 always策略

执行写命令的时候不是直接写在硬盘中,而是写在缓冲区中,再根据相关的策略将命令同步到AOF文件中。

2.2 everysec 策略

是系统的默认值,每一秒将命令同步到AOF文件中去。

2.3 no策略

no策略同步到AOF文件是根据操作系统来决定的。

2.4 对比

命令 always everysec no
优点 不丢失数据 每秒一次fsync 不用管
缺点 IO开销较大,一般的sata盘只有几百TPS 丢1秒数据 不可控

一般使用第二种方式

2.5 AOF重写

作用:

  1. 减少硬盘占用量
  2. 加速恢复速度

方式:

客户端执行 bgreweriteaof 后返回ok,并创建出一个子进程去进行AOF重写(对AOF进行回溯)

重写配置:

  1. auto-aof-rewrite-min-size:AOF文件重写需要的尺寸,即AOF多大时才进行重写
  2. auto-aof-rewrite-percentage:AOF文件增长率,进行重写后,下次多少再进行重写

统计:

  1. aof_current_size :AOF当前尺寸(单位:字节)
  2. aof_base_size:AOF上次启动和重写的尺寸(单位:字节)

重写条件:自动触发时机

流程:

  1. 执行bgrewriteaof命令
  2. 父进程fork出子进程
  3. fork过程同时会将新的写到aof缓冲区中,也会重写aof缓冲区
  4. 生成新的aof文件
  5. 通知返回,将aof_rewrite_buf中的数据追加到新的AOF文件中,替换旧的AOF文件

2.6 AOF配置

  1. appendonly yes :使用aof之前要打开它,默认是关闭的
  2. appendfilename "appendonly-${port}.aof":修改默认的文件名
  3. appendfsync everysec :使用每秒策略
  4. dir /bigdiskpath :放到大磁盘目录下
  5. no-appendfsync-on-rewrite yes :是否在追加重写时产生的数据,即可能会丢失数据
  6. auto-aof-rewrite-percentage 100 :重写的百分比
  7. auto-aof-rewrite-min-size 64mb:重写最小大小

3. RDB和AOF对比

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

RDB策略

  1. 建议关
  2. 集中管理

4. 常见问题

4.1 fork操作

fork操作是同步的,内存量越大,执行所需的时间就越长,可以通过查看 info:latest_fork_usec 来查看上次fork操作所花的时间。

改善:

  1. 优先使用物理机或者高效支持fork操作的虚拟化技术
  2. 控制Redis实例最大可以内存:maxmemory
  3. 合理配置Linux内存分配策略:vm.overcommit_memory=1
  4. 降低fork频率:例如放宽AOF重写自动触发时机,不必要的全量复制

4.2 子进程开销优化

  1. CPU:
    1. 开销:RDB和AOF文件生成,属于CPU密集型
    2. 优化:不做CPU绑定,不和CPU密集型任务一起部署
  2. 内存
    1. 开销:fork内存开销,copy-on-write
    2. 优化:echo never > /sys/kernel/mm/transparent_hugepage/enabled 紧张分配大内存页
  3. 硬盘
    1. 开销:AOF和RDB文件写入,可以结合iostat,iotop分析
    2. 优化:
      1. 不要和高硬盘负载服务部署在一起:存储服务,消息队列等
      2. no-appendfsync-on-rewrite = yes
      3. 选用ssd
      4. 单机多实例持久化文件目录可以考虑分盘

5. 更多区别:

redis持久化RDB和AOF

  • 6 min read

CONTRIBUTORS


  • 6 min read