redis持久化操作及其原理详解

Redis 持久化机制

什么是redis持久化:

简而言之,把redis内存中的数据保存到磁盘的过程就是持久化。

redis 官方提供了两种持久化机制:

  • 快照(Snapshot)保存某一时刻的数据状态
  • AOF(Append Only File)只追加日志文件,将所有redis写命令记录到文件中
1. 快照(RDB)
1.1 特点

可以将某一时刻的所有数据都写入到硬盘中,这也是redis默认开启的持久化方式,保存的文件是以.rdb结尾的文件,因此这种快照方式也叫做RDB

1.2 生成方式
  • 客户端命令主动生成bgsave/save

    bgsave 命令原理:当收到客户端的bgsave命令时,redis会调用fork 来创建一个子进程,由子进程负责将快照写入磁盘中,而父进程继续处理命令。

    fork:当一个进程创建子进程的时候,底层的操作系统会创建该进程的一个副本,在类unix系统中创建子进程的操作会进行优化,在刚开始的时候,父子进程共享相同的内存,直到父进程或子进程对内核进行了写之后,对被写入的内存的共享才会结束服务。

在这里插入图片描述

save 命令原理:接收到save命令的redis服务在快照创建完毕之前将不再响应其他的命令。

在这里插入图片描述

  • 服务器配置自动触发

    在redis.conf中设置了save配置选项,redis会在save选项条件满足之后自动触发一次bgsave命令,如果设置多个save配置选项,当任意一个save配置选项条件满足,redis也会触发一次bgsave命令。

    # Save the DB on disk:
    #   In the example below the behaviour will be to save:
    #   after 900 sec (15 min) if at least 1 key changed 
    #   after 300 sec (5 min) if at least 10 keys changed 
    #   after 60 sec if at least 10000 keys changed
    save 900 1		    #(900秒)15分钟以内有1个发生变化,就做一次bgsave
    save 300 10		 	#(300秒)5分钟以内有10个发生变化,就做一次bgsave
    save 60 10000		#(60秒) 1分钟以内有10000个发生变化,就做一次bgsave
    
    # By default Redis will stop accepting writes if RDB snapshots are enabled  默认情况下RDB是被启用的
    stop-writes-on-bgsave-error yes
    
    rdbcompression yes
    
    rdbchecksum yes
    
    # The filename where to dump the DB
    dbfilename dump.rdb  #默认的文件名称
    
    dir ./  #rdb文件保存的位置
    
    
  • 服务器接收客户端shutdown指令

    当redis 通过shutdown指令接收到关闭服务器的请求时,会执行一个save命令,阻塞所有客户端,不再执行客户端执行发生的任何命令,并且在save执行完毕之后关闭服务器。

  • 执行flushall命令也会自动触发持久化,把rdb文件清空。

  • 主从同步触发

    在 Redis 主从复制中,当从节点执行全量复制操作时,主节点会执行 bgsave 命令,并将 RDB 文件发送给从节点,该过程会自动触发 Redis 持久化。

1.3 配置生成快照的名称和位置
# The filename where to dump the DB
dbfilename dump.rdb  #默认的文件名称

dir ./  #rdb文件保存的位置
2. AOF持久化
2.1 特点

这种方式可以将所有客户端执行的写命令记录到日志文件中,AOF持久化将会被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化,因此只要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复到AOF文件的记录的数据集。

2.1 开启AOF持久化
#yes为开启,默认为no
appendonly yes

