Redis支持RDB和AOF两种持久化机制
RDB
RDB持久化是把当前进程数据生成快照保存到硬盘的过程
这里涉及到了一个时点性的问题。当redis生成快照的时候,由于需要时间,并且对外服务不能停止,因此复制的过程中,数据在不断更新,因此当快照完成的时候,这个快照具体应该说成是哪个时点的数据就会很混乱。(正常应该说成是完成时点的数据)
那么如何解决这个时点混乱?redis采用的是fork + CopyOnWrite
- fork方法:在redis进程中创建一个子进程,这里要明确一个概念就是,进程之间是数据隔离的,因为进程都有自己的内存空间,但是对于父进程而言,它可以让子进程看到自己的数据。并且创建子进程速度快,占用空间小。
- CopyOnWrite:写时复制,子进程是由父进程复制而来,如果父进程对数据进行了写操作,那么父进程并不会在当前物理地址修改,而是指向另一个物理地址,修改另一个物理地址的值。这个复制过程是由子进程来做的,父进程该做什么做什么,并且由于进程隔离,子进程看到的永远是一个时点的数据。由此解决了时点混乱问题。
弊端
- 不支持拉链:只有一个dump.rdb
- 丢失的数据相对多一些,时点与时点之间窗口数据容易丢失
优点
- 类似java中的序列化
- 恢复速度相对快一些
AOF
AOF持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。
优点
- 丢失数据相对少
- redis中RDB和AOF可以同时开启,但是恢复文件时只会用AOF恢复,因为AOF中恢复的完整度高一些
弊端
- 体量无限增大,恢复很慢
解决:
1、4.0以前对日志进行重写,删除能抵消的命令,合并重复的命令,最终也是一个纯指令的日志文件
2、4.0以后重写时,将老的RDB数据写入AOF中,将增量的以指令的方式append到AOF中,利用了RDB的快以及AOF的日志完整性
redis是一个内存数据库,写的操作会触发I/O,redis默认关闭AOF,可通过修改配置文件中appendonly来开启AOF,redis支持三种AOF模型,在配置文件中表示为
- appendfsync always 每次I/O调一次flush 最可靠
- appendfsync everysec 每秒调一次flush 默认
- appendfsync no 不调flush