首页 > 数据库 >Redis持久化机制

Redis持久化机制

时间:2023-10-31 15:04:34浏览次数:39  
标签:文件 持久 AOF 过期 Redis key RDB 化机制

持久化机制

通常来说,应该同时使用两种持久化方案,以保证数据安全:

  • 如果数据不敏感,且可以从其他地方重新生成,可以关闭持久化

  • 如果数据比较重要,且能够承受几分钟的数据丢失,比如缓存等,只需要使用RDB即可

  • 如果是用做内存数据,要使用Redis的持久化,建议是RDB和AOF都开启

  • 如果只用AOF,优先使用everysec的配置选择,因为它在可靠性和性能之间取了一个平衡

当RDB与AOF两种方式都开启时,Redis会优先使用AOF恢复数据,因为AOF保存的文件比RDB文件更完整

RDB模式(内存快照)

RDB(Redis Database Backup File,Redis数据备份文件)持久化方式:是指用数据集快照的方式半持久化模式记录 Redis 数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。

优点

  • RDB快照是一个压缩过的非常紧凑的文件。保存着某个时间点的数据集,适合做数据的备份,灾难恢复

  • 可最大化Redis的的性能。在保存RDB文件,服务器进程只需要fork一个子进程来完成RDB文件创建,父进程不需要做IO操作

  • 与AOF相比,恢复大数据集的时候会更快

缺点

  • RDB的数据安全性是不如AOF的,保存整个数据集的过程是比繁重的,根据配置可能要几分钟才快照一次,如果服务器宕机,那么就可能丢失几分钟的数据

  • Redis数据集较大时,fork的子进程要完成快照会比较耗CPU、耗时

① 创建

当 Redis 持久化时,程序会将当前内存中的数据库状态保存到磁盘中。创建 RDB 文件主要有两个 Redis 命令:SAVEBGSAVE

Redis-RDB-创建

② 载入

服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。

Redis-RDB-载入

save同步保存

save 命令是同步操作,执行命令时,会 阻塞 Redis 服务器进程,拒绝客户端发送的命令请求。

具体流程如下:

Redis-RDB-Save命令

由于 save 命令是同步命令,会占用Redis的主进程。若Redis数据非常多时,save命令执行速度会非常慢,阻塞所有客户端的请求。因此很少在生产环境直接使用SAVE 命令,可以使用BGSAVE 命令代替。如果在BGSAVE命令的保存数据的子进程发生错误的时,用 SAVE命令保存最新的数据是最后的手段。

bgsave异步保存

bgsave 命令是异步操作,执行命令时,子进程执行保存工作,服务器还可以继续让主线程处理客户端发送的命令请求。

具体流程如下:
Redis-RDB-BgSave命令

Redis使用Linux系统的fock()生成一个子进程来将DB数据保存到磁盘,主进程继续提供服务以供客户端调用。如果操作成功,可以通过客户端命令LASTSAVE来检查操作结果。

自动保存

可通过配置文件对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动进行数据集保存操作:

# RDB自动持久化规则
# 当 900 秒内有至少有 1 个键被改动时,自动进行数据集保存操作
save 900 1
# 当 300 秒内有至少有 10 个键被改动时,自动进行数据集保存操作
save 300 10
# 当 60 秒内有至少有 10000 个键被改动时,自动进行数据集保存操作
save 60 10000

# RDB持久化文件名
dbfilename dump-<port>.rdb

# 数据持久化文件存储目录
dir /var/lib/redis

# bgsave发生错误时是否停止写入,通常为yes
stop-writes-on-bgsave-error yes

# rdb文件是否使用压缩格式
rdbcompression yes

# 是否对rdb文件进行校验和检验,通常为yes
rdbchecksum yes

默认配置

RDB 文件默认的配置如下:

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
# 在给定的秒数和给定的对数据库的写操作数下,自动持久化操作。
#  save <seconds> <changes>
# 
save 900 1
save 300 10
save 60 10000
#bgsave发生错误时是否停止写入,一般为yes
stop-writes-on-bgsave-error yes
#持久化时是否使用LZF压缩字符串对象?
rdbcompression yes
#是否对rdb文件进行校验和检验,通常为yes
rdbchecksum yes
# RDB持久化文件名
dbfilename dump.rdb
#持久化文件存储目录
dir ./

AOF模式(日志追加)

AOF(Append Only File,追加日志文件)持久化方式:是指所有的命令行记录以 Redis 命令请求协议的格式完全持久化存储保存为 aof 文件。Redis 是先执行命令,把数据写入内存,然后才记录日志。因为该模式是只追加的方式,所以没有任何磁盘寻址的开销,所以很快,有点像 Mysql 中的binlog,AOF更适合做热备。

Redis-AOF

