Copy-On-Write

一 概述

Copy-On-Write,顾名思义为写时复制。

二 Copy-On-Write的实现

系统调用fork()系统调用创建进程,linux中的fork()系统调用实现Copy-on-Write写时复制,一般情况下,fork()系统调用会在创建子进程时,会将资源全部复制给子进程,这样效率比较低,而且有些资源对子进程没有用处。所以为了降低创建子进程的成本,Linux优化了fork()函数的实现方式,当父进程创建子进程时,内核只为子进程创建虚拟空间,且父子进程使用的时相同的物理空间,只有父子进程修改时,才会为子进程分配独立的物理空间。

Copy-On-Write:如果由多个调用者同时要求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容,系统才会真正复制一份专用副本给调用者,而其他调用者所见到的最初的资源仍然不变。

三 Copy-On-Write的核心思想及Redis的RDB持久化中应用

Copy-On-Write在处理过程中需要维持一个为读请求使用的指针,并在新数据写入完成后过更新这个指针,以提升读写并发能力,因此,Copy-On-Write也间接提供了读写过程中的原子性,在保持读写过程中的原子性的同时,还保持了一定的读写效率,当Redis需要做持久化时,Redis会fork一个子进程,子进程会将数据保存到磁盘上的一个临时的rdb文件中,当子进程完成临时的rdb的写操作之后会将原来的rdb替换掉,这样的好处就是可以实现copy-on-write,子进程继续接收其他请求,使得Redis的性能比较好,也就是说redis需要做持久化时,redis调用fork创建子进程,此时就存在了子进程与父进程,父进程继续处理client请求,而子进程将内存中的数据写入rdb文件中,由于OS(操作系统)的Copy-on-Write机制的存在,父子进程会共享相同的物理页面,当父进程处理写请求的时候,OS会为要修改的页面创建副本,而不是写共享的页面,所以子进程地址空间内的数据是fork时刻的整个数据库的一个快照,当子进程完成了临时文件的写入之后,用临时文件替换掉原来的快照文件,然后子进程退出,进而完成备份操作。

Redis在启动之后会自动加载已经存在的rdb文件中的数据。

值得注意的是:每次持久化都是将内存中的数据完整的写入磁盘一次,而不是同步增量的数据,当数据量很大写操作(set操作)的时候必然会引起磁盘的I/O操作从而影响性能。且由于快照功能是在一定间隔时间进行一次,可能会因为Redis宕机而丢失从当前至最近一次快照期间的数据,如果Redis不允许丢失任何修改的持久化操作时,就要使用AOF持久化方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值