大厂面试官问我:Redis持久化RDB有没有可能阻塞?阻塞点在哪里?【后端八股文三:Redis持久化八股文合集】

 往期内容:

大厂面试官问我:Redis处理点赞,如果瞬时涌入大量用户点赞(千万级),应当如何进行处理?【后端八股文一:Redis点赞八股文合集】-CSDN博客

大厂面试官问我:布隆过滤器有不能扩容和删除的缺陷,有没有可以替代的数据结构呢?【后端八股文二:布隆过滤器八股文合集】-CSDN博客

本文为【Redis持久化八股文合集】初版,后续还会进行优化更新,欢迎大家评论交流~

大家第一眼看到这个标题,不知道心中是否有答案了?在面试当中,面试官经常对项目亮点进行深挖,来考察你对这个项目亮点的理解以及思考!这个时候,你如果可以回答出面试官的问题,甚至是主动说出自己的思考,那在面试中是大大加分的~

Redis能否将数据持久化,如何实现

能,将内存中的数据异步写入硬盘,两种方式:RDB(默认)和AOF

快照方式(RDB Redis DataBase)和文件追加(AOF Append Only File)

快照方式重启恢复快、但是数据更容易丢失,文件追加数据更完整、重启恢复慢。

混合持久化方式,Redis 4.0之后新增的方式,混合持久化是结合RDB和AOF的优点,在写入的时候先把当前的数据以RDB的形式写入到文件的开头,再将后续的操作以AOF的格式存入文件当中,这样既能保证重启时的速度,又能降低数据丢失的风险。

在恢复时,先恢复快照方式保存的文件,然后再恢复追加文件中的增量数据。

RDB持久化原理

(定时创建快照)
通过bgsave命令触发,然后父进程执行fork操作创建一个子进程,子进程创建RDB文件,根据父进程生成临时快照,完成后对原文件进行原子替换(定时一次性将所有数据进行快照生成一份副本在硬盘中)
优点:紧凑压缩的二进制文件,Redis加载RDB恢复数据远快于AOF的方式
缺点:由于每次生成RDB开销较大,非实时持久化

AOF持久化原理/ AOF的存储过程

(每当修改写入文件)
开启后,Redis每执行一个修改数据的命令,都会把这个命令添加到AOF文件中
优点:实时持久化
缺点:AOF文件体积逐渐变大,需要定期执行重写操作来降低文件体积,加载慢

区别 / 持久化方式哪个性能好

  1. AOF 文件比 RDB 更新频率高,优先使用 AOF 还原数据;
  2. AOF比 RDB 更安全也更大;
  3. RDB 性能比 AOF 好;
  4. 如果两个都配了优先加载 AOF。

主流的机制是哪个?/ 目前主流Redis的持久化方式是什么?

主流的 Redis 持久化方式是结合使用 RDB(Redis 数据备份)和 AOF(Append-Only File)两种机制。这种组合方式可以充分利用两种方式的优势。

键过期之后aof怎么记录?

当 Redis 中的某个键过期后,在下一次 AOF 文件重写时,Redis 会自动删除这些过期键的相关命令,从而避免在 AOF 文件中保留无用的过期数据。

Redis RDB 有没有可能阻塞?阻塞点在哪里?RDB 持久化时内存会翻倍吗?AOF 重写实现原理?

RDB 创建过程中,Redis 主线程会被阻塞,以确保在 RDB 文件生成期间数据的一致性。但 Redis 4.0 引入的子进程 COW(Copy-On-Write)技术可以大大减少阻塞时间。

RDB 持久化不会导致内存翻倍。在 RDB 文件生成期间,Redis 会fork出一个子进程来执行 RDB 保存,主进程仍然对外提供服务,不会占用额外的内存。

AOF 重写的原理是:Redis 会fork出一个子进程,由子进程来遍历当前内存中的数据,并生成等价的一系列 Redis 命令,写入到新的 AOF 文件中,以达到压缩 AOF 文件的目的。

