Caution

未完待续

1 RDB

Tip
  • snapshot,快照
  • 二进制格式
  • 早期redis版本的默认方式
  • 按照事先指定的频率,周期性都保存到磁盘
  • 默认文件是dump.rdb
  • 宕机后,数据会丢失一部分
redis.conf
save 900 1  #900秒内如果有>=1个key发生变化(set写入的操作),则写入磁盘
save 300 10 #300秒内如果有>=10个key,则不用等待900秒 写入
save 60 10000  #如果60秒内有>=10000个 则写入
Caution

如果你在60秒内 做了 999次操作, 然后这个时候redis服务器宕机了. 那么数据就不会写入磁盘,也就是说丢失了.

1.1 主动生成rdb快照

进入客户端

# 每次执行这样的命令都会将所有redis内存快照到一个新的rdb文件,并覆盖原有快照文件
save 或 bgsave  

同步方式,在主线程中保存快照, 所以这个时候所有操作会阻塞,因为主线程就是用来执行client的请求的

  • background save ,异步方式,client请求不会阻塞
  • 调用fork创建一个子进程,父进程继续处理各个请求
  • linux的写时复制cow特点,父子进程共享同一个物理空间,父进程会将操作的页面创建一个副本,而子进程的数据还是要开始保存的那个时间点
  • 子进程负责将内存中的内容保存到临时文件,只有当其保存ok后,才会保存到真正的文件
  • 执行完后,子进程退出

1.2 重放

  • 就是将dump.rdb 重新加载到内存
  • rdb比aof的重放速度快,直接文件重新写入 ,aof是重新执行命令

2 AOF

  • append only file
  • 记录每一次的写操作,几乎不会丢失数据,但是 这样性能肯定就没那么好了
    • 因为写入磁盘本身 是先写到缓存的? 操作系统..
  • 就是将你执行的redis命令 添加到指定的文件
  • 文件会比较大
  • 重启时,可以通过重新执行文件中的命令在内存中重建数据
redis.conf中开启aof
appendonly no # 设置为yes 开启
appendfilename "appendonly.aof"  # 文件名
dir /usr/local/var/db/redis/  # 存放的目录在这里

2.1 写入策略

# appendfsync always  # 每写一条命令,就写入, 这个性能最不好
# 每1秒,redis内部本身也是先写到缓存中,到达1秒后,写入磁盘
# 故障时 只会丢失1秒钟的数据
appendfsync everysec
# appendfsync no      # 将数据交给操作系统来处理.

#表示重写的时候,父进程的新的操作不同步到文件
no-appendfsync-on-rewrite no
#可以用config set parma value 来修改
但是如果要永久话,需要 config rewirte

2.2 重写优化

我们知道当redis重启时, 会将aof文件里的命令重新执行来达到重建数据的目的

  • aof重写的问题
    • aof 是重新执行了一遍命令, 肯定比rdb 重放慢
    • 由于可能有很多无用的命令, 这个很好理解, 就是你后面的命令 直接覆盖了前面的, set a 1 ,set a 2,第一条命令实际就是没用的
    • 比如你执行了100次的操作,可能只要一次就行了,但是保存的还是100语句
  • 手动重写命令 bgrewirteaof 命令可以重写aof文件,合并一些操作
    • 不会读取旧的aof文件
    • 比如内存中的结果直接变成 它所对应的语句 写到临时文件
    • 将内存中的文件保存到临时文件,最后替换真正的文件
    • 过程
      • 主进程通过fork 生成子进程
      • 子进程根据内存中的数据创建数据库重建命令序列与临时文件中
      • 父进程继续接收client的请求,会把这些请求的命令追加于原来的aof文件,为了防止重写失败,额外的会把这些新的请求写于一个缓冲队列中
      • 子进程写完临时文件后,会通知父进程,父进程会把缓冲队列中的命令写到临时文件中
      • 最后 父进程?用临时文件替换老的aof文

2.3 重写策略

# 当你的文件 自上一次重写后 大小增加了100%后, 会触发重写
#当现在得aof文件是上次重写后的文件的2倍大小时,再次重写
auto-aof-rewrite-percentage 100
# 表示当文件至少达到64m的时候才会自动重写, 因为文件太小 本身加载到内存就很快.
auto-aof-rewrite-min-size 64mb

3 redis 4.0以后 混合持久化

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

  • 就是结合了上面的2个
  • 开启
aof-use-rdb-preamble yes
  • AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将 重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一 起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改 名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换。
  • 于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升。
Diagram
  • bgrewirteaof 后看下 aof文件,然后 set 写入 ,再看看文件里的内容
Back to top