zoukankan      html  css  js  c++  java
  • [Redis]持久化

    redis是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失。

    幸好Redis还为我们提供了持久化的机制,分别是RDB(Redis DataBase)AOF(Append Only File)。   

    一:持久化流程

    1:客户端向服务端发送写操作(数据在客户端的内存中)。

    2:数据库服务端接收到写请求的数据(数据在服务端的内存中)。

    3:服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)。

    4:操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)。

    5:磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)。

       这5个过程是在理想条件下一个正常的保存流程,但是在大多数情况下,我们的机器等等都会有各种各样的故障,这里划分了两种情况:

    1:Redis数据库发生故障,只要在上面的第三步执行完毕,那么就可以持久化保存,剩下的两步由操作系统替我们完成。

    2:操作系统发生故障,必须上面5步都完成才可以

    二:RDB机制

    RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,

    这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb

    既然RDB机制是通过把某个时刻的所有数据生成一个快照来保存,那么就应该有一种触发机制,是实现这个过程。

    对于RDB来说,提供了两种机制:手动触发(save、bgsave)、自动触发。

    2.1:save触发方式

      该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止。具体流程如下:

     

      执行完成时候如果存在老的RDB文件,就把新的替代掉旧的。我们的客户端可能都是几万或者是几十万,这种方式显然不可取。

    2.2:bgsave触发方式

      执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下:

       具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。

    阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。

    2.3:自动触发

      自动触发是由我们的配置文件来完成的。在redis.conf配置文件中,里面有如下配置:

      save:这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。

            比如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。

       stop-writes-on-bgsave-error :默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。

                     这会让用户意识到数据没有正确持久化到磁盘上,否则没有人会注意到灾难(disaster)发生了。

                     如果Redis重启了,那么又可以重新开始接收数据了

      rdbcompression :默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。

      rdbchecksum :默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,

                但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

      dbfilename :设置快照的文件名,默认是 dump.rdb

      dir:设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。

    2.4:两种手动触发比较

     

    2.5:RDB的优点和缺点

      优点

      1:RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快

      2:节省磁盘空间

       缺点

      1:虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能

      2:在一定周期,在一定间隔时间做一次备份,所以如果Redis意外down掉,就会丢失最后一次快照后的所有修改

    三:AOF机制

    以日志的形式来记录每个写操作。将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件,不可以改写文件。

    Redis启动之初会读取该文件重新构建数据,通俗的理解就是日志记录

    3.1:AOF原理

    3.2:AOF文件重写原理

    AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。为了压缩aof的持久化文件。

    redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写

    重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容

    用命令的方式重写了一个新的aof文件,这点和快照有点类似

     

    3.3:三种触发机制

    1:每修改同步always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好

    2:每秒同步everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失

    3:不同no:从不同步

    3.4:AOF的优点和缺点

      优点

      1:备份机制更健全,丢失数据概率低

      2:AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。

      3:AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。

         比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,

           将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据

      缺点

      1:比起RDB占用更多的磁盘空间

      2:恢复备份速度慢

      3:每次读写都同步的话,有一定的性能压力

      4:存在个别Bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来。

    四、RDB和AOF到底该如何选择

      选择的话,两者加一起才更好。因为两个持久化机制你明白了,剩下的就是看自己的需求了

      需求不同选择的也不一定,但是通常都是结合使用。有一张图可供总结

  • 相关阅读:
    PHP实现无限极分类
    html2canvas生成并下载图片
    一次线上问题引发的过程回顾和思考,以更换两台服务器结束
    Intellij IDEA启动项目报Command line is too long. Shorten command line for XXXApplication or also for
    mq 消费消息 与发送消息传参问题
    idea 创建不了 java 文件
    Java switch 中如何使用枚举?
    Collections排序
    在idea 设置 git 的用户名
    mongodb添加字段和创建自增主键
  • 原文地址:https://www.cnblogs.com/yan-sh/p/13162736.html
Copyright © 2011-2022 走看看