优点

  • 数据更完整,安全性更高,秒级数据丢失(取决fsync策略,如果是everysec,最多丢失1秒的数据
  • AOF文件是一个只进行追加的日志文件,且写入操作是以Redis协议的格式保存的,内容是可读的,适合误删紧急恢复

缺点

  • 对于相同的数据集,AOF文件的体积要大于RDB文件数据恢复也会比较慢
  • 根据所使用的fsync策略,AOF的速度可能会慢于RDB。 不过在一般情况下,每秒fsync的性能依然非常高

持久化流程

Redis-AOF持久化流程

① 命令追加

若 AOF 持久化功能处于打开状态,服务器在执行完一个命令后,会以协议格式将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾。

② 文件同步

服务器每次结束一个事件循环之前,都会调用 flushAppendOnlyFile 函数,这个函数会考虑是否需要将 aof_buf 缓冲区中的内容写入和保存到 AOF 文件里。flushAppendOnlyFile 函数执行以下流程:

  • WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件;
  • SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。

这个函数是由服务器配置的 appendfsync 的三个值:always、everysec、no 来影响的,也被称为三种策略:

  • always:每条命令都会 fsync 到硬盘中,这样 redis 的写入数据就不会丢失。

Redis-AOF-Always

  • everysec每秒都会刷新缓冲区到硬盘中(默认值)。

    Redis-AOF-Everysec

  • no:根据当前操作系统的规则决定什么时候刷新到硬盘中,不需要我们来考虑。

Redis-AOF-No

数据加载

  • 创建一个不带网络连接的伪客户端

  • 从 AOF 文件中分析并读取出一条写命令

  • 使用伪客户端执行被读出的写命令

  • 一直执行步骤 2 和 3,直到 AOF 文件中的所有写命令都被处理完毕为止

文件重写

为何需要文件重写

  • 为了解决 AOF 文件体积膨胀的问题

  • 通过重写创建一个新的 AOF 文件来替代现有的 AOF 文件,新的 AOF 文件不会包含任何浪费空间的冗余命令

文件重写的实现原理

  • 不需要对现有的 AOF 文件进行任何操作

  • 从数据库中直接读取键现在的值

  • 用一条命令记录键值对,从而代替之前记录这个键值对的多条命令

后台重写

为不阻塞父进程,Redis将AOF重写程序放到子进程里执行。在子进程执行AOF重写期间,服务器进程需要执行三个流程:

  • 执行客户端发来的命令

  • 将执行后的写命令追加到 AOF 缓冲区

  • 将执行后的写命令追加到 AOF 重写缓冲区

Redis-AOF-后台重写

默认配置

AOF 文件默认的配置如下:

############################## APPEND ONLY MODE ###############################
#开启AOF持久化方式
appendonly no
#AOF持久化文件名
appendfilename "appendonly.aof"
#每秒把缓冲区的数据fsync到磁盘
appendfsync everysec
# appendfsync no
#是否在执行重写时不同步数据到AOF文件
no-appendfsync-on-rewrite no
# 触发AOF文件执行重写的增长率
auto-aof-rewrite-percentage 100
#触发AOF文件执行重写的最小size
auto-aof-rewrite-min-size 64mb
#redis在恢复时,会忽略最后一条可能存在问题的指令
aof-load-truncated yes
#是否打开混合开关
aof-use-rdb-preamble yes

AOF文件格式说明

# CRLE为为换行,结尾均以回车符\r和换行符\n结尾
*3CRLE       # *3表示有3个参数,命令本身也是参数的一部分,而且总是第一个参数
$3CRLE       # 第一个参数的字节数,对应于SET命令字长度
SETCRLE      # 第一个参数,总是为命令本身
$5CRLE       # 第二个参数长度,5表示第二个参数长度为5字节
mykeyCRLE    # 第二个参数值
$7CRLE       # 第三个参数长度为7字节
myvalueCRLE  # 第三个参数值

过期策略

过期策略用于处理过期缓存数据。Redis采用过期策略:惰性删除 + 定期删除。memcached采用过期策略:惰性删除

定时过期

每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即对key进行清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。

惰性过期

只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。

定期过期

每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。expires字典会保存所有设置了过期时间的key的过期时间数据,其中 key 是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。

淘汰策略

Redis淘汰机制的存在是为了更好的使用内存,用一定的缓存丢失来换取内存的使用效率。当Redis内存快耗尽时,Redis会启动内存淘汰机制,将部分key清掉以腾出内存。当达到内存使用上限超过maxmemory时,可在配置文件redis.conf中指定 maxmemory-policy 的清理缓存方式。

# 配置最大内存限制
maxmemory 1000mb
# 配置淘汰策略
maxmemory-policy volatile-lru

LRU(最近最少使用)

  • volatile-lru:从已设置过期时间的key中,挑选最近最少使用(最长时间没有使用)的key进行淘汰
  • allkeys-lru:从所有key中,挑选最近最少使用的数据淘汰

LFU(最近最不经常使用)

  • volatile-lfu:从已设置过期时间的key中,挑选最近最不经常使用(使用次数最少)的key进行淘汰
  • allkeys-lfu:从所有key中,选择某段时间内内最近最不经常使用的数据淘汰

Random(随机淘汰)

  • volatile-random:从已设置过期时间的key中,任意选择数据淘汰
  • allkeys-random:从所有key中,任意选择数据淘汰

TTL(过期时间)

  • volatile-ttl:从已设置过期时间的key中,挑选将要过期的数据淘汰
  • allkeys-random:从所有key中,任意选择数据淘汰

No-Enviction(驱逐)

  • noenviction(驱逐):当达到最大内存时直接返回错误,不覆盖或逐出任何数据

标签:文件,持久,AOF,过期,Redis,key,RDB,化机制
From: https://www.cnblogs.com/kimber/p/17800191.html

相关文章

  • Redis部署架构
    部署架构单节点(Single)优点架构简单,部署方便高性价比:缓存使用时无需备用节点(单实例可用性可以用supervisor或crontab保证),当然为了满足业务的高可用性,也可以牺牲一个备用节点,但同时刻只有一个实例对外提供服务高性能缺点不保证数据的可靠性在缓存使用,进......
  • 浅析Redis大Key
    一、背景在京东到家购物车系统中,用户基于门店能够对商品进行加车操作。用户与门店商品使用Redis的Hash类型存储,如下代码块所示。不知细心的你有没有发现,如果单门店加车商品过多,或者门店过多时,此Key就会越来越大,从而影响线上业务。userPin:{storeId:{门店下加车的所有商品......
  • windows设置redis开机启动
    最近遇到了个问题,需要在windows中使用redis,但是redis没有开机启动,需要每次通过命令行进行启动,所以选择了设置redis开机启动。另外cmd窗口启动redis,如果不小心关掉了cnd,redis会跟着停掉,很不方便进入redis文件夹,打开cmd,输入命令:redis-server.exe--service-installredis.window......
  • Redis学习
    Redis数据结构Redis数据类型常见的有五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合),随着Redis版本的更新,后面又支持了四种数据类型:BitMap(2.2版新增)、HyperLogLog(2.8版新增)、GEO(3.2版新增)、Stream(5.0版新增)。应用场景String类型的应用场景:缓存对......
  • PHPStudy 安装tp8 php8.2.9 安装XDbug、redis扩展安装XDbug扩展vscode断点:
    一、PhpStudy升级PHP版本,安装PHP8.2操作步骤1.1、官网下载最新的php版本打开Windows版的官网下载,地址:https://windows.php.net/download/ 页面上有不同的PHP版本,这里我们下载的是64位nts版的PHP8.2.9。1.2、解压下载的文件将下载的文件php-8.2.9-nts-Win32-vs16-x64.zip,移到PhpS......
  • Redis集群模式incr保证原子性的原理
    1.主要是redis的key会解析到固定的主机上,比如集群上有host1,host2,host3;然后key1可能会解析后发现是要发到host2上,则在host2正常的情况下(有点像kafkarebalance;consumer处理哪些分区),key1会一直在host2上进行操作;因此在redis集群正常情况下不会出现对key1第一次incr是在host2,第二次......
  • 爱好的持久性
    感觉入坑时懵懵懂懂,甚至刚成年,不知道这个东西的毒害。再加上没有老师以及学长的指引,就一条道走到黑了。现在回过头来,发现这真的是一条不归路,至少对于普通人是这样的。感觉每个人都会踩坑,固然有自己固执的因素,但是如果有贵人相助(老师、学长合理规劝),一定能减少亏损,但这都过去了,要说......
  • 【Redis使用】一年多来redis使用markdow笔记总结,第(1)篇:Redis命令详解
    Redis是一个高性能的key-value数据库。本文会让你知道:什么是nosql、Redis的特点、如何修改常用Redis配置、写出Redis中string类型数据的增删改查操作命令、写出Redis中hash类型数据的增删改查相关命令、说出Redis中list保存的数据类型、使用StrictRedis对象对string类型数据......
  • Redis的四种模式:单机、主从、哨兵、集群简介
    Redis的单机模式单机模式就是安装一个redis,启动起来,业务调用即可。具体安装步骤和启动步骤就不赘述了,单机在很多场景也是有使用的,例如在一个并非必须保证高可用的情况下。单机的优点:部署简单,0成本。成本低,没有备用节点,不需要其他的开支。高性能,单机不需要同步数据,数据......
  • redis 替换keys方案 scan
    redis替换keys方案@AutowiredprivateRedisTemplateredisTemplate;publicSet<String>keyScan(Stringkey){//批量查询需要统计的数据Set<String>keys=(Set<String>)redisTemplate.execute((RedisCallback<Set<String>>)connec......