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

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
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
相关文章
|
6天前
|
存储 缓存 NoSQL
Redis中的rdb和aof
本文深入探讨了Redis的持久化机制,包括RDB和AOF两种方式。详细解释了RDB的工作原理、优势和劣势,以及AOF的实现原理、配置选项、文件重写机制和三种数据同步方式,还介绍了AOF文件修复工具redis-check-aof的使用,并通过实例展示了如何开启和配置AOF持久化方式。
Redis中的rdb和aof
|
20天前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
3天前
|
存储 缓存 NoSQL
Redis 大 Key 对持久化的影响及解决方案
Redis 大 Key 对持久化的影响及解决方案
11 1
|
3天前
|
存储 NoSQL 安全
8)详解 Redis 的配置文件以及数据持久化
8)详解 Redis 的配置文件以及数据持久化
9 0
|
3天前
|
存储 NoSQL Redis
Redis的RDB快照:保障数据持久性的关键机制
Redis的RDB快照:保障数据持久性的关键机制
11 0
|
3天前
|
存储 缓存 NoSQL
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
13 0
|
2月前
|
监控 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.
|
5月前
|
NoSQL Redis
03- Redis的数据持久化策略有哪些 ?
Redis的数据持久化包括两种策略:RDB(全量快照)和AOF(增量日志)。RDB在指定时间间隔将内存数据集保存到磁盘,而AOF记录所有写操作形成日志。从Redis 4.0开始,支持RDB和AOF的混合持久化,通过设置`aof-use-rdb-preamble yes`。
51 1
|
3月前
|
canal 缓存 NoSQL
Redis常见面试题(一):Redis使用场景,缓存、分布式锁;缓存穿透、缓存击穿、缓存雪崩;双写一致,Canal,Redis持久化,数据过期策略,数据淘汰策略
Redis使用场景,缓存、分布式锁;缓存穿透、缓存击穿、缓存雪崩;先删除缓存还是先修改数据库,双写一致,Canal,Redis持久化,数据过期策略,数据淘汰策略
Redis常见面试题(一):Redis使用场景,缓存、分布式锁;缓存穿透、缓存击穿、缓存雪崩;双写一致,Canal,Redis持久化,数据过期策略,数据淘汰策略
|
4月前
|
存储 缓存 JSON
Redis-持久化-淘汰机制-IO策略
Redis-持久化-淘汰机制-IO策略
下一篇
无影云桌面