redis 的AOF 有哪些面试的要点

178 阅读11分钟

AOF 写后日志的好处是 不用对命令进行预检查,也不会阻塞当前写操作,坏处,AOF 会对下次写命令的阻塞

aop 两个概念

  • 写回
  • 重写

image.png

AOF 重写会阻塞吗?

image.png

Redis的AOF重写过程是设计成尽可能不阻塞主服务器操作的。这是通过使用子进程来完成AOF重写来实现的,这样主进程可以继续处理客户端请求,减少了重写操作对服务器性能的影响。下面是详细的解释:

AOF重写过程

  1. 启动子进程:当触发AOF重写时,Redis主进程会fork一个子进程来执行实际的重写操作。fork操作本身在大数据库上可能会产生短暂的延迟,因为需要复制进程的内存空间,但这通常很快完成。

  2. 子进程重写AOF:子进程读取当前数据库的状态,并生成一个新的AOF文件。这个过程完全在子进程中进行,因此主进程可以继续响应客户端请求,几乎不受影响。

  3. 使用新AOF文件:子进程完成AOF文件的重写后,它会通知主进程。主进程在合适的时候(通常是下一次客户端请求处理循环)将新的AOF文件替换旧的AOF文件,并开始使用新的文件。这一步涉及的阻塞时间非常短,因为主要是文件操作。

非阻塞特性

  • 继续处理命令:在AOF重写期间,Redis主进程可以继续接收和处理命令,这确保了服务的可用性。
  • 修改缓冲区:为了处理在重写期间发生的写命令,Redis引入了一个AOF重写缓冲区。主进程将新的写命令同时写入当前的AOF文件和重写缓冲区。当子进程完成重写并且新的AOF文件被主进程采用时,重写缓冲区中的命令会被追加到新的AOF文件中,确保了数据的完整性。

注意事项

尽管AOF重写过程设计为非阻塞,但在某些情况下,如当服务器内存非常紧张时,fork操作可能会导致可见的性能影响,因为操作系统可能需要在物理内存和交换空间(swap)之间移动数据。此外,大规模的数据变动也会影响重写性能,可能会导致重写操作本身需要较长时间完成。

总的来说,Redis的AOF重写是设计成尽量减少对主进程的影响,通过使用子进程来实现非阻塞的数据重写,从而确保Redis服务的高可用性和响应性。

AOF 日志重写的时候,是由 bgrewriteaof 子进程来完成的,不用主线程参与,我们今天说的非阻塞也是指子进程的执行不阻塞主线程。但是,你觉得,这个重写过程有没有其他潜在的阻塞风险呢?如果有的话,会在哪里阻塞?

问题1,Redis采用fork子进程重写AOF文件时,潜在的阻塞风险包括:fork子进程 和 AOF重写过程中父进程产生写入的场景,下面依次介绍。 a、fork子进程,fork这个瞬间一定是会阻塞主线程的(注意,fork时并不会一次性拷贝所有内存数据给子进程,老师文章写的是拷贝所有内存数据给子进程,我个人认为是有歧义的),fork采用操作系统提供的写实复制(Copy On Write)机制,就是为了避免一次性拷贝大量内存数据给子进程造成的长时间阻塞问题,但fork子进程需要拷贝进程必要的数据结构,其中有一项就是拷贝内存页表(虚拟内存和物理内存的映射索引表),这个拷贝过程会消耗大量CPU资源,拷贝完成之前整个进程是会阻塞的,阻塞时间取决于整个实例的内存大小,实例越大,内存页表越大,fork阻塞时间越久。拷贝内存页表完成后,子进程与父进程指向相同的内存地址空间,也就是说此时虽然产生了子进程,但是并没有申请与父进程相同的内存大小。那什么时候父子进程才会真正内存分离呢?“写实复制”顾名思义,就是在写发生时,才真正拷贝内存真正的数据,这个过程中,父进程也可能会产生阻塞的风险,就是下面介绍的场景。 b、fork出的子进程指向与父进程相同的内存地址空间,此时子进程就可以执行AOF重写,把内存中的所有数据写入到AOF文件中。但是此时父进程依旧是会有流量写入的,如果父进程操作的是一个已经存在的key,那么这个时候父进程就会真正拷贝这个key对应的内存数据,申请新的内存空间,这样逐渐地,父子进程内存数据开始分离,父子进程逐渐拥有各自独立的内存空间。因为内存分配是以页为单位进行分配的,默认4k,如果父进程此时操作的是一个bigkey,重新申请大块内存耗时会变长,可能会产阻塞风险。另外,如果操作系统开启了内存大页机制(Huge Page,页面大小2M),那么父进程申请内存时阻塞的概率将会大大提高,所以在Redis机器上需要关闭Huge Page机制。Redis每次fork生成RDB或AOF重写完成后,都可以在Redis log中看到父进程重新申请了多大的内存空间。 问题2,AOF重写不复用AOF本身的日志,一个原因是父子进程写同一个文件必然会产生竞争问题,控制竞争就意味着会影响父进程的性能。

AOF 重写也有一个重写日志,为什么它不共享使用 AOF 本身的日志呢?

一个原因是父子进程写同一个文件必然会产生竞争问题,控制竞争就意味着会影响父进程的性能。二是如果AOF重写过程中失败了,那么原本的AOF文件相当于被污染了,无法做恢复使用。所以Redis AOF重写一个新文件,重写失败的话,直接删除这个文件就好了,不会对原先的AOF文件产生影响。等重写完成之后,直接替换旧文件即可。

