从源码解读从源码解读redis持久化持久化
为什么需要持久化?为什么需要持久化?
由于Redis是一种内存型数据库,即服务器在运行时,系统为其分配了一部分内存存储数据,一旦服务器挂了,或者突然宕机
了,那么数据库里面的数据将会丢失,为了使服务器即使突然关机也能保存数据,必须通过持久化的方式将数据从内存保存到
磁盘中。
对于进行持久化的程序来说,数据从程序写到计算机的磁盘的流程如下:
1、客户端发送一个写指令给数据库(此时数据在客户端的内存)
2、数据库接收到写的指令以及数据(数据此时在服务端的内存)
3、数据库发起一个系统调用,把数据写到磁盘(此时数据在内核的内存)
4、操作系统把数据传输到磁盘控制器(数据此时在磁盘缓存中)
5、磁盘控制器执行真正写入数据到物理媒介的操作(如磁盘)
如果只是考虑数据库层面,数据在第三阶段之后就安全了,在这个时候,系统调用已经发起了,即使数据库进程奔溃了,系统
调用会继续进行,也能顺利将数据写入到磁盘中。 在这一步之后,在第4步内核会将数据从内核缓存保存到磁盘缓存中,但为
了系统的效率问题,默认情况下不会太频繁地执行这个动作,大概会在30s执行一次,这就意味着如果这一步失败了或者就在
进行这一步的时候服务器突然关机了,那么就可能会有30s的数据丢失了,这种比较普通的灾难性问题也是需要考虑的。
POSIX API也提供了一个系统调用让内核强制将缓存数据写入到磁盘中,比较常见的就是fsync系统调用。
int fsync(int fd);
fsync函数只对由文件描述符fd指定的一个文件起作用,并且等待写磁盘操作结束后才返回。每次调用fsync时,会初始化一个
写操作,然后把缓冲区的数据写入到磁盘中。fsync()函数在完成写操作的时候会阻塞进程,如果其他线程也在写同一个文件,
它也会阻塞其他线程,直到完成写操作。
持久化持久化
持久化是将程序数据在持久状态和瞬时状态间转换的机制。对于程序来说,程序运行中数据是在内存的,如果没有及时同步写
入到磁盘,那么一旦断电或者程序突然奔溃,数据就会丢失了,只有把数据及时同步到磁盘,数据才能永久保存,不会因为宕
机影像数据的有效性。而持久化就是将数据从程序同步到磁盘的一个动作过程。