首页 > 数据库 >redis持久化

redis持久化

时间:2022-08-23 11:37:13浏览次数:76  
标签:文件 持久 AOF redis Redis RDB 快照 写入

redis如何实现数据不丢失:为了保证Redis数据不丢失,要把数据从内存存储到磁盘上,这就是Redis的数据持久化。Redis 数据持久化有三种方式:
1)AOF日志(Append Only File,文件追加方式):

  先执行命令把数据写入内存,然后再记录命令日志到文件中,重启时重新执行AOF文件中的命令以恢复数据,是目前redis持久化的主流方式。工作流程如下:所有命令追加到aof_buf缓冲区,缓冲区根据策略向硬盘aof文件做同步操作,redis服务器重启时,加载aof文件恢复数据。
Redis为什么要先执行命令,再把数据写入日志?
由于Redis在写入日志之前,不对命令进行语法检查,所以只记录执行成功的命令,避免出现记录错误命令的情况,而且在命令执行后再写日志不会阻塞当前的写操作。
Redis先执行命令,再把数据写入日志,有什么风险?
如果Redis刚执行完命令,此时发生故障宕机,会导致这条命令存在丢失的风险。AOF日志其实也是在主线程中执行,所以当Redis把日志文件写入磁盘的时候,还是会阻塞后续的操作无法执行。redis如果直接追加到硬盘,由于Redis是单线程,性能完全取决于硬盘负载,先写入缓冲区还可以提供多种同步到硬盘的策略。
redis的系统调用,write和fsync
write触发延迟写,写入系统缓冲区后返回,通过系统调度完成同步磁盘的操作
fsync强制磁盘同步,阻塞直到写入硬盘完成后返回
缓冲区向硬盘aof的同步操作:通过appendfsync控制,取值有三种always、everysec、no
always:命令写入aof_buf后调用系统fsync操作同步到AOF文件,fsync完成后线程返回
everysec:命令写入aof_buf后调用系统write操作,write完成后线程返回,fsync同步文件操作由专门线程每秒调用一次
no:命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作有操作系统负责,通常同步周期最长30s

2)RDB快照(Redis DataBase):将某一个时刻的内存数据,以二进制的方式写入磁盘。
  RDB记录的是某一时刻的数据而不是操作,所以采用RDB方法做故障恢复时只需要直接把RDB文件读入内存即可,实现快速恢复
  RDB做快照时会阻塞线程吗?

  Redis提供了三个命令生成RDB快照文件,分别是save,bgsave和bgrewriteaof。

save 命令在主线程中执行,会导致阻塞,直到RDB操作完成。bgsave命令会创建一个子进程,该子进程用于RDB持久化过程,避免了对主线程的阻塞,这也是Redis RDB的默认配置。子进程会根据父进程的内存生成快照文档,对原有文件进行原子替换。bgsave创建子进程的时候对主进程会有略微阻塞,时间很短,微秒级别。bgsave期间服务器拒绝执行save、bgsave、bgrewriteaof这三个命令,主要是防止线程间竞争产生问题。子进程创建RDB文件(dump.rdb)是一个压缩的二进制文件,压缩后的文件远远小于内存中的大小,保存在dir配置指定的目录下,通过它可以恢复Redis内存中的数据

  RDB生成快照文件时,数据还能被增删改吗?
可以的,如果生成快照文件期间数据不能被修改,是会有潜在问题的。假如生成快照的20s时间里,如果数据不能被修改,Redis就不能处理对这些数据的写操作,那无疑会给业务服务造成巨大影响。如果主线程执行写操作,则被修改的数据会复制一份副本,然后bgsave子进程会把该副本数据写入RDB文件,在这个过程中,主线程仍然可以直接修改原来的数据。
  可以每秒做一次快照么?
如果频繁地执行全量快照,会带来两方面开销:一是频繁将全量数据写入磁盘,会给磁盘带来很大压力。二是bgsave子进程需要从主线程fork出来,fork创建过程本身会阻塞主线程,而且主线程的内存越大,阻塞时间越长。
  既然频繁执行全量快照不行,那还有什么其他好方法吗?
