Redis 对外提供数据访问服务时,使用的是常驻内存的数据。如果仅将数据存在内存,一旦宕机重启,数据全部丢失。
redis所有数据保持在内存中,对数据的更新将异步地保存到磁盘上。持久化主要是做灾难恢复、数据恢复,可归类到高可用。
比如你的Redis宕机,你要做的事情是让Redis变得可用,尽快变得可用!
重启Redis,尽快让它对外提供服务,若你没做数据备份,即使Redis启动了,数据都没了!可用什么呢?
很可能说,大量的请求过来,缓存全部无法命中,在Redis里根本找不到数据,这个时候就造成缓存雪崩,就会去MySQL数据库去找,突然MySQL承接高并发,宕机!
MySQL宕机,你都没法去找数据恢复到Redis里面去,Redis的数据从哪儿来?就是从MySQL来的!
若你把Redis的持久化做好,备份和恢复方案也做到,那么即使你的Redis故障,也可通过备份数据,快速恢复,一旦恢复立即对外提供服务
Redis提供了两种持久化方式:
RDB 按指定时间间隔执行数据集的时间点快照。
AOF 会记录服务器接收的每个写操作,这些操作将在服务器启动时再次执行,以重建原始数据集。
如果同时使用RDB和AOF两种持久化机制,那么在Redis重启时,会使用AOF来重新构建数据,因为AOF中的数据更加完整!
Redis Server在有多db 中存储的K.V可理解为Redis的一个状态。当发生写操作时,Redis就会从一个状态切换到另外一个状态。基于全量的持久化就是在某个时刻,将Redis的所有数据持久化到硬盘中,形成一个快照。当Redis 重启时,通过加载最近一个快照数据,可以将 Redis 恢复至最近一次持久化状态上。
save 可以由客户端显示触发,也可在redis shutdown 时触发。save本身是单线程串行方式执行,因此当数据量大时,可能会发生Redis Server的长时间卡顿。但其备份期间不会有其他命令执行,因此备份时期 数据的状态始终是一致性的。
若存在老的RDB文件,则新的会替换老的,时间复杂度O(N)。
bgsave可由客户端显式触发,配置定时任务触发,主从架构下由从节点触发bgsave命令在执行时,会fork一个子进程。子进程提交完成后,会立即给客户端返回响应,备份操作在后台异步执行,期间不会影响Redis的正常响应。
对于bgsave来说,当父进程Fork完子进程之后,异步任务会将当前的内存状态作为一个版本进行复制 在复制过程中产生的变更,不会反映在这次备份当中。
在Redis的默认配置中,当满足下面任一条件,会自动触发 bgsave 的执行:
配置 | seconds | changes |
---|---|---|
save | 900 | 1 |
save | 300 | 10 |
save | 60 | 10000 |
bgsave相对于save的优势是异步执行,不影响后续命令执行。但Fork子进程,涉及父进程的内存复制,会增加服务器内存开销。当内存开销高到使用虚拟内存时,bgsave的Fork子进程会阻塞运行,可能会造成秒级不可用。因此使用bgsave需要保证服务器空闲内存足够。
命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
是否阻塞 | 阻塞 | 非阻塞 |
复杂度 | O(N) | O(N) |
优点 | 不会消耗额外内存 | 不阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 需要fork子进程,内存开销大 |
RDB对Redis对外提供的读写服务,影响非常小,可让Redis保持高性能,因为Redis主进程只要fork一个子进程,让子进程执行RDB
相对于AOF,直接基于RDB文件重启和恢复Redis进程,更加快速
耗时,O(n)
fork():耗内存,copy-on-write策略 RDB每次在fork子进程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,或者甚至数秒
不可控,容易丢失数据 一般RDB每隔5分钟,或者更长时间生成一次,若过程中Redis宕机,就会丢失最近未持久化的数据
RDB记录的是每个状态的全量数据,AOF记录的则是每条写命令的记录,通过所有写命令的执行,最后恢复出最终的数据状态。
always
每次刷新缓冲区,都会同步触发同步操作。因为每次的写操作都会触发同步,所以该策略会降低Redis的吞吐量,但该模式会拥有最高的容错能力。
every second
每秒异步的触发同步操作,为Redis的默认配置。
no
由操作系统决定何时同步,该方式下Redis无法决定何时落地,因此不可控。
对比
命令 | always | everysec | no |
---|---|---|---|
优点 | 数据零误差 | 性能较高 | 无需设置 |
缺点 | 性能较低 | 宕机丢失一秒数据 | 不可控 |
AOF重写
持久化方式 | RDB | AOF |
---|---|---|
占用内存空间 | 小(数据级:压缩) | 大(指令级:重写) |
存储速度 | 慢 | 快 |
恢复速度 | 快 | 慢 |
数据安全性 | 会丢失数据 | 依据策略决定 |
资源消耗 | 高 | 低 |
启动优先级 | 低 | 高 |
总结:
官方推荐两个都启用,如果对数据不敏感,可以选单独用RDB,不建议单独用 AOF,因为可能会出现 bug。
如果只是做纯内存缓存,可以都不用 。