设为首页 加入收藏

TOP

Redis面试题(三)
2023-09-23 15:44:12 】 浏览:213
Tags:Redis
RDB、AOF、混合持久化是怎么回事

RDB快照(snapshot)

在默认情况下,Redis将内存数据库快照保存在名字为dump.rdb文件中。
需要注意的是,RDB 持久化是一种全量持久化方式,它将整个 Redis 数据集写入到磁盘。因此,在每次持久化操作期间,Redis 会将内存中的所有数据保存到 dump.rdb 中,而不是增量地向文件中添加数据。
rdb的启动方式:

save 900 1
save 300 10
save 60 10000 #在60秒的实践中10000个改动

在redis中的save命令可以手动持久化数据。
bgsave(backgroundsave)后台save,其是通过操作系统提供的写时复制技术(Copy-On-Write,COW)实现的,在生成快照的同时,依然可以正常处理命令。
在Redis中,bgsave命令用于在后台异步地创建当前数据库的快照。这个命令实际上会调用fork()系统调用来创建一个子进程,子进程会将数据写入磁盘。 在创建子进程时,父进程的内存空间会被复制到子进程。这是一个昂贵的操作,因为如果你有一个占用了10GB内存的Redis实例,那么执行fork()就需要额外的10GB内存。但是,这就是Copy-On-Write技术发挥作用的地方。
Copy-On-Write (COW) 是一种可以延迟或避免复制数据的技术。当父进程创建子进程时,操作系统并不立即复制所有的内存页,而是让父进程和子进程共享同样的内存页。只有当其中一个进程尝试修改某个内存页时,操作系统才会创建那个内存页的副本,让修改的进程(主进程)使用这个副本,而另一个进程(bgsave子进程)继续使用原来的内存页。这就是所谓的"写时复制"。
在Redis的BGSAVE命令中,COW技术可以帮助节省内存。当BGSAVE命令执行时,子进程开始写快照,而父进程继续处理命令。如果在此过程中,父进程需要修改某个内存页,那么操作系统会为父进程创建一个新的内存页,而子进程仍然可以看到原来的内存页,因此可以正确地将数据写入快照。
总的来说,COW技术允许Redis在创建快照时最大限度地节省内存,并且确保了快照的一致性,因为子进程看到的始终是fork()时的数据。
两者的区别如下。
image.png

缺点:

  • 生成快照占用内存巨大。
  • 按照快照的保存策略进行持久化,例如save 60 1000,如果在下一个60秒内没有满足save条件但是redis宕机了,那么就有数据丢失的问题。

AOF(Append-Only file)持久化

可以通过修改配置文件来打开AOF功能

# appendonly yes

将修改的每一条指令记录进文件appendonly.aof中(先写入os cache每隔一段时间fsync到磁盘),逐条的把所有命令执行。

可以配置redis多久fsync到磁盘一次:

appendfsync always	#每次有新命令追加到AOF文件时就执行一次fsync
appendfsync everysec	#每秒fsync一次,足够快,并且故障时只会丢失1秒钟的数据
appendfsync no 	#从不fsync,将数据交给操作系统来处理,足够快但是不安全。

推荐并且默认的就是每秒fsync一次,appendfsync everysec具体来说:

  • Redis会用一个1秒计时器来实现这个时间间隔的控制。
  • 在一个1秒时间段内,所有发生的写命令会存在内存缓冲区
  • 到了每个1秒时间点,Redis会把这1秒内缓冲起来的所有写命令一次性异步写入AOF文件。
  • 然后计时器重置,开始计时下一个1秒时间段内的写命令。

缺点:redis运行时间很长,AOF文件会很大,恢复的速度会很慢。

RDB和AOF的优劣:
image.png
生产环境可以都启动

AOF重写:

incr readcount #多次执行,会在AOF文件中多次记录
set readcount n  #不如直接set为最后一次的readcount的值

多条命令可以直接重写为一条命令。

#aof文件至少要达到64m才会自动重写,文件太小恢复速度本来就很快,重写意义不大
auto-aof-rewrite-percentage 100	

#aof文件自上次重写后文件大小增长了100%会触发重写
auto-aof-rewrite-min-size 64mb  

aof重写是执行bgrewriteaof命令重写aof,类似bgsave也是有些消耗性能。

Redis4.0 混合持久化

必须先开启AOF

aof-use-rdb-preamble yes

AOF在重写时,直接写成RDB的二进制格式数据,.aof文件中追加 快照的形式。
混合持久化的文件结构。
需要注意的是,这个RDB格式的快照是直接写入到AOF文件中的,而不是作为一个单独的文件存在。也就是说,一个AOF文件可能既包含RDB格式的数据快照,又包含普通的AOF命令。实际上,我们无法直接读取或者理解RDB格式的数据快照,因为它是二进制的。我们只能知道,当Redis加载这个AOF文件时,它会首先加载RDB格式的数据快照,然后再执行后面的命令,从而恢复所有的数据。
image.png
image.png
此时就不需要rdb持久化方式了。
优势:

  • 数据格式更加紧凑,
  • 数据启动恢复效率更高,
  • 又兼顾安全性。

线上Redis持久化策略一般如何设置

如果对性能要求较高,在Master最好不要做持久化,可以在某个Slave开启AOF备份数据,策略设置为每秒同步一次即可。

一次线上事故,Redis主节点宕机导致数据全部丢失

如果你的Redis 采用如下模式部署,就会发生数据丢失的问题:

  • master-slave+哨兵部署实例。
  • master 没有开启数据持久化功能。
  • Redis进程使用supervisor管理,并配置为进程宕机,自动重启。

如果此时master宕机,就会导致下面的问题:

  • master宕机,哨兵还未发起切换,此时 master进程立即被supervisor自动拉起。
  • 但master没有开启任何数据持久化,启动后是一个空实例。
  • 此时 slave为了与master保持一致,它会自动清空实例中的所有数据,slave也变成了一个空实例。在这个场景下,master / slave 的数据就全部丢失了。

这时,业务应用在访问Redis时,发现缓存中没有任何数据,就会把请求全部打到后端数据库上,这还会进一步引发缓存雪崩,对业务影响非常大。
这种情况下我们一般不应孩给Redis主节点配置进程宕机马上自动重启策略,而应该等哨兵把某个Redis从节点切换为主节点后再重启之前宕机的Redis主节点让其变为slave节点。

Supervisor是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统。它可以很方便的监听、启动、停止、重启一个或多个进程。用用Supervisor管理的进程,当一个进程意外被杀死,supervisort监听到进程死后,会自动将它重新拉起,很方便的做到进程自动恢复的功能,不再需要自己写shell脚本来控制。

Redis线上数据如何备份

  1. 写crontab定时调度脚本,每小时都copy一份rdb或aof文件到另一台机器中,保留最近48小时的备份。
  2. 每天都保留一份当日的数据备份到一个目录中
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Spring 多线程的事务处理 下一篇主动写入流对@ResponseBody注解的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目