COW(Copy-On-Write)技术

具体来说,在 Redis 执行 RDB 持久化时,会进行以下步骤:

Redis 主进程会 fork 出一个子进程。

子进程会开始生成 RDB 文件,这个过程中主进程仍然会继续处理客户端的请求。

当主进程需要修改某些内存数据时,它不会直接修改,而是先复制一份数据,然后在复制的副本上进行修改。

这就是 COW 的原理 - 复制时只会复制被修改的部分,而不是整个内存空间。这样可以大大减少 RDB 持久化过程中主进程的阻塞时间。

具体的优势如下:

减少主进程的阻塞时间:只有在主进程需要修改内存中的数据时,才会触发数据复制,而不是在整个 RDB 生成过程中都被阻塞。

减少内存占用:由于只复制被修改的部分,而不是整个内存空间,所以内存占用也会大大减少。

提升性能:由于主进程的阻塞时间大幅缩短,Redis 可以更快速地响应客户端请求,整体性能得到提升。

它的回收进程是怎么工作的呢?

Redis 还有一个内存回收进程 (Redis Eviction Process):

当 Redis 的内存使用达到设定的上限时,Redis 会启动内存回收进程。

回收进程会根据设定的驱逐策略(如 LRU、LFU 等),选择并删除一些不常访问的键值对,以释放内存空间。

如果设置了过期时间的键,回收进程也会主动删除已过期的数据。

这个回收过程是异步执行的,不会阻塞 Redis 的正常服务。

Redis的持久化机制:配置文件中的具体的配置项,问这样写是怎样的执行流程?

在配置文件中设置 save 参数可以控制 RDB 的触发时机,设置 appendonly 参数可以开启 AOF 持久化。Redis 会根据配置,周期性地生成 RDB 快照,并持续地记录 AOF 日志。

在重启时,Redis 会先尝试从 RDB 文件恢复,如果不存在则从 AOF 文件恢复。

如果一个存储量很大的服务器宕机了,恢复数据有什么优化方式

对于存储量很大的服务器宕机后的数据恢复,可以考虑以下优化方式:

利用 RDB 文件进行快速恢复,减少从 AOF 文件恢复的时间。

事先预留足够的磁盘空间,确保 RDB 和 AOF 文件可以存放。

开启 AOF 文件的异步写入模式,减少 AOF 写入对服务的性能影响。

定期对 AOF 文件进行 rewrite 操作,控制 AOF 文件大小。

AOF会丢失数据吗

正常情况下,AOF 不会丢失数据。Redis 提供了 appendfsync 参数来控制 AOF 文件的同步策略,可以设置为 everysec 或 always 来确保数据的持久性。但在极端情况下,如机器宕机,仍然可能会造成少量数据丢失。

Redis版本更新在持久化方面做了什么改动?为什么这样做?

Redis 4.0 之后支持以下 3 种持久化方案:

1. **RDB(Redis DataBase)持久化** :快照方式持久化,将某一个时刻的内存数据,以二进制的方式写入磁盘。占用空间小,恢复快,可能存在数据丢失。

3. **混合持久化** :RDB + AOF 混合方式的持久化,Redis 4.0 之后新增的方式,混合持久化是结合了 RDB 和 AOF 的优点,在写入的时候,先把当前的数据以 RDB 的形式写入文件的开头,再将后续的操作命令以 AOF 的格式存入文件,这样既能保证 Redis 重启时的速度,又能减低数据丢失的风险。

Redis运行很久,AOF执行语句会一直膨胀很大吗? AOF日志过大该如何处理?

AOF 日志会随着时间不断增大,这是因为 Redis 会记录所有对数据库进行的操作。

可以定期执行 BGSAVE 命令生成 RDB 快照,然后使用 redis-check-aof 工具压缩 AOF 文件,删除旧的操作记录。

