深入浅出Redis(四):Redis基于RDB、AOF的持久化

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 深入浅出Redis(四):Redis基于RDB、AOF的持久化

引言

Redis是一款基于内存的键值对数据结构存储系统,Redis基于内存且常用来缓存关系型数据库中的数据,但不代表着Redis不能进行持久化,本篇文章将深入浅出的说明Redis基于RDB和AOF的持久化方式

Redis支持两种持久化方式,RDB(Redis Database )是基于快照的方式,在服务端初始化时根据快照RDB文件进行数据恢复,而AOF(Append Of File)是记录命令的方式,在服务端初始化时使用AOF伪客户端通过AOF文件依次发送命令,服务端来执行以此来恢复数据

RDB

RDB文件格式

RDB文件是二进制数据,格式主要分为数据内容和其他信息

databases字段包含多个数据库的数据,其中selectdb 0用于切换数据库,key_value_pairs用于保存数据类型(type),键值对数据(key,value),如果是过期数据则会有记录到期时间(expiretime ms)

其他数据包括REDIS用于该文件是否为RDB文件、db_version表示版本号、EOF在databases字段后表示数据内容结束、check_sum用于校验RDB文件是否损坏

image.png

RDB原理

使用save命令主进程生成RDB文件,造成对主进程的阻塞,所以不会使用这种命令

使用bgsave命令fork子进程进行持久化,子进程通过遍历数据库读取数据文件写入RDB文件,在此期间父进程可能接收写操作,写操作时使用Copy on write技术

Copy On Write:父进程fork子进程时,是将父子进程共享数据,共享数据是只读的,当要发生写操作时会触发中断,并将页数据复制生成副本给予子进程;COW有效避免了创建子进程时复制父进程数据,而是直接共享父进程数据,当发生写操作时发生中断生成副本给子进程,如果写操作太多也可能导致频繁生成副本

在实际情况中,我们也不会手动执行bgsave,而是在配置文件中进行配置,当满足条件时执行bgsave

配置save 60 10000 服务端会维护 修改累计次数和上次RDB时间 数据,定期检查如果满足60s有1W次写操作就自动执行bgsave,生成RDB文件后更新这俩个数据

注意:为了禁止RDB开销过大,会禁止同时生成RDB、AOF文件

RDB恢复数据

当服务端启动时,自动判断RDB文件是否存在,存在则使用RDB文件恢复数据,注意RDB文件要在Redis启动目录

将Redis服务进程杀死后重启,数据自动恢复

image.png

AOF

AOF默认是不开启的,在配置文件中使用yes启动,启动AOF代表着优先使用AOF而不是RDB

 #默认不开启aof模式
 appendonly no 
 #持久化文件名字
 appendfilename "appendonly.aof" 

AOF文件格式

AOF文件存储序列化后的写命令

 #*5表示该命令有5个字符   $5表示字符串长度 
 #命令为:RPUSH setresult tom-result cc-result jack-result
 *5
 $5
 RPUSH
 $9
 setresult
 $10
 tom-result
 $9
 cc-result
 $11
 jack-result

AOF原理

bgrewriteaof命令也是使用COW,fork子进程来遍历数据库记录序列化的写命令,在此期间父进程处理写命令后将写命令加入AOF缓冲区,再子进程完成AOF文件后整合AOF缓冲区中的写命令

实际也不会手动使用bgrewriteaof来生成AOF文件,根据配置文件中配置的策略来决定每次写操作

在事件循环中执行写命令会将写命令放入AOF缓冲区,在本次事件循环结束前将AOF缓冲区写入文件系统中(page cache),根据不同的策略有不同的时机刷盘(page cache的数据写入磁盘)

默认下使用everysec 每秒刷盘策略,如果发生宕机只会丢失一秒的数据,大多数情况下也使用的是这种策略

使用always 将会每次执行写命令进行刷盘,虽然不会丢失数据,但性能开销最大

使用no 将不会处理,将刷盘的时机交给OS处理,这也是性能最高的策略

如果业务不允许数据丢失则可以选择always策略;如果只是用Redis充当缓存,保存的数据库中都有,追求性能则可以选择no ;如果用Redis保存库中没有的数据且允许一秒丢失可以选择默认的everysec策略

 ​
 #每次修改都会同步,消耗性能
 #appendfsync always     
 ​
 #每秒同步一次,可能丢失这一秒的数据
 appendfsync everysec    
 ​
 #不同步,这时操作系统自己同步数据,速度最快
 #appendfsync no       
 ​
 no-appendfsync-on-rewrite no
 #自动执行AOF重写时,当前AOF大小(即aof_current_size)和上一次重写时AOF大小(aof_base_size)的比值
 auto-aof-rewrite-percentage 100 
 #执行AOF重写时,文件的最小体积,默认值为64MB
 auto-aof-rewrite-min-size 64mb 

AOF重写

