
Redis是跑在内存里的,当程序重启或者服务崩溃,数据就会丢失,如果业务场景希望重 启之后数据还在,就需要持久化,即把数据保存到可永久保存的存储设备中。
持久化方式:
二者的区别:
应用场景:
如果业务本身只是缓存数据而不是海量访问,不用开持久化。
如果对数据非常重视,可以同时开启RDB和AOF,优先使用AOF(AOF内容更全,数据恢复更完整)。
如果可以接受丢几分钟级别的数据,那么建议只开RDB。单独开AOF,Rdis官方不建议,因为如果决定要走数据备份,那么镜像保存始终是数据库领域非常行之有效的解决方案,所以在配置中RDB是默认打开的,而AOF不是。
Redis默认是开启RDB持久化的,在redis.windows.conf可以看到。
save 900 1
save 300 10
save 60 10000
表示每900s,有1条写数据操作
每300s,有10条写数据操作
每600s,有10000条写数据操作
这里的写操作指增加、删除及更新,就会激活RDB持久化(触发bgsave)。
主动执行命令save,会有响应的提示输出。就会在主线程生成RDB文件,由于和执行操作命令在同一个线程,所以如果写入RDB文件的时间太长,会阻塞主线程,这个命令慎用。
主动执行bgsava,区别save,会创建一个子进程生成RDB文件,避免主线程的阻塞。
达到持久化配置阈值,周期函数检查是否达到策略,达到就触发bgsave。
程序正常关闭时执行,以记录更全的数据。
执行持久化过程中,Redis依然可以继续处理操作命令,数据是能被修改的,主要通过写时复制技术实现,相当于异步执行。
fork出的子进程后,子进程复制了页表,但是页表指向的物理内存还是同一块。
只有当修改内存数据时,物理内存才会被复制一份。此时Redis使用bgsave对当前内存当中的所有数据做快照,主线程修改的副本,这部分不会追加给子进程进行持久化。
这样做减少了创建子进程过程时的性能损耗,从而加快创建子进程的速度,因为创建过程会阻塞主线程。
默认情况下,AOF是关闭的,应该根据实际需要打开。
打开之后,Redis每条更改数据的操作都会记录到AOF文件中,当你重启,AOF会助你重建状态,相当于就是请求全部重放一次,所以AOF恢复起来会比较慢。
执行请求时,每条日志都会写入到AOF当中,会一定程度上影响程序性能。因此Redis提供了3种刷盘策略,以便根据需要进行不同的选择。
Redis建议方案2,在保证速度情况下,崩溃丢失1s的数据认为大多数场景是可以接受的。
在不存在超级热点缓存时,丢失30s不是问题时,可以使用方案3。
方案1使用场景较少,因为Redis本身是无法做到完全不丢数据,Redis定位就不是完全可靠的,没有必要损耗大量性能去追求立刻刷盘。
将数据写入AOF缓存(aof_buf)当中,本质是一个sds数据。
aof_buf将对应数据刷入到磁盘缓冲区,对应四个时机,会调用flushAppendOnlyFIle函数,其使用Write函数将数据写入操作系统缓冲区:
处理完事件处理后,等待下一次事件到来之前,也就是beforeSleep中
周期函数serverCron
服务器退出之前的准备工作时
通过配置指令关闭AOF功能时
注意,如果是appendfsync everysec策略,那么在上一次fsynci还没完成之前,并且时长 不超过两秒时,就本次flushAppendOnlyFile就会放弃,也就是说先不写入aof_buf的,等待下次调度。
刷盘,调用系统的flush函数。
Redis在AOF文件体积过大时,自动在后台Fork一个子进程,专门对AOF重写。
针对相同Key的操作,进行合并,比如对同一个Key的set,用后者覆盖前者。
在重写过程中,新的操作记录不仅记录在原有的AOF缓冲区,还会记录在AOF重写缓冲区,在新的AOF文件创建好时,一起追加到新文件当中,再用新的AOF替代旧的AOF。
重写时机:
二者都是配置决定的,最后实际上还是周期函数检查然后触发。
混合部署实际发生在AOF重写阶段,将当前状态保存为RDB二进制文件内容,写入AOF文件,再将重写缓冲区的内容追加到AOF文件中。
此时的AOF文件,是二进制数据+日志数据的混合体,所以叫做混合持久化。
发生在AOF流程当中,本质上还是AOF,只是重写时使用RDB进行优化。
是RDB和AOF的折中。
更好解决了AOF体积过大的问题,同时文件恢复数据更快。
对应配置文件的,aof-use-rdb-preamble。
在5.0之后默认是打开的,所以5.0之后只要AOF配置开启,默认就是混合持久化。
同时启用AOF和RDB时,Redis重新启动时,会使用AOF文件重建数据集。
通常来说AOF数据更完整,混合持久化属于AOF,有混合持久化时,优先使用混合持久化的数据。
通过判断文件开头是否有REDIS来判断。