#默认生成的文件
appendfilename "appendonly.aof" 
2.2 日志追加频率
#appendfsync always
# 默认 
appendfsync everysec
#appendfsync no
  • always【谨慎使用】

    说明:每个redis写命令都要同步写入硬盘,严重降低redis速度

    解释:如果用户使用了always选项,那么每个redis写命令都会被写入硬盘,从而将发生系统崩溃时出现的数据丢失减少到最少,但是这种同步策略需要对硬盘进行大量的写入操作,所以redis处理命令的速度会受到硬盘性能的限制;转盘式硬盘在这种频率下200左右个命令/s,固态硬盘(SSD) 几百万个命令/s;使用SSD

    用户谨慎使用,这种模式不断写入少量数据的做法可能会引发验证的写入放大问题,导致SSD寿命减少。

  • everysec【推荐】

    说明:每秒执行一次同步,显示的将多个写命令同步到磁盘

    解释:为了兼顾数据安全和写入性能,用户可以考虑用此选项,让redis每秒一次的频率对AOF文件进行同步,redis每秒同步一次AOF文件时性能和不使用任何持久化特性时相差无几,而通过每秒同步一次AOF文件,redis可以保证即使系统崩溃,用户最多丢失一秒之内产生的数据。

  • no 【不推荐】

    说明:由操作系统觉得何时同步

    解释:将由操作系统决定何时进行同步AOF日志文件,这个选项不会对redis性能带来影响,但是在系统崩溃时,会丢失不定数量的数据,另外如果用户硬盘处理写入操作不够快的话,当缓冲区被等待写入硬盘数据填满时,redis会处于阻塞状态,并导致redis的处理命令请求的速度变慢。

2.3 AOF文件的重写
2.3.1 AOF带来的问题

AOF方式同时带来了另一个问题,持久化文件会变得越来越大,例如我们调用incr test命令100次,文件中必须保存100条命令,同时有99条命令是多余的,因为要恢复数据库的状态其实文件中保存一条set test 100就够了。为了压缩AOF持久化文件,redis提供了AOF重写机制。

2.3.2 AOF重写

触发重写的方式:

  • 客户端方式触发

    执行bgrewriteaof 命令,不会阻塞redis的服务

  • 服务器配置方式自动触发

    配置redis.conf中的auto-aof-rewrite-percentage 选项

    如果设置auto-aof-rewrite-percentage值为100和 auto-aof-rewrite-min-size 64mb,并且启用的AOF持久化文件时,那么当AOF文件体积大于64M,并且AOF文件的体积比上一次重写之后体积大了至少一倍(100%)时,会自动触发,如果重写过于频繁,用户可以考虑将auto-aof-rewrite-percentage设置为更大。

    第一次达到64Mb —> 压缩到20Mb ----->按照100%比例计算达到40Mb时----->继续压缩 18Mb—>36Mb

    # Automatic rewrite of the append only file.
    # Redis is able to automatically rewrite the log file implicitly calling
    # BGREWRITEAOF when the AOF log size grows by the specified percentage.
    #
    # This is how it works: Redis remembers the size of the AOF file after the
    # latest rewrite (if no rewrite has happened since the restart, the size of
    # the AOF at startup is used).
    #
    # This base size is compared to the current size. If the current size is
    # bigger than the specified percentage, the rewrite is triggered. Also
    # you need to specify a minimal size for the AOF file to be rewritten, this
    # is useful to avoid rewriting the AOF file even if the percentage increase
    # is reached but it is still pretty small.
    #
    # Specify a percentage of zero in order to disable the automatic AOF
    # rewrite feature.
    
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    
    
2.3.3 重写原理

重写AOF文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的AOF文件,替换原有的文件,和快照有点类似

  1. redis调用fork产生子进程(1),子进程根据内容中的数据生成快照(2),往临时文件夹中写入重建数据库状态的命令。
  2. 父进程继续处理client请求(3),除了把命令写入到原来的aof文件中(4),同时还把收到的新的写入命令缓存起来(5)。这样就能保证如果子进程重写失败并不会出问题。
  3. 当子进程把快照内容以命令形式写入到临时文件中后(6),子进程发信号通知父进程(7),然后把父进程缓存的命令也写入到临时文件中(8)。
  4. 父进程用临时文件替换老的aof文件(9),并重命名。后面收到的新命令也开始往新的aof文件中追加(10)。

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值