Redis持久化2大机制:AOF和RDB。
持久化
Redis是内存数据库,为了防止重启/宕机后数据丢失,因此需要持久化。
RDB
从以下几个方面熟悉RDB。
- 什么是RDB
- RDB记录了什么
- RDB什么时候记录
- RDB有什么缺陷以及如何解决的
什么是RDB
RDB是内存快照,记录的是内存中的数据某一时刻的状态,以文件的形式写到磁盘上。
RDB记录了什么
记录的是某一时刻的数据。恢复数据时,只需要直接把RDB文件读入内存,很快完成恢复。
RDB什么时候记录
需要考量的因素,如果快照太频繁那么会产生额外的开销,如果快照频率太低会丢失数据。
RDB有什么需要考虑的问题以及如何解决的
问题:哪些数据做快照
对哪些数据进行快照这影响到了效率。 Redis采用全量快照。全量快照就是把所有数据都记录到磁盘中。全量快照产生的问题,写入RDB文件是否会阻塞主线程。
解决:bgsave创建子线程
Redis采用2个命令来生成RDB文件,默认bgsave。
bgsave:创建子进程,专门用于RDB文件,避免主线程阻塞。 save:主线程中执行,会导致阻塞。
问题:做快照时,数据能否修改
做快照时,数据还能被增删改吗?影响到是否被阻塞,能否同时正常处理请求。 如果对内存数据做快照时,数据还能修改,那么如何保证快照完整性;如果不能操作,那么性能降低了。
解决方案:借助操作系统的写时复制技术(Copy-On-Write)COW
在执行快照的同时,正常处理写操作。如果主线程要修改一块数据,那么这块数据会被复制一份,生成该数据的副本,主线程在副本上修改,子进程可以继续把原来的数据写入RDB文件。
问题:太频繁地进行全量快照会带来2方面的开销
- 会可能发生多个快照竞争磁盘带宽,前一个快照还没有做完,后一个又开始做了。
- bgsave子进程fork创建的过程本身是会阻塞主线程的。
解决:增量快照
做了1次全量快照后,后续快照只要对修改的数据进行快照记录。 那么如何记住哪些数据被修改了?需要额外的元数据信息去记录。
总结
RDB为了减少内存快照对正常读写的影响,设计了bgsave和写时复制方式。 虽然RDB比AOF快照恢复速度快,但是快照频率很难把握。Redis4.0中提出混合使用AOF和RDB,RDB以一定频率执行,2次快照之间使用AOF日志对着期间的命令进行操作。等到第二次做全量快照时就可以清空AOF日志了。
如果允许数据丢失,可以使用RDB。如果数据不能丢失,可以采用混合使用的方式。