Redis数据持久化之AOF

把Redis当作缓存使用是Redis比较普遍的应用场景,因为Redis将数据存储在内存中,操作数据时响应速度非常快。但是如果Redis服务器一旦宕机,内存中的数据将全部丢失。

如果我们通过从后端数据库恢复数据,则需要频繁访问数据库,给数据库带来巨大压力,并且直接从后端数据库读取数据,性能远远比不上Redis,从而导致使用这些数据的应用程序响应变慢。

因此,Redis的数据持久化是非常重要的,目前Redis实现持久化的方式有两种,即AOFRDB

传统数据库通常情况下使用写前日志,也就是在数据写入数据库之前进行日志记录,而AOF恰好相反,是写后日志。

为什么Redis会使用AOF记录日志呢?

  • 避免对Redis操作语句进行语法检查,导致额外的检查开销,且命令执行成功后才进行日志记录,可以避免记录错误命令;
  • 在命令执行后才记录日志,可以避免因记录日志阻塞当前命令操作。

但是AOF也存在风险。如果命令执行完后,还没记录日志服务器就宕机了,那么操作命令和数据有可能丢失;虽然AOF可以避免因记录日志阻塞当前命令操作,但还是可能阻塞下一个操作。

Redis提供三种日志写回策略,可通过appendfsync进行配置:

  • Always,同步写回,执行完操作后马上将日志写回磁盘;可以做到基本不丢数据,但频繁的慢速磁盘操作,会影响Redis主线程性能;
  • Everysec,每秒写回,执行完操作后将日志写入AOF文件的内存缓冲区,每隔一秒将缓冲区的内容写回磁盘;减少了性能开销,但是如果发生宕机,会丢失上一秒的操作命令和数据;
  • No,操作系统控制写回,执行完操作后将日志写入AOF文件的内存缓冲区,由操作系统决定何时将缓冲如内容写回磁盘;写回磁盘的时机不受Redis控制,一旦宕机,丢失的数据可能较多。

如果系统要求高性能,可选择No策略,如果系统要求高可靠,可以选择Alwasy策略,如果允许数据轻微丢失,且不希望性能受太大影响,可以选择Everysec策略。

随着时间推移,对数据进行CRUD的操作命令越来越多,这会使得AOF文件越来越大,同样会给Redis带来性能问题。一是文件系统可能无法保存过大文件;二是文件太大,追加命令记录时,效率变低;三是如果发生宕机,使用AOF恢复的过程非常缓慢。

Redis通过AOF重写机制来解决这个问题。同一条数据,可能经过成百上千次修改,就会记录成百上千条操作命令,重写时,根据键值直接生成当前最新状态的写入命令,这样就把多条操作命令重写成一条,就能节省空间了。

 AOF重写不会阻塞主线程,它和主线程写回时不同,重写过程是由后台子线程完成的。AOF重写日志时,Redis会先执行一个内存拷贝,用于重写;然后用两个日志保证在重写过程中,新写入的数据不会丢失。

在拷贝过程中,为了避免一次性拷贝大量数据给子进程造成长时间阻塞,fork子进程采用操作系统提供的写实复制机制,拷贝必要的数据结构,其中包括拷贝内存页表(虚拟内存和物理内存的映射索引表),但是这个过程仍然可能消耗大量CPU资源,拷贝完成之前整个进程依然会被阻塞,阻塞时间取决于实例的内存大小,实例越大,内存页表越大,fork阻塞时间越久。拷贝内存页表完成后,父子进程指向相同的内存地址空间,拷贝内存真正数据后,父子进程才会真正分离。

在拷贝内存真正的数据过程中,父进程也可能会产生阻塞风险。

  • 父子进程指向相同的内存地址空间,子进程进行AOF重写,但此时父进程依然会有流量写入,如果父进程操作的是一个已经存在的key,这时候父进程就会真正拷贝key对应的内存数据,申请新的内存空间,这样逐渐地,父子进程逐渐拥有各自独立的内存空间。内存分配是以页为单位进行分配的,默认为4k,如果此时父进程操作的是一个bigkey,重新申请大块内存的耗时变长,可能产生阻塞风险。
  • 如果操作系统开启了内存大页机制(Huge Page,页面大小2M),那么父进程申请内存时的阻塞率会大大提高。所以在Redis机器上需要关闭Huge Page机制。

AOF重写时为什么不共享原来的AOF本身的日志呢?

  • 由于父子进程同时写同一个文件必然会产生竞争关系,会影响父进程的性能;
  • 如果AOF重写失败,那么原本的AOF文件就被污染了,无法做恢复使用;
  • 所以Redis AOF重写一个新文件,如果重写失败直接删除这个文件,如果重写完成后直接替换旧文件。

使用AOF进程故障恢复时,需要把所有的记录重新运行一遍,而Redis是单线程设计,这些操作只能一条一条的顺序执行,这个过程依然很慢。

如果使用RDB快照,既能避免数据丢失,又能更快地恢复数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无绪听雨眠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值