一. 为什么需要持久化
- 「概念回顾」:Redis是一个开源的,使用C语言编写的,支持集群、分布式、主从同步等配置的、
基于内存的
、可持久化的、单进程的、单线程的key-value框架。 - 「原因」:正因为Redis是基于
内存
的,所有的读写操作均在内存中进行,所以有着极高的性能,但是服务器重启会导致数据丢失,因此需要将内存中的数据存储到磁盘中,方便重启时能够从磁盘中恢复数据。
二. 持久化的方式
-
快照(RDB, Redis DataBase):周期性的把redis当前内存中的全量数据写入到一个快照文件中。如间隔1s写一次。
-
文件追加(AOF, Append Only File):用日志的形式记录服务器所处理的每一个修改操作(写入、删除);
-
混合持久化:
使用RDB来恢复内存状态,会丢失大量的数据;而重放AOF日志性能较差。
故Redis 4.0将二者混合使用,先用RDB持久化文件重新构建内存,再重放AOF日志,到达数据恢复和提高性能的效果。
三. RDB
-
原理
快照的持久化是基于操作系统的多进程COW机制(Copy On Write),在持久化时调用 glibc的函数fork()产生一个子进程fork,为节约内存资源,尽可能让子进程和父进程共享内存的数据和代码,子进程fork来处理持久化操作,父进程来处理客户端请求。 -
优点
只有一个文件dump.rdb,方便持久化;
COW机制实现了性能最大化。 -
缺点
数据安全性低;
当数据集较大时,可能会导致整个服务器卡顿过久。
四. AOF
-
原理
「修改数据」:当有修改请求到达Redis时,先进行参数校验,若通过则将修改指令存储到AOF日志(即磁盘),再进行修改操作;「恢复数据」:当服务器重启,可从AOF文件中恢复数据;
「AOF重写」:即AOF Rewrite,fork子线程遍历内存数据并将其转化为Redis指令,再序列化到一个新的AOF日志,若在此期间有新的命令,则加到新的AOF中,完成替换。
「fsync() 方法」:若内存缓存中的redis指令还没有来得及写到AOF文件中就宕机,fsync() 方法可以将指定文件的内容强制从内存缓存中刷写到磁盘上。但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据。
-
优点
数据安全性更高。 -
缺点
AOF文件比RDB文件大,且恢复速度慢。