• Redis的持久化方式


    Redis的持久化方式

    一、什么是持久化?

           持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。

     

    二、Redis为什么要持久化?

           Redis是一个内存数据库,所有的数据将保存在内存中,这与传统的MySQL、Oracle、SqlServer等关系型数据库直接把数据保存到硬盘相比,Redis的读写效率非常高。但是保存在内存中也有一个很大的缺陷,一旦断电或者宕机,内存数据库中的内容将会全部丢失。为了弥补这一缺陷,Redis提供了把内存数据持久化到硬盘文件,以及通过备份文件来恢复数据的功能。

    三、Redis官方提供了不同级别的持久化方式

    1、RDB(Redis DataBase)

          在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。

          它是Redis数据库中数据的内存快照,并且是一个二进制文件(默认名称为dump.rdb,可修改),存储了文件生成时Redis数据库中所有的数据内容。可用于Redis的数据备份、转移与恢复。

    1) 配置文件参数及说明

     

    在redis.conf配置文件中可以配置:
    ################################ SNAPSHOTTING  ################################
    # Redis触发自动备份的触发策略
    # save <seconds> <changes>
    save 900 1     # 在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照
    save 300 10    # 在300秒(5分钟)之后,如果至少有10个key发生变化,则dunp内存快照
    save 60 10000  # 在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照
    
    # 如果持久化出错,主进程是否停止写入
    stop-writes-on-bgsave-error yes
    
    # 是否压缩
    rdbcompression yes
    
    # 导入时是否检查
    rdbchecksum yes
    
    # 文件名称
    dbfilename dump.rdb
    
    # 文件保存路径
    dir /www/server/redis/

    2) RDB持久化工作原理

    •       Redis调用fork(),产生一个子进程。
    •       子进程把数据写到一个临时的RDB文件。
    •       当子进程写完新的RDB文件后,把旧的RDB文件替换掉。

    3) RDB持久化触发方式

     

    手动触发

        save:会阻塞redis的服务器进程,直到RDB文件被创建完毕,线上环境应该禁止使用。

        bgsave:该触发方式会fork一个子进程,由子进程负责持久化过程,因此阻塞只会发生在fork子进程的时候。

        

       

        重启redis服务端和客户端,看数据是否真的持久化了

       

       

    自动触发

        1)根据 save <seconds> <changes> 配置规则自动触发

        2)从节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发 bgsave

        3)执行 debug reload 时

        4)执行 shutdown时,如果没有开启aof,也会触发

        说明:自动触发对应 bgsave 命令,Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。

        由于 save 基本不会被使用到,我们重点看看 bgsave 这个命令是如何完成RDB的持久化的。

     

     

         这里需要注意的是 fork 操作会阻塞,导致Redis读写性能下降。我们可以控制单个Redis实例的最大内存,来尽可能降低Redis在fork时的事件消耗。以及上面提到的自动触发的频率减少fork次数,或者使用手动触发,根据自己的机制来完成持久化。

    4) RDB持久化优缺点

    优点

          1)RDB文件是一个很简洁的单文件,它保存了某个时间点的Redis数据,很适合用于做备份。你可以设定一个时间点对RDB文件进行归档,这样就能在需要的时候很轻易的把数据恢复到不同的版本。

          2)基于上面所描述的特性,RDB很适合用于灾备。单文件很方便就能传输到远程的服务器上。

          3)RDB的性能很好,需要进行持久化时,主进程会fork一个子进程出来,然后把持久化的工作交给子进程,自己不会有相关的I/O操作。

          4)比起AOF,在数据量比较大的情况下,RDB的启动速度更快。

    缺点

          1)RDB容易造成数据的丢失。假设每5分钟保存一次快照,如果Redis因为某些原因不能正常工作,那么从上次产生快照到 Redis 出现问题这段时间的数据就会丢失了。

          2)RDB方式无法做到实时或秒级持久化。因为 RDB 使用 fork() 产生子进程进行数据的持久化,而fork操作是一个耗时操作,无法做到实时性。如果数据比较大的话可能就会花费点时间,造成Redis停止服务几毫秒。如果数据量很大且CPU性能不是很好的时候,停止服务的时间甚至会达到1秒。

    2、AOF(Append Only File)

          快照功能(RDB)并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。

         1)配置文件参数以及说明

         开启AOF功能需要配置:appendonly yes,默认不开启。

        2)工作原理

         AOF持久化会把被执行的写命令写到AOF文件的末尾,记录数据的变化。默认情况下,Redis是没有开启AOF持久化的,开启后,每执行一条更改Redis数据的命令,都会把该命令追加到AOF文件中,这是会降低Redis的性能,但大部分情况下这个影响是能够接受的,另外使用较快的硬盘可以提高AOF的性能

         AOF的整个流程大体来看可以分为两步,第一步是命令的实时写入(如果是 appendfsync everysec 配置,会有1s损耗),第二步是对 aof 文件的重写。

         aof 重写是为了减少aof文件的大小,使得 AOF文件的体积不会超出保存数据集状态所需的实际大小。可以手动或者自动触发。fork的操作也是发生在重写这一步,也是这里会对主进程产生阻塞。

         实际上,AOF持久化并不会立即将命令写入到硬盘文件中,而是写入到硬盘缓存,在接下来的策略中,配置多久来从硬盘缓存写入到硬盘文件。所以在一定程度一定条件下,还是会有数据丢失,不过可以大大减少数据损失。

    重写的流程图如下:

    AOF持久化提供三种策略:

     

    always: 每次操作都会立即写入aof文件中

    everysec: 每秒持久化一次(默认配置)

    no: 不主动进行同步操作,默认30s一次。写入AOF文件中的操作由操作系统决定,一般而言为了提高效率,操作系统会等待缓存区被填满,才会开始同步数据到磁盘。

    3)触发方式

    手动触发

          bgrewriteaof

    自动触发

         根据配置规则来触发,当然自动触发的整体时间还跟Redis的定时任务频率有关系。

    4)AOF持久化优缺点

    优点

        1) 比RDB可靠

        可以制定不同的fsync策略:不进行fsync、每秒fsync一次和每次查询进行fsync。默认是每秒fsync一次。这意味着最多丢失一秒钟的数据。

        2)AOF日志文件是一个纯追加的文件

        就算是遇到突然停电的情况,也不会出现日志的定位或者损坏问题。甚至如果因为某些原因(例如磁盘满了)命令只写了一半到日志文件里,我们也可以用redis-check-aof这个工具很简单的进行修复。

        3)通过重写来减少aof文件的大小

        当AOF文件太大时,Redis会自动在后台进行重写。重写很安全,因为重写是在一个新的文件上进行,同时Redis会继续往旧的文件追加数据。新文件上会写入能重建当前数据集的最小操作命令的集合。当新文件重写完,Redis会把新旧文件进行切换,然后开始把数据写到新文件上。

        4)快速恢复数据

        AOF把操作命令以简单易懂的格式一条接一条的保存在文件里,很容易导出来用于恢复数据。例如我们不小心用FLUSHALL命令把所有数据刷掉了,只要文件没有被重写,我们可以把服务停掉,把最后那条命令删掉,然后重启服务,这样就能把被刷掉的数据恢复回来。
    缺点:

    •     在相同的数据集下,AOF文件的大小一般会比RDB文件大。
    •     在某些fsync策略下,AOF的速度会比RDB慢。通常fsync设置为每秒一次(everysec)就能获得比较高的性能,而在禁止fsync的情况下速度可以达到RDB的水平。
    •     在过去曾经发现一些很罕见的BUG导致使用AOF重建的数据跟原数据不一致的问题。

    3、同时开启RDB和AOF

         在这种情况下,当redis重启的时候会优先载入 AOF 文件来恢复原始的数据。因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整。

    4、不使用持久化

         数据的生命周期只存在于服务器的运行时间里

    参考链接:

    https://segmentfault.com/a/1190000002906345

    http://redisdoc.com/topic/persistence.html

    https://www.cnblogs.com/xuwenjin/p/9876432.html

    https://juejin.cn/post/6844903655527677960

  • 相关阅读:
    codeblocks多文件联合编译
    C++顶层const和底层const的区别
    keras failed to create cublas handle:CUBLAS_STATUS_ALLOC_FAILED问题
    Notepad++强大的代码补全和代码提示功能的方法
    PEP8编码风格
    在Maven项目中使用easypoi完成Excel文件上传下载
    Restful风格,使用同一地址,访问不同的方法
    注解@NoRepositoryBean的作用
    注解@MappedSuperclass的作用
    Shiro整合Spring以及权限登陆过滤
  • 原文地址:https://www.cnblogs.com/hld123/p/14701845.html
Copyright © 2020-2023  润新知