天天看点

Redis的持久化机制(上)1 持久化概论

Redis最常用的场景就是做缓存,把DB数据存储在内存,然后直接从内存读数据,这样系统响应就会很快。

风险是一旦服务器宕机,内存中数据将全部丢失。

最简单的解决方案是从后端DB恢复这些数据,但注意:

  • 需要频繁访问DB,会给DB带来巨大压力
  • 这些数据是从慢速DB中读出来的,性能肯定比不上从Redis中读取,导致使用这些数据的应用程序响应变慢。

所以,对于Redis,实现数据持久化,避免从后端 DB进行恢复,很关键。

1 持久化概论

1.1 什么是持久化

redis所有数据保存在内存,对数据的更新将异步保存到磁盘。

持久化的意义:

主要是做灾难恢复、数据恢复,可归类到高可用。

比如你的Redis宕机,你要做的事情是让Redis变得可用,尽快变得可用!

重启Redis,尽快让它对外提供服务,若你没做数据备份,即使Redis启动了,数据都没了!有啥可用的?

而且很可能,大量请求过来,缓存全部无法命中,造成缓存雪崩。然后MySQL宕机,你都没法去找数据恢复到Redis里面去,Redis的数据从哪儿来?就是从MySQL来的!

若把Redis的持久化做好,备份和恢复方案也做到,那么即使你的Redis故障,也可通过备份数据,快速恢复,一旦恢复立即对外提供服务。

1.2 数据库持久化策略

数据库不关心故障

而是在数据文件损坏后从数据备份或快照中恢复

RDB 就是这种情况

数据库使用操作日志记录每个操作的操作行为

以在失败后通过日志恢复一致性。由于操作日志是按顺序追加写入的,因此不会出现无法恢复操作日志的情况

类似于 Mysql 的重做和撤消日志。

数据库不修改旧数据,而仅通过追加进行写入

因此数据本身就是日志,因此永远不会出现数据无法恢复的情况

CouchDB 是一个很好的例子。AOF 类似这种情况

1.2 持久化方式

RDB - 快照

按指定时间间隔执行数据集的时间点快照存储,类似于MySQL Dump的 frm 备份文件。

在Redis内部一个定时器事件,每隔固定时间去检查当前数据发生的改变次数与时间是否满足配置的持久化触发的条件,如果满足则通过操作系统fork调用来创建出一个子进程,这个子进程默认会与父进程共享相同的地址空间,这时就可以通过子进程来遍历整个内存来进行存储操作,而主进程则仍然可以提供服务,当有写入时由操作系统按照内存页(page)为单位来进行copy-on-write保证父子进程之间不会互相影响。

缺点是快照只是代表一段时间内的内存映像,所以系统重启会丢失上次快照与重启之间所有的数据。

AOF - 命令日志

记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据(MySQL 的 binlog)。

AOF 会记录服务器接收的每个写操作,这些操作将在服务器启动时再次执行,以重建原始数据集。使用与Redis协议本身相同的格式记录命令,并且仅采用append-only方式。当日志太大时,Redis可以在后台重写日志。类似于MySQL Binlog、Hbase HLog。在Redis重启时,通过回放日志中的写入指令来重构整个数据。

RDB与AOF混用

Redis4.0 开始的新特性。在混合使用中 AOF 读取 RDB 数据重建原始数据集,集二者优势为一体。

如果希望Redis仅作为纯内存的缓存来用,亦可禁用RDB和AOF。

可以在同一实例中同时使用AOF和RDB。这种情况下,当Redis重新启动时,AOF文件将用于重建原始数据集,因为它可以保证是最完整的。

最重要的是理解RDB与AOF持久性之间的不同权衡。如果同时使用RDB和AOF两种持久化机制,那么在Redis重启时,会使用AOF来重新构建数据,因为AOF中的数据更加完整!