Redis如何实现持久化(AOF、RDB、混合模式)的优缺点

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
日志服务 SLS,月写入数据量 50GB 1个月
简介: Redis如何实现数据不丢失Redis的读写操作都是在内存中,所以Redis性能才会高,但是当Redis重启后,内存中的数据就会丢失,那为了保存内存中的数据不会丢失,Redis实现了数据持久化机制,会把数据保存到磁盘,这样Redis重启就能够从磁盘恢复原有的数据

Redis如何实现数据不丢失


Redis的读写操作都是在内存中,所以Redis性能才会高,但是当Redis重启后,内存中的数据就会丢失,那为了保存内存中的数据不会丢失,Redis实现了数据持久化机制,会把数据保存到磁盘,这样Redis重启就能够从磁盘恢复原有的数据

Redis提供了三种数据持久化方式

AOF日志:每执行一条写操作命令就把该命令以追加的方式写入一个文件里

RDB快照:将某一时刻的内存数据以二进制的方式写入磁盘

混合持久化:集成了AOF与RDB的优点


AOF


AOF步骤

Redis在执行完一条命令后就会把该命令以追加的方式写到一个文件,然后Redis重启时,会读取该命令然后逐一执行命令的方式来进行数据恢复134afa3dbfc347a0aeea66e5c560e653.png

why先执行命令后写入磁盘?

避免额外的检查开销:因为如果先将写操作记录到AOF日志中,再执行该命令的话,如果当前命令有问题如果不检查的话,Redis使用该命令进行恢复的时候就可能会出错

不会阻塞当前写操作命令的执行:因为是在当前线程的写操作之后

  • 数据可能会丢失:当前线程执行完命令而还没有写入磁盘时就宕机了
  • 可能阻塞其它操作:因为记录AOF日志也是在主线程中执行,所以当Redis把日志写入磁盘时会阻塞后续的命令

AOF的写回策略

Always:每次写操作命令都会执行完后,同步AOF日志数据写回硬盘

Everysec:每次写操作命令执行完后,先写入AOF日志缓冲区,每秒写回磁盘

No:不由Redis控制写回磁盘,每次都写入AOF日志缓冲区,再由操作系统决定何时写回磁盘

27c09236c66d461ea1e16e0aebb80d61.png

AOF日志文件过大怎么办?


AOF日志是一个文件,随着写命令的执行,文件会越来越大,如果文件过大就会带来性能问题,比如AOF恢复中执行的命令就会很多就会导致恢复过程很慢

所以Redis提供了AOF重写机制,当AOF文件大小超过设定的阈值时AOF就会启用重写机制来压缩AOF文件,比如set name lixiaobo 与set name lidabo 就会设置为一条指令set name lidabo


重写AOF日志过程


Redis的重写AOF过程是由后台子进程bgwriteaof来完成的,这么做的好处:


1、子进程进行AOF重写期间,主进程可以继续处理命令请求,从而避免阻塞主进程

2、子进程带有父进程的数据副本,之所以不使用多线程是因为多线程会共享内存那么修改时候就需要加锁来保证数据安全而这样就会降低性能。而使用子进程,创建子进程时候父子进程是共享内存数据,而当父子进程任意一方修改就会发生写时复制


触发重写机制后,主进程会创建重写AOF的子进程,此时子进程只会对这个内存进行只读,重写AOF子进程会读取所有指令,并逐一把内存数据的键值对转换成另一条命令,再将命令记录到重写日志(新的AOF文件)

但是重写过程中,主进程依然可以正常处理命令,所以就出现了问题,如果主进程修改了已经存在的key-value,那么就会发生写时复制,此时这个key-value数据在子进程的内存数据就与主进程的内存数据不一样了

为了解决这种数据不一致,Redis设置了一个AOF重写缓冲区,这个缓冲区在创建bgwriteaof子进程之后开始使用

在重写AOF期间,当Redis执行完一个写命令之后,它会同时把这个写命令放入AOF缓冲区与AOF重写缓冲区

也就是说在bgwriteaof期间,主进程需要执行三个工作


1、 执行客户端发来的命令

2、将执行后的命令写入AOF缓冲区

3、将执行后的命令写入AOF重写缓冲区


当子进程重写完成之后会向主进程发送一条信号,信号是进程间通信的一种方式

主进程收到该信号后,会调用一个信号处理函数


1、将AOF重写缓冲区中的所有内容追加到新的AOF文件中,使得新旧两个AOF所保存的数据一致

2、新的AOF的文件进行改名,覆盖现有的AOF文件


442937bc9f6b4b3fad68ff93403d1349.png


RDB


RDB记录的是某一个瞬间的内存数据,记录的是实际数据,因此在数据恢复时,RDB恢复数据的效率比AOF高些

如何进行RDB

redis提供了两个命令来执行RDB

save:执行save会在主线程生成RDB文件,所以会阻塞主线程

bgsave:创建一个子进程来生成RDB文件,避免阻塞主线程


Redis的快照是全量快照,也就是每次执行快照都会把内存中的数据都记录到磁盘,所以这是一个比较重的操作


RDB执行快照时候数据能修改?


可以修改,在执行bgsave过程,Redis依旧可以继续处理操作命令,也就是数据是能被修改,关键技术还是写时复制


混合持久化


混合持久化步骤

AOF的优点是丢失数据少,但是数据恢复慢,而RDB是优点是恢复速度快而快照的频率不好把握,如果频率过低,数据丢失的量就比较多,如果频率高就会影响性能

所以退出了混合持久化集成两者优点,在AOF重写日志时,fork出来的子进程会把当前主线程共享的内存数据以RDB方式写入到AOF文件,然后主线程处理的命令被记录到重写缓冲区中,重写缓冲区中的命令会以追加AOF的形式存在AOF日志中

225c19b532ba4bf886564bfdd8e05a24.png

混合持久化的优缺点

优点

集成了AOF与RDB的优点

缺点

文件可读性变差

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6天前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
26天前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
27天前
|
存储 缓存 NoSQL
【Azure Redis 缓存 Azure Cache For Redis】如何设置让Azure Redis中的RDB文件暂留更久(如7天)
【Azure Redis 缓存 Azure Cache For Redis】如何设置让Azure Redis中的RDB文件暂留更久(如7天)
|
29天前
|
存储 NoSQL Redis
Redis 文件总大小问题之计算待加载AOF文件总大小如何解决
Redis 文件总大小问题之计算待加载AOF文件总大小如何解决
|
29天前
|
NoSQL Redis
Redis AOF重写问题之减少CPU和fork开销如何解决
Redis AOF重写问题之减少CPU和fork开销如何解决
|
29天前
|
NoSQL Redis
Redis 临时manifest修改问题之确保被持久化到磁盘如何解决
Redis 临时manifest修改问题之确保被持久化到磁盘如何解决
|
22天前
|
监控 NoSQL Redis
Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.
Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.
|
25天前
|
NoSQL Redis
【Azure Redis】Redis导入备份文件(RDB)失败的原因
【Azure Redis】Redis导入备份文件(RDB)失败的原因
|
25天前
|
缓存 NoSQL Redis
【Azure Redis 缓存】Azure Cache for Redis 服务的导出RDB文件无法在自建的Redis服务中导入
【Azure Redis 缓存】Azure Cache for Redis 服务的导出RDB文件无法在自建的Redis服务中导入
|
29天前
|
NoSQL Redis
Redis AOF重写问题之产生过多INCR AOF文件如何解决
Redis AOF重写问题之产生过多INCR AOF文件如何解决