赞
踩
redis的持久化过程
redis作为缓存,数据的持久化时怎么做的呢?
主要有两种方式:RDB和AOF
1.RDB
RDB的执行原理:
fork的概念
在Redis中,`fork`是一个非常重要的概念,它是一种创建子进程的方式。具体来说,`fork`主要用于创建一个与父进程完全相同的子进程,以便执行后续的操作。
Redis的持久化机制中,`fork`起着重要的作用。Redis会单独创建一个子进程来进行持久化,即先将数据写入到一个临时文件中,待持久化过程结束后,再将这个临时文件替换上次持久化后的文件。在这个过程中,`fork`函数的作用是复制一个与当前进程一样的进程,新进程的所有数据数值都和原进程一致,但它是一个全新的进程,并作为原进程的子进程。
值得注意的是,`fork`的过程中会使用一种叫做Copy-on-Write(COW)的技术。这是一种高效的复制技术,它允许父进程和子进程共享同一块内存空间,只有在需要修改时才进行实际的内存复制。这种技术大大提高了Redis持久化的效率,因为它减少了不必要的内存复制操作。
总的来说,`fork`在Redis中是一个非常重要的概念,它不仅用于创建子进程,还与Redis的持久化机制紧密相连,帮助Redis实现了高效率的数据持久化。
页表:在Linux系统中,所有的进程都没有办法直接操作物理内存。操作系统会给每个进程分配一个虚拟内存,操作系统会维护一个虚拟内存和物理内存之间关系的映射表,这个表就被称为页表。从而实现进程对物理内存的读写操作。
主进程和子进程是如何同步数据的呢?
由主进程fork而来的子进程拷贝了和主进程一样的页表。也就是说子进程有着和主进程相同的映射关系了。子进程在操作自己的虚拟内存时,由于映射关系和主进程是一样的。最终一定能映射到相同的物理内存!
子进程拿到页表后,就可以对物理内存进行读操作,并且把读到的数据写入磁盘,这是新的RDB文件会替换旧的文件。一般到这里就完成了异步持久化过程。
COW技术
问题:
但是,子进程在写RDB文件的过程中,主进程还是可以修改内存中的数据。如果这个时候主进程在修改数据,子进程同时在读写,就可能产生冲突,出现脏数据。
解决方案:
子进程与 Redis 进程共享内存中的数据,但是子进程并不会修改内存中的数据,而是不断的遍历读取写入文件中,但是 Redis 父进程则不一样,它需要响应客户端的命令对内存中数据不断地修改 (如果子线程在持久化数据,往往这时候最容易出问题) 。因此,我们在fork的时候就会把共享数据设置为read-only(只读数据)。假设主进程真的接收了写的请求,这个时候就会使用操作系统的 COW 机制来进行数据段页面的分离,当 Redis 父进程对其中某一个页面的数据进行修改时,则会将页面的数据复制一份出来,然后对这个复制页进行修改,这个时候子进程相应的数据页并没有发生改变,依然是 fork 那一瞬间的数据。页表的映射关系,也就会映射到新拷贝的物理数据上去 (下次子进程同步数据就是同步新的修改了的数据!)
2.AOF
两种持久化方式的比较:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。