【重新理解Redis】(一) 讲Redis的持久化机制

讲Redis的持久化机制

Redis作为内存键值对数据库,特性之一就是持久化机制。参考关系型数据库(Mysql)的持久化机制,你可以想到他们肯定都是采用类似日志的形式记录数据修改变动,然后系统宕机时,通过重做日志的形式恢复数据。

在Redis的设计哲学中,一切的可靠性操作应尽可能少地侵入redis的设计出发点——快。也就是说,持久化机制应尽可能少地侵入redis主进程能力,这一点也是整个redis学习过程中都应该考虑到的。

Redis主要提供了两种持久化机制:

1,RDB持久化

RDB(Redis DataBase),即快照持久化,通过快照的方式将数据dump入一个dump.rdb文件中,文件中存储的是二进制数据,,紧凑型压缩。这样恢复数据只是版本切换的问题了,速度较快。也是redis的默认持久化方式。

RDB流程:主进程通过fork一个子进程来实现快照工作,fork的方式避免了主进程的阻塞。

快照期间,通过写时复制(Copy-On-Write,COW)技术,使得frok期间主进程仍然可以接受写入操作。也就是说,写时复制使得子进程能够感知到主进程中的数据变化,对于修改的数据,子进程会先写入该数据副本,然后主进程仍然可以对数据修改。

快照机制:第一次快照是全量快照机制,会快照内存中的所有数据,然后后面就采用增量快照的机制,只需要对两次快照期间变动的数据做快照即可。这也就意味着需要记录下来变动的数据,如果变动的数据较多,这个记录文件势必就会过大,这对内存资源珍贵的redis来说必然会有影响。为此,redis提供了解决机制,我们后面讲到。

快照频率:快照有手动触发快照和自动触发两种形式:

  • save:在主进程中快照,会阻塞主进程;
  • bgsava:后台异步快照,此时仍然可以响应客户端请求。

配置文件的形式:save second changes:每秒内至少有多少个key发生变化触发。

2,AOF持久化

AOF(Append Of File),redis主进程写入命令后,再将操作记录写入aof文件中,可以看到这里aof记录的是操作命令,可读性来说比较友好。不同于mysql日志的写前日志(Write Ahead Log,WAL),aof是写后日志。这样设计的原因:(但是,这样就会有丢失数据的风险)

  • 写入日志的都是执行成功的命令,确保没有记录错误命令的情况;
  • 避免当前写入的阻塞

2.1,AOF落盘机制:

由于追加写的原因和可靠性机制,aof文件是需要落盘的。落盘策略,由appendfsync 控制:

2.2,AOF重写机制

当aof文件过大时,就会触发重写机制,通过bgrewriteaof触发,默认是64MB,下次触发时是当原来文件重写后的2倍。

重写流程:(一次拷贝两次重写)

  • 主线程fork一个子进程实行重写;
  • 重写期间,主进程会将当前操作同时写入到aof缓存区和aof重写缓存区,以保证重写期间aof文件的完整性以及新的数据修改不会丢失;
  • 子进程写完后会通知主进程,然后主进程把aof重写缓存区数据写入新的aof文件
  • 新的AOF文件覆盖旧的AOF文件,完成AOF重写。

可能的阻塞:

  • fork时,主进程内存越大,阻塞越长。
  • 主线程有写入时,会阻塞。

2.3,RDB-AOF

redis4.0之后提供了第三种机制,即RDB-AOF混合的方式。我们之前讲到,RDB在增量复制的时候需要记录文件修改操作,当修改变动大时时很不可取的。这时,我们可以使用AOF文件记录增量间隙之间的修改,然后下次做全量快照的时候,可以重做AOF日志,然后清空AOF就好了。

3,总结

适用场景:

RDB:恢复速度快,数据丢失较高;

AOF:丢失率低,存储占用多,恢复速度慢;

RDB-AOF:推荐选择

4,其他

fork原理:fork的理解,是一种复制,复制映射关系而非物理内存,fork时,主进程内存越大,阻塞越长。

写时复制:

猜你喜欢

转载自blog.csdn.net/qq_40589204/article/details/124749686