redis-持久化篇
Redis持久化
Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以 Redis 提供了**持久化功能 **!
RDB
RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是定期把内存所有数据都记录到磁盘中。
一旦Redis实例出现故障重启,就会从磁盘中读取快照文件,恢复数据
什么是快照?可以理解成定期给当前的内存中的redis数据拍一张照,然后保存下来。
RDB触发机制
可以分为手动触发和自动触发,手动的save占用主进程,bgsave是fork一个新进程来完成快照保存,在此期间主进程通过copyonwrite的机制(类似copyonwrite的Arraylist那样),拷贝一份当前数据,在拷贝的地方进行修改,等到子进程完成磁盘写之后再进行覆盖。
自动触发写在redis.conf上,save X Y,表示在X秒内如果有Y个key修改,那么就save(注意这里触发的还是bgsave)
- 手动触发
用bgsave可以防止主进程被阻塞,提高效率
fork采用的是copy-on-write
- 当主进程执行读操作的时候可以访问共享内存
- 当主进程执行写操作的时候,则会拷贝一份数据
子进程和主线程怎么共享内存,也就是怎么让子进程知道redis的内存是那些块?通过拷贝主进程的页表(没错就是计组那个页表),这样就知道主进程占用的虚拟地址和物理地址的映射关系,从而找到这些块。
copyonwrite会将此时的共享内存变成只读,主进程来读的时候就可以直接读,写的时候拷贝一份。
- 自动触发
注意这里save其实也是bgsave,一般都不会影响主进程
优缺点
优点:
- 只有一个dump.rdb,方便持久化,是一个紧凑的二进制文件,恢复的时候速度也比AOF更快,在数据量大的时候更明显。
- 实现了性能的最大化,fork子进程来完成而不影响主进程,保证了Redis的高性能。
缺点:
- 可能存在数据丢失,在两次RDB的时间里,如果出现宕机,这段时间没有写入的数据都将丢失
- 没有办法做到秒级持久化/实时持久化
- 对于cpu和内存的开销比较大,毕竟要fork一个新进程占用cpu,还要进行COW占用内存而,AOF主要占用的是IO资源
使用场景:
- 可以容忍数分钟数据丢失,追求更快的启动速度和恢复速度。
AOF
AOF(append only file) 持久化,采用日志的形式来记录每个写操作,追加到AOF文件的末尾。
意思就是把操作的每一条语句都记录下来,那肯定占用的空间大
Redis默认情况是不开启AOF的。重启时再重新执行AOF文件中的命令来恢复数据。它主要解决数据持久化的实时性问题。
AOF是执行完命令后才记录日志的。为什么不先记录日志再执行命令呢?这是因为Redis在向AOF记录日志时,不会先对这些命令进行语法检查,如果先记录日志再执行命令,日志中可能记录了错误的命令,Redis使用日志回复数据时,可能会出错。
正是因为执行完命令后才记录日志,所以不会阻塞当前的写操作。但是会存在两个风险:
- 更执行完命令还没记录日志时,宕机了会导致数据丢失
- AOF不会阻塞当前命令,但是可能会阻塞下一个操作。
这两个风险最好的解决方案是折中妙用AOF机制的三种写回策略 appendfsync:
- always,同步写回,每个子命令执行完,都立即将日志写回磁盘。
- everysec,每个命令执行完,只是先把日志写到AOF内存缓冲区,每隔一秒同步到磁盘。
- no:只是先把日志写到AOF内存缓冲区,有操作系统去决定何时写入磁盘。
always同步写回,可以基本保证数据不丢失,no策略则性能高但是数据可能会丢失,一般可以考虑折中选择everysec。
如果接受的命令越来越多,AOF文件也会越来越大,文件过大还是会带来性能问题。日志文件过大怎么办呢?
AOF重写机制就是随着时间推移,AOF文件会有一些冗余的命令如:无效命令、过期数据的命令等等,AOF重写机制就是把它们合并为一个命令(类似批处理命令),从而达到精简压缩空间的目的。
AOF重写会阻塞嘛?AOF日志是由主线程会写的,而重写则不一样,重写过程是由后台子进程bgrewriteaof完成。
优缺点
优点:
- 实时持久化,数据安全,AOF持久化配置为always就可以基本上避免丢失,但是开销比较大,通常用容忍1s内丢失的everysec
- 通过append模式写文件,那么即使中途服务器宕机,也可以尽量解决一致性问题(取决于刷盘策略)
- 重写机制,在文件太大的时候可以压缩空间
缺点:
- 文件比RDB大,恢复时间也会慢很多
- 启动效率低
- 文件体积迅速变大,需要定期执行重写机制降低文件体积。
使用场景:
- 对数据安全性有较高需求的场景
Redis4.0开始支持RDB和AOF的混合持久化,就是内存快照以一定频率执行,两次快照之间,再使用AOF记录这期间的所有命令操作。