当前位置: 首页> 科技> 数码 > 了解Redis数据持久化(中)

了解Redis数据持久化(中)

时间:2025/7/11 11:43:28来源:https://blog.csdn.net/huaqianzkh/article/details/141536298 浏览次数:0次

3.5写时复制

        Redis在使用RDB方式进行持久化时,会用到写时复制机制。写时复制的效果: bgsave子进程相当于复制了原始数据,而主线程仍然可以修改原来的数据。

        对Redis来说,主线程fork出bgsave子进程后,bgsave子进程实际是复制了主线程的页表。这些页表中,就保存了在执行bgsave命令时,主线程的所有数据块在内存中的物理地址。这样一来,bgsave子进程生成RDB时,就可以根据页表读取这些数据,再写入磁盘中。如果此时,主线程接收到了新写或修改操作,那么,主线程会使用写时复制机制。具体来说,写时复制就是指,主线程在有写操作时,才会把这个新写或修改后的数据写入到一个新的物理地址中,并修改自己的页表映射。

3.5.1写时复制底层原理

        bgsave子进程复制主线程的页表以后,假如主线程需要修改虚页7里的数据,那么,主线程就需要新分配一个物理页(假设是物理页53),然后把修改后的虚页7里的数据写到物理页53上,而虚页7里原来的数据仍然保存在物理页33上。这个时候,虚页7到物理页33的映射关系,仍然保留在bgsave子进程中。所以,bgsave子进程可以无误地把虚页7的原始数据写入RDB文件。

 

3.6每秒做一次RDB快照?

        快照时间越短,即使某一刻发生了宕机,上一刻的数据做了快照,损失的数据也不会太多。但是快照的间隔时间就很关键了。

        在T0时刻做了一次快照,在T0+t的时刻发生了宕机,进行数据恢复成T0那么5和9的数据就无法进行恢复了

        是不是可以每秒做一次快照?毕竟,每次快照都是由bgsave子进程在后台执行,也不会阻塞主线程。

解释:

        这种想法其实是错误的。虽然bgsave执行时不阻塞主线程,但是,如果频繁地执行全量快照,也会带来两方面的开销。

        一方面,频繁将全量数据写入磁盘,会给磁盘带来很大压力,多个快照竞争有限的磁盘带宽,前一个快照还没有做完,后一个又开始做了,容易造成恶性循环。

        另一方面,bgsave子进程需要通过fork操作从主线程创建出来。虽然,子进程在创建后不会再阻塞主线程,但是,fork这个创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。如果频繁fork出bgsave子进程,这就会频繁阻塞主线程了。那么,有什么其他好方法吗?

优缺点

        RDB快照快速恢复数据,但是生成RDB文件频率设置的低的话就可能会出现,丢失数据过多,生成RDB文件过快的话,又会增加额外的开销。

        频繁写入开销问题:

        频繁生成RDB文件写入磁盘,会造成磁盘压力过大,会出现上一个RDB还没有处理完,下一个RDB文件写入就已经开始了,造成死循环。
bgsave会调用glibc中,fork函数生成子进程,子进程会阻塞主线程,主线程内存越大,阻塞时间越长。子线程的创建本身是对主线程有阻塞的。

3.7RDB增量快照

        增量快照,所谓增量快照说的就是,做完一次快照之后,后续的快照只对修改的数据进行快照,这样可以避免每次全量快照的开销。

        比如对一万条数据进行了修改,你只需要记录这一万条修改数据的信息,就需要有1万条额外的记录,进入额外的空间开销比较大。

 

 

关键字:了解Redis数据持久化(中)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: