前言
开始Redis面试知识的复习和资料的收集(收集和参考了网上的优质文章),本篇文章会不断更新,本系列文章主要分为两部分,一部分是该专题所涉及的相关基础知识,另一部分是面试题与思考题,大部分重要知识和基础知识的延伸会在面试题和思考题中给出,这样做的目的是给出具体的场景,便于理解知识(相较于直接在知识中展出),且我会以相对口语化的方式叙述。
建议关注,随着我复习的进度,内容会一直得到补充
持久化相关知识
1.三种持久化机制
RDB持久化,AOF持久化,混合型持久化(将RDB和AOF结合在一起,这里就不过多赘述了)
2.RDB持久化
RDB全称叫做Redis数据备份文件,也叫做Redis数据快照,将内存中所有数据都记录到磁盘中,当Redis故障或重启时,从磁盘中读取快照文件,恢复数据
主动进行RDB持久化:
事实上,redis有自己的自动触发持久化机制,并且配置在了配置文件中:
由上面可见,两次备份间如果发生宕机,会出现数据丢失,因为其备份的频率很低
配置文件中关于RDB的其他配置
3.深入剖析一下RDB持久化过程
bgsave异或持久化可以做到几乎对主进程0阻塞,为什么说是几乎呢,因为主进程去fork这个子进程的时候是阻塞的,为了让主进程尽快得去处理其他请求,bgsave是如何实现:
在linux中,所有进程都无法直接操作物理内存,操作系统会为进程分配虚拟内存,然后再虚拟内存中会有一个与物理内存做映射的表叫做页面,通过这个对物理内存进行读写,当fork子线程的时候,不是把内存做拷贝,而是把页表进行拷贝,此时子进程就可以对内存中的数据进行修改,这样,无需拷贝内存中的数据就可以实现内存共享,使得fork子线程的速度非常快
子线程就会读取内存中的数据并且写入磁盘中的一个RDB文件中来持久化,并替换旧的RDB文件
但由于是异步的,此时子进程正在读取数据,主进程可能收到修改数据的指令,此时读写会发生冲突,为了解决这个问题,copy采用了copy-on-write技术,共享内存只能读,当主线程要修改共享内存中的某个数据,例如数据A时,会将该数据A复制出来,并进行修改,此后对于数据A的读和写都在副本中进行
极端情况下,当子线程读取数据存储到RDB文件内的速度很慢,此时主线程收到了将所有数据进行修改的请求,那么所有数据都要复制一份,变成双倍内存
4.AOF持久化
AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看作是命令日志文件。
AOF默认是关闭的,打开:
AOF记录的频率:
由于是记录命令,AOF比RDB文件大得多,并且记录的大部分名称都是无效的,只有对一个key的最后一次写操作才有意义,可以通过bgrewriteaof命令,让AOF文件执行重写功能
自动触发文件重写阈值:
5.RDB和AOF对比
面试题
1.redis持久化机制有哪些?
RDB,AOF,混合型持久化
2.那仔细讲讲你对他们的理解
RDB:RDB是通过将内存中当前进程的数据生成快照(.rdb)文件保存到硬盘中,可以自动触发或者手动触发:
自动触发的配置写在了配置文件中:
900秒内如果至少1个key被修改,就执行bgsave,300秒内如果至少10个key被修改,就执行bgsave,10000秒内如果至少60个key被修改,就执行bgsave
手动触发:save和bgsave,其中save是主线程来进行生成RDB文件进行持久化过程,会造成长时间阻塞,一般使用bgsave,主线程会fork一个子线程,并将自己的快照文件复制给子线程,子线程根据快照文件读取共享内存数据到.rdb文件中,读取完成后替换旧的rbd文件进行持久化操作
RDB持久化的优点在于使用子线程来异步持久化,主线程不会进行IO操作,保证了Redis的高性能,而且其存储的是压缩的二进制文件,适用于备份,全量复制,并且其加载速度远大于AOF文件
缺点在于其持久化间隔时间比较长,如果下一次持久化前发生宕机等故障,会造成数据的丢失,即无法做到实时持久化,并且在fork子线程进行持久化时,如果主线程进行修改操作,需要对修改的数据先进行复制,理论上最差的情况是全都复制一遍,即占用两倍的内存。并且RDB二进制文件存在新老版本不兼容的问题.
AOF:AOF持久化是将命令像日志一样写入文件中进行持久化,其持久化策略有三种:
其优点在于能将数据丢失的风险大大降低,保证数据是最新的,并且将命令写入文件的操作是异步的,不允许主线程
缺点在于因为是保存所有命令,其文件比RDB大得多,数据恢复其实也就是执行命令的过程,所以会慢很多
混合型持久化的优点在于效率大幅提升,缺点在于最终文件为.aof文件,在4.0版本之前不是被该aof文件,且由于前部分时RDB格式,阅读性差
3.你刚刚说AOF的文件很大,那AOF文件会越来越大?
AOF其实是有他的重写机制的,当AOF文件比上一次重写时的文件大小增长100%并且文件大小不小于64M时,会进行重写,重写时如果客户端发生修改操作,这边也是copy-on-write技术,重写时,新的变更操作会写到原AOF文件中,同时这些变更操作会被Redis收集,最差情况就和RDB一样,;两倍内存,当内存数据被全部写入到新的AOF文件后,新的变更操作会追加进去,此后所有新的操作会写到新的aof文件中,因为只有重写完成后才会更改写入文件,所以如果发生故障,不会影响到原来的aof文件,所有比较可靠