redis 的AOF 有哪些面试的要点,请帮我罗列下 并给出详细答案

Redis的AOF(Append Only File)持久化是面试中常被提及的重点之一,因为它直接关系到数据的安全性和恢复能力。下面是一些关于AOF持久化的面试要点及详细解释:

1. AOF持久化是什么?

  • 定义:AOF持久化是Redis用来记录每个写操作命令的日志文件,命令以Redis协议的格式追加存储,以确保数据的持久性。在Redis重启时,可以通过重新执行这些命令来恢复数据。

2. AOF与RDB持久化的区别?

  • 数据安全性:AOF可以提供更高的数据安全性。通过配置,AOF可以做到每秒同步一次或每次写操作后同步,而RDB在指定的时间间隔内生成数据快照。
  • 性能:对于大量数据的恢复,RDB通常速度更快,因为它是直接将数据快照读入内存。而AOF可能因为需要逐条执行命令而更慢。
  • 文件大小:AOF文件可能比RDB文件大,因为它记录的是所有的写操作命令。但AOF提供了重写机制来减小文件大小。

3. AOF重写是什么?为什么需要?

  • 定义:AOF重写是减小AOF文件大小的过程。它通过读取当前数据库状态,生成一系列最小化的写操作命令来创建一个新的AOF文件,而不是简单地复制旧文件。
  • 原因:随着时间的推移,原始的AOF文件可能会因为记录了大量冗余命令而变得非常大。AOF重写帮助减少磁盘使用和提高数据恢复的速度。

4. AOF同步策略有哪些?

  • 同步策略:Redis提供三种AOF同步策略,可通过appendfsync配置项设置:
    • always:每个写命令都同步写入磁盘,提供最高的数据安全性但性能较低。
    • everysec(默认):每秒同步一次,平衡了数据安全性和性能。
    • no:由操作系统决定何时同步,性能最高,但在系统崩溃时可能丢失数据。

5. AOF文件如何恢复数据?

  • 恢复过程:在Redis启动时,如果配置了AOF持久化,Redis会读取AOF文件,并重新执行其中的所有命令来重建数据库状态。

6. 面对AOF文件膨胀,如何处理?

  • 策略:可以通过手动或自动触发AOF重写来减小文件大小。自动触发可以通过配置auto-aof-rewrite-percentageauto-aof-rewrite-min-size来实现。

7. AOF在实际应用中的考虑因素?

  • 性能影响:使用AOF可能会对性能产生影响,特别是在appendfsync配置为always时。
  • 数据安全性:选择合适的appendfsync策略可以在性能和数据安全性之间做出权衡。
  • 磁盘空间:需要监控AOF文件大小,适时进行重写,以避免磁盘空间被耗尽。

在面试中,展现对AOF持久化的深入理解,包括其工作原理、与RDB的对比、重写机制、同步策略及实际应用考虑,可以帮助面试官

宕机了,Redis如何避免数据丢失?

Redis提供了几种机制来减少或避免因宕机而导致的数据丢失,主要包括持久化和复制(Replication)功能。通过正确配置和使用这些功能,可以在很大程度上确保数据的安全性和可恢复性。

持久化

Redis支持两种主要的持久化方法:RDB(Redis Database)和AOF(Append Only File)。这两种方法可以单独使用,也可以同时使用,以达到最佳的数据安全性。

  1. RDB持久化

    • RDB是一种将Redis在某一时刻的数据快照保存到硬盘上的机制。
    • 可以配置Redis定期进行快照保存,比如每隔一定时间或达到一定的写操作数量时。
    • RDB非常适合用于备份、灾难恢复,以及重启Redis时的快速加载数据。
    • 缺点是,在两次快照之间,如果发生宕机,那么这段时间内的数据将会丢失。
  2. AOF持久化

    • AOF记录每一个写操作命令,并将其追加到文件末尾,保证了数据的完整性和一致性。
    • 通过重放这些命令,可以恢复宕机前的数据状态。
    • AOF提供了不同的同步频率配置选项,如每次写操作后同步、每秒同步等,以平衡数据安全性和性能。
    • AOF文件可能会比RDB文件大,并且在某些情况下重启恢复速度较慢。

复制

Redis的复制功能允许将一台Redis服务器的数据复制到一个或多个Redis从服务器。这提供了数据冗余,以及读取操作的负载均衡。

  • 在主服务器宕机的情况下,可以从一个更新的从服务器进行故障转移(failover),将其提升为新的主服务器,以此来减少服务中断时间和数据丢失风险。
  • Redis的Sentinel系统可以管理复制和故障转移过程,自动选择一个从服务器来替代宕机的主服务器。

最佳实践

为了最大限度地减少数据丢失的风险,可以采用以下最佳实践:

  • 同时使用RDB和AOF持久化:利用RDB进行定期全量备份,同时使用AOF来记录每个写操作,确保数据的恢复性和一致性。
  • 合理配置AOF同步频率:根据业务的容错要求和性能需求,合理选择AOF的同步频率。
  • 使用复制和Redis Sentinel:通过配置主从复制,加上Redis Sentinel来自动进行故障转移,提高数据的可用性和容灾能力。
  • 定期测试备份和恢复流程:定期测试备份文件的有效性以及恢复流程的正确性,确保在需要时能够顺利进行数据恢复。

通过综合运用上述机制和最佳实践,可以有效地避免Redis宕机导致的数据丢失问题。