也可以设置 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 参数,让 Redis 自动压缩 AOF 文件

Redis有持久化,为什么不能当做数据库?

Redis 作为内存数据库,持久化只是为了防止数据丢失,而不是作为主要的数据存储方式。

相比传统数据库,Redis 的持久化方式更简单,更注重性能,但可靠性略低。

Redis 适合存储一些热点数据,而不适合大量的、持久性强的数据。需要与传统数据库配合使用。

Redis的持久化可以保证在任何情况下都不丢失数据吗?

Redis 的持久化机制并不能百分之百保证数据不丢失,主要取决于持久化的配置和触发时机。

例如,在 appendonly yes 模式下,如果 Redis 宕机且 AOF 日志还未同步到磁盘,仍然可能丢失部分数据。

所以需要合理配置持久化参数,并结合其他备份手段,提高数据可靠性。

Redis作为单线程是如何实现RDB的?

  • Redis 是单线程模型,但通过 BGSAVE 命令,可以在后台创建 RDB 快照,不会阻塞主线程的响应。
  • 这是通过 Redis 使用 fork() 系统调用创建子进程完成的,子进程负责写 RDB 文件,不会影响主进程的性能。

为什么Redis要持久化,不持久化可不可以?

Redis 作为内存数据库,如果不持久化,一旦服务重启,所有数据都会丢失。

持久化机制可以在 Redis 重启时自动加载数据,保证数据安全。

但对于一些purely in-memory的场景,也可以不开启持久化。

Redis在持久化时fork出一个子进程,这时已经有两个进程了,怎么能说是单线程呢?

单线程是指    网络IO和键值对读写    是一个线程 完成

而其他功能如持久化、异步删除、集群数据同步等,则是依赖其他线程

事实底层不是单线程

(在持久化操作是都是 fork 子进程和利用 Linux 系统的页缓存技术来完成,并不会影响 Redis 的性能)

在生成 RDB 期间,Redis 可以同时处理写请求么

可以的,Redis 使用操作系统的多进程写时复制技术 COW(Copy On Write) 来实现快照持久化,保证数据一致性。

Redis 在持久化时会调用 glibc 的函数fork产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。

当主线程执行写指令修改数据的时候,这个数据就会复制一份副本, bgsave 子进程读取这个副本数据写到 RDB 文件。

这既保证了快照的完整性,也允许主线程同时对数据进行修改,避免了对正常业务的影响。

写时复制

写时复制(Copy-On-Write,简称COW)是一种内存管理和数据共享技术,通常用于减少内存复制的开销以及处理多进程或多线程并发访问共享数据时的数据一致性问题。
写时复制的核心思想是在需要修改数据时,不立即复制整个数据,而是在修改前创建数据的副本,然后对副本进行修改。这样可以延迟内存复制,提高性能和降低内存开销。

写时复制的优点包括:

  • 减少了内存复制的开销,因为只有在必要时才会复制数据,而不是每次读写操作都复制一次。
  • 提高了性能,因为多个进程或线程可以共享相同的数据,而不需要每个进程都维护一份独立的数据副本。
  • 确保了数据一致性,因为每个进程或线程都在自己的数据副本上进行修改,不会影响其他进程或线程的数据。

如何实现数据尽可能少丢失又能兼顾性能呢?/Redis版本更新在持久化方面做了什么改动?

重启 Redis 时,我们很少使用 rdb 来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 rdb 来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。

Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。将 rdb 文件的内容和增量的 AOF 日志文件存在一起。这里的 AOF 日志不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量 AOF 日志,通常这部分 AOF 日志很小。

于是在 Redis 重启的时候,可以先加载 rdb 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,重启效率因此大幅得到提升

  ---------------------------------------------------------------------------------------------------------------

 更多精彩内容以及一手消息请关注公众号:绝命Coding

关注公众号可免费获取简历模板以及后端学习等免费资料

  • 31
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值