第一个方法是做增量快照。在第一次做完全量快照后,T1和T2时刻如果再做快照,只需要将被修改的数据写入快照文件就行了。
第二个方法是Redis4.0提出一个混合使用AOF日志和RDB快照的方法:RDB快照以一定的频率执行,在两次快照之间,使用AOF日志记录这期间的所有命令操作。假如两次RDB之间有T1和T2两次修改,用AOF日志记录,等到第二次做全量快照时,就可以清空AOF日志,因为此时的修改都已经记录到快照中了。

  上述介绍的是RDB的手动触发,下面介绍下自动触发方式,配置文件redis.conf:

  • 配置 save m n,例如 save 900 1,表示900(saveparam.seconds)秒内数据集出现1次(saveparam.changes)修改时,执行bgsave。

    • 服务器维护dirty计数器,每进行一次写操作,计数器+1;lastsave属性记录上次save或bgsave的时间戳。

  • 从节点执行全量复制操作,则主节点自动执行bgsave生成RDB文件发送给从节点。

  • 执行debug reload重新加载redis时,自动触发save操作。

  • 执行shutdown命令时,如果没有开启AOF,则自动执行bgsave。

 

RDB的优缺点:

优点:

  • RDB文件,压缩的二进制文件,是redis某个时间点的数据快照,适用于备份、全量复制、拷贝到远程机器或文件系统中用于灾备。

  • 加载RDB文件恢复数据,远快于AOF

缺点:

  • 无法实时持久化/秒级持久化,bgsave每次执行都要fork操作执行子进程,属于重量级操作,频繁执行成本过高。

  • RDB是特定二进制格式的文件,演进过程中有多个格式的RDB版本,存在老版本redis服务无法兼容新版RDB格式的问题。

3) 混合使用AOF日志和RDB快照

  如上简介

标签:文件,持久,AOF,redis,Redis,RDB,快照,写入
From: https://www.cnblogs.com/MarkLeeBYR/p/16615549.html

相关文章

  • 关于Redis在windows上运行及fork函数问题
    Redis在将数据库进行持久化操作时,需要fork一个进程,但是windows并不支持fork,导致在持久化操作期间,Redis必须阻塞所有的客户端直至持久化操作完成。微软的一些工程师花费时间......
  • java帝国的诞生——一场旷日持久的战争
    一、C&C++聊到java的诞生,就不得不谈谈C语言和C++。C语言诞生于1972年,而java则是在1995年才出现,这中间时间跨度还是蛮大的。C语言在java出现之前已经统治了二十多年了。......
  • 数据库 - db和redis数据一致性问题
    数据库-db和redis数据一致性问题直接说解决办法:查询数据操作:查询缓存,如果命中,直接返回;如果没有命中,查询数据库,再写入缓存更新数据操作:直接更新db数据库然后......
  • Redis基础练习题-错题集(一)
    (1)下面关于Redis中set数据类型与list数据类型的比较,正确的说法是()选项A. set中的数据具有唯一性,list中的数据不具有唯一性B. set中的数据有序,list中的数据无序......
  • Redis中set和list的区别有哪些
    list和set的区别:1、List和Set都是接口继承于Collection接口。2、最大的不同就是List是可以重复的。而Set是不能重复的。(注意:元素虽然无放入顺序,但是元素在set中的位置是......
  • 如何查看redis使用那个配置文件启动
      [root@cdc-henan-cdhworker02redis]#/usr/local/redis/bin/redis-cli-h192.168.1.50-atest123-p6379Warning:Usingapasswordwith'-a'or'-u'option......
  • Redis持久化
    Redis持久化redis是一个内存数据库当redis服务器重启获取电脑重启数据回丢失我们可以将redis内存中的数据持久化保存到硬盘的文件中redis持久化机制:RDB:默认方式不......
  • Redis命令操作_常用命令和Redis持久化
    通用命令keys*查询所有的键typekey:获取键对应的value的类型delkey:删除指定的keyclear:清除窗口所有内容127.0.0.1:6379>keys*(emptylistorset)127.0.0.1:......
  • docker快速搭建redis集群
    采用三台主节点Docker部署,均采用默认端口,每台机器一台redis,可以视情况自行修改#清理环境,所有节点执行!注意会删除数据rm-rf/opt/redis/clustermkdir-p/opt/redi......
  • Redis 的持久化总结
    AOF持久化这种保存写操作命令到日志的持久化方式,就是Redis里的AOF(AppendOnlyFile)持久化功能,注意只会记录写操作命令,读操作命令是不会被记录的,因为没意义。第一......