AOF文件记录序列化后的写命令,体积占用比快照RDB文件大的多,但记录很多写记录时会导致体积非常大

写命令可能存在对键值对进行“覆盖”的操作

 #命令1
 set name caicai 
 #命令2
 set name cl
 ...
 #命令n
 set name liangzai

对于以上的键name来说,最终的值为liangzai,但是没有作用的命令1、2也记录在AOF文件中

当AOF体积与上次重写文件体积超过设置的比例时,对AOF文件进行重写“瘦身”压缩,也就是去除类似命令1、2这种命令

 #自动执行AOF重写时,当前AOF大小(即aof_current_size)和上一次重写时AOF大小(aof_base_size)的比值
 auto-aof-rewrite-percentage 100 
 #执行AOF重写时,文件的最小体积,默认值为64MB
 auto-aof-rewrite-min-size 64mb 

AOF恢复数据

当配置文件中开启AOF时就不再使用RDB恢复数据,RDB与AOF只能开启一种

在服务端启动时,使用AOF伪客户端发送命令给服务端,将AOF文件中的命令都执行一遍

需要注意的是AOF文件被恶意修改时,再启动redis客户端是无效的

使用redis-check-aof --fix 要修复的文件来进行修复,修复后会丢失被破坏的数据(假如我在appendonly.aof文件中修改了某个key,那就没有这个key的数据)

 [root@liang bin]# redis-check-aof --fix appendonly.aof 
 0x              30: Expected \r\n, got: 3131
 AOF analyzed: size=238, ok_up_to=23, diff=215
 This will shrink the AOF from 238 bytes, with 215 bytes, to 23 bytes
 Continue? [y/N]: y
 Successfully truncated AOF

总结

本篇文章围绕Redis的持久化,深入浅出的解析了RDB文件格式、执行原理、COW、恢复数据以及AOF文件格式、执行原理、重写、恢复数据等

RDB文件是默认情况下使用的持久化策略,常在配置文件中配置自动生成RDB的规则,在生成RDB时使用fork子进程与COW避免阻塞,是一种体积小恢复快的快照文件,但会丢失最后一次生成RDB文件后的写命令

COW让fork出的子进程不用复制资源,而是与父进程共享资源,当处理读操作时共享资源,只有感知到写操作时,发生页中断,将页中数据复制生成一份副本给子进程(父子进程都持有一份)

开启AOF持久化后优先使用AOF持久化,父进程处理写命令后将命令放入AOF缓冲区再放入文件系统pagecache中,根据不同刷盘策略有不同刷盘时机(默认每秒,no不管OS处理,always每次刷盘),文件中记录序列化后的写命令,体积太大时会执行AOF重做,恢复数据时由伪客户端发送AOF文件中所有命令,是一种体积大,恢复慢的文件,根据不同刷盘策略有不同的数据丢失量和性能损耗(成反比)

最后

  • 参考资料
  • 《Redis深度历险》
  • 《Redis设计与实现》


相关实践学习
基于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
相关文章
|
5天前
|
存储 监控 负载均衡
保证Redis的高可用性是一个涉及多个层面的任务,主要包括数据持久化、复制与故障转移、集群化部署等方面
【5月更文挑战第15天】保证Redis高可用性涉及数据持久化、复制与故障转移、集群化及优化策略。RDB和AOF是数据持久化方法,哨兵模式确保故障自动恢复。Redis Cluster实现分布式部署,提高负载均衡和容错性。其他措施包括身份认证、多线程、数据压缩和监控报警,以增强安全性和稳定性。通过综合配置与监控,可确保Redis服务的高效、可靠运行。
27 2
|
5天前
|
NoSQL 安全 Unix
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅(中)
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅
16 0
|
3天前
|
NoSQL 算法 Java
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
【redis源码学习】持久化机制,java程序员面试算法宝典pdf
|
5天前
|
存储 NoSQL 关系型数据库
【Redis】Redis的特性和应用场景 · 数据类型 · 持久化 · 数据淘汰 · 事务 · 多机部署
【Redis】Redis的特性和应用场景 · 数据类型 · 持久化 · 数据淘汰 · 事务 · 多机部署
15 0
|
5天前
|
存储 NoSQL 调度
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅(下)
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅
10 0
|
5天前
|
存储 NoSQL API
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅(上)
Redis源码、面试指南(4)单机数据库、持久化、通知与订阅
18 1
|
5天前
|
存储 NoSQL 算法
Redis持久化&Redis主从
Redis持久化&Redis主从
14 0
|
5天前
|
NoSQL Redis 数据库
【Redis】RDB和AOF
【Redis】RDB和AOF
|
5天前
|
NoSQL 关系型数据库 MySQL
Redis持久化机制 RDB 和 AOF 的选择
Redis持久化机制 RDB 和 AOF 的选择
60 0
|
5天前
|
存储 缓存 NoSQL
Redis之持久化(RDB和AOF)
Redis之持久化(RDB和AOF)