Skip to main content
  1. internet/

Redis持久化机制实现

·868 words·2 mins·

Redis使用内存进行数据的读写,如果服务永不崩溃、服务器不会宕机——Redis服务永远正常运行,那么数据就不需要落盘。但目前的技术水平还不能达到这一水准,因此我们还是需要将数据存储到磁盘上,当服务重启时就可以加载这些数据。

RDB #

我们可以将内存中的数据直接copy到磁盘中,这种持久化方式就是RDB

为了防止已经copy到磁盘中的数据被用户修改,在copy过程中,Redis服务需要拒绝写操作,比如将用户请求先放入队列中,一旦copy结束再从队列中获取请求进行执行。但是这样需要考虑很多场景、条件,Redis本着简单、高效的准则,采用了最简单粗暴的方式——拒绝外部请求。

但是拒绝外部请求会导致服务不可用,这是我们不能接受的,因此在copy时Redis服务会fork出一个子进程,fork完之后,父进程就可以继续工作,由子进程来进行copy。(copy on write。。。)

AOF(Append Only File) #

RDB持久化最明显的缺点就是缺乏实时性,为了弥补这一点,Redis仿照文件追加的方式设计了AOF持久化——每执行一条写命令,就将该命令写到磁盘中。为了减少磁盘IO(毕竟太慢了),Redis需要先将命令写入到缓冲队列(aof_buf)中,然后再同步到磁盘中。(事件循环?)

“同步到磁盘”有三种方式

  • 将缓冲队列中的数据直接写入并同步(fsync)到文件中。
  • 将缓冲队列中的数据写入到文件中,并每隔一秒进行一次同步。
  • 将缓冲队列中的数据写入到文件中,同步操作由操作系统控制。

AOF重写 #

随着命令的增多,AOF文件越来越大,为了解决AOF文件膨胀问题,Redis提供了文件重写功能。

一个key往往对应着多条命令,为了找到key对应的数据,直接读取内存会更方便。因此,AOF重写的过程就是将内存中的数据copy到AOF文件的过程。在copy过程中,为了Redis对外提供服务,因此fork出子进程来实现AOF重写,同时,写命令会存入AOF缓冲区和AOF重写缓冲区分别用于现有AOF文件的同步和AOF重写。重写完成后会将新AOF文件覆盖旧AOF文件。