上一篇文章中,AOF虽然可以通过重写机制减少AOF文件的大小,但是AOF数据恢复的时候依然是一个很耗费时间的操作,那么也就是不能够快速的进行数据的恢复,RDB正好可以解决这个问题。
RDB
RDB(Redis 数据库):RDB 持久性以指定的时间间隔执行数据集的时间点快照。
以上是官网原话,其实解读一下按照一定的时间间隔,进行数据的快照备份,内存快照:内存中的数据在某一时刻的状态。
那么AOF和RDB的区别是什么,AOF记录的是对数据的操作,比如set rpop等,而RDB记录的是某一时刻内存数据的数据,也就是数据A是什么B是什么。
那些数据做快照
那么RDB对那些内存中的数据进行快照处理的,答案是全量快照,那么其实如果全量快照的时候,会不会阻塞主线程对增量数据的处理呢,以此阻塞主线程。
Redis提供两个命令生成RDB文件
- save : 在主线程中执行,会阻塞。
- bgsave : 创建一个子进程,专门生成RDB文件,可以避免主线程的阻塞。
一般来说通过bgsave进行全量快照,这即执行了全量快照,也可以保证数据的可靠性,对性能也不会有影响。
写时复制机制
我们直到在通过bgsave命令执行RDB文件的生成的时候,其实存在一个问题,那就是对于实时增量请求数据可以进行数据的修改嘛,那么如果不能修改的话,其实相当于在备份RDB文件过程中,整个系统只能提供只读服务,这对于大多数的业务场景是不允许的。那么Redis是如何解决这个问题的?
其实核心原理比较简单,也就是Redis采用了写时复制,我们都知道Java集合类中有CopyOnWriteArrayList,其实也是同样的原理。
bgsave是由主线程fork生成的,可以共享主线程的所有内存数据,bgsave子进程运行后,可以读取主线程的内存数据。并写入到RDB文件中。
如果主线程接受到新的读请求,因为读请求不会修改数据,所以对于bgsave生成的RDB文件数据不会有影响,但是如果是写请求的时候,主线程会生成一个这个数据的副本,在副本上进行操作,bgsave线程继续读取主线程的数据。这样就可以实现在写时复制保证快照期间数据可修改。
小结
本篇主要简短的介绍了RDB机制,为了允许在生成快照的时候可以修改数据,引入了写时复制机制,但是频繁的快照其实也不好,最好的方式是RDB和AOF进行混合使用。