copy-on-write 写时复制

最近在读一些关于虚拟化的论文,里面大都提到了一个copy-on-write的技术。

Copy-on-Write 简单来说是,复制一个对象时,不是真正的在内存中开辟一块新的地址,将原来的对象复制到新地址,而是在新对象的内存映射表(Translation Table)中指向同原对象相同的位置,并且把那块内存的copy-on-write位设置为1,在对这个对象执行读操作的时候,内存数据没有变动,直接执行就可以了。但是执行写操作的时候,才将原对象复制一份到新地址,并且同时修改新对象的内存映射表到这个新位置,然后在进行写入操作。Copy-on-Write是建立在virtual memory 和paging的基础上实现,优点比较显而易见:节省内存空间,复制对象并不真正复制,相当于只建立了一个指针。但是该技术只能适用于一小部分内存的page上,如果在复制新对象以后,大部分对象都还需要继续进行写操作 就会产生大量的分页错误,得不偿失。

如果需要改写一个重要文件,很多时候,我们要对原始数据进行备份,然后对原文内容进行修改,这样可以防止修改错误无法恢复到原来正确的状态,也防止计算机突然断电照成数据不一致。确定修改无误,则把备份文件删除,然后把修改后的文件在复制一份作为本分,再在当前的基础上进行修改。。。如果文件大小比较小,一般的版本控制工具都可以胜任,但是如果数据很大(虚拟机镜像,数据库文件等),每次修改都要复制一遍或者比较上一个版本,这样做费时费力。

复制技术:

1:快照(snapshot)

快照技术既是要备份的原始文件进行拍照,把某一时刻的状态保存起来。 这样后续如果更改错误的话,可以rollback回去。比如VMware提供了一个snapshot功能,当我们卸载或者装载某个软件后,又想恢复到以前的历史状态,我们可以先对虚拟机做一个快照。一般来说,快照功能都是虚拟机或者数据库自己实现,文件系统的快照一般都卷管理器实现。新出现的现代文件系统,zfs,btrfs,除了文件系统的基本功能以外还有快照和卷管理功能。快照虽然安全便捷,但是也引发了很多问题,因为rollback需要一定的时间,而且rollback的状态有时会出现问题,因此,对于实时性要求比较高的系统,一般不采用snapshot技术。

2:Copy-on-Write (写时复制)

当多个用户共享一块相同的数据时,如果其中某个用户要求对数据进行修改,系统会把这块数据复制一份然后进行修改,修改完成后让该用户的记录指向新修改的数据,其他用户看到的还是原来的数据而该用户看到的是已经修改的数据。 如果数据不写只读的话,不会被复制,这样可以节省存储空间。

对于快照技术来说,写时复制是一个必须的功能,例如虚拟机文件,保存了快照之后要基于快照之上进行读写。但是虚拟机文件很大,如果只修改其中一部分的话,没必要将整个虚拟机文件修改,这样才用写时复制可以使不同状态的多个虚拟机共享大部分相同的数据块。

“Stability in a Persistent Store Based on a Large Virtual Memory” 使用了一种内存地址转换的方法,为每个数据块分配一个逻辑地址,另外还有一个逻辑地址到实际地址的映射表,访问数据块内容的时候要从映射表中找到实际的地址,这样建立快照的时候,只需要修改映射表就ok了。坏处是映射表难以维护,地址转换也降低了性能。


reference:

 http://ouonline.net/b-plus-tree-2



你可能感兴趣的:(copy-on-write 写时复制)