• Redis持久化方式RDB和AOF


    Redis 持久化


    1. RDB(快照)

        优点 

      • rdb是可进行压缩的二进制文件,表示Redis在某一个时间点的数据快照。非常使用与备份,灾难恢复等场景.比如使用定时任务执行bgsave并备份rdb到server或其他文件系统中,用于恢复数据.
      • rdb加载速度快于AOF方式

        缺点

      • RDB不可以做到实时持久化,容易造成数据丢失,假如频繁使用bgsave强行实时持久化,会非常影响性能,因为创建fork子进程也是有阻塞产生的
      • RDB使用特定的二进制保存,随着redis的不断更新,会有多个格式的RDB版本,会产生兼容问题

      2. AOF(追加)

        优点

      • 比RDB要可靠,可以定制不同的fsync策略(appendfsync everysec/no/always),默认是appendfsync everysec,每秒fsync一次,意味着最多丢失1s的数据
      • AOF是一个纯追加的文件,遇到宕机基本也不会影响磁盘上的aof日志文件
      • 档aof太大时,redis会自动进行重写(重写在一个新的文件,与此同时reids会继续往旧的aof文件追加日志信息,当新文件写完时会用新文件覆盖旧文件,之后日志信息开始往新文件追加)

        缺点

      • 相同数据集,aof文件要大于rdb文件
      • AOF速度稍慢与RDB

    RDB 


     RDB持久化是把当前进程数据生成的快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发

      1.手动触发,使用save和bgsave命令

      • save:阻塞当前redis服务器,直到持久化完成为止,对于内存较大的实例会造成长时间的阻塞,线上环境禁止使用,已经被废弃.
    root@e7576f2fbb11:/# redis-cli save
    OK
    root@e7576f2fbb11:/# redis-cli info|grep save        #查看持久化相关信息
    rdb_changes_since_last_save:0
    rdb_bgsave_in_progress:0
    rdb_last_save_time:1497083505
    rdb_last_bgsave_status:ok
    rdb_last_bgsave_time_sec:0
    rdb_current_bgsave_time_sec:-1
    root@e7576f2fbb11:/# tail -n 4 /var/log/redis/redis-server.log
    61:C 10 Jun 08:20:46.257 * DB saved on disk
    61:C 10 Jun 08:20:46.258 * RDB: 0 MB of memory used by copy-on-write
    29:M 10 Jun 08:20:46.316 * Background saving terminated with success
    29:M 10 Jun 08:31:45.676 * DB saved on disk            ###运行redis-cli save对应的redis服务日志
      • bgsave: redis进程执行fork操作创建子进程,RDB持久化由这个子进程负责,完成后自动结束.阻塞仅仅会发生在fork阶段,时间非常非常的短,bgsave是对save的优化.
    root@e7576f2fbb11:/# redis-cli bgsave
    Background saving started
    root@e7576f2fbb11:/# redis-cli info|grep fork
    latest_fork_usec:771                  #####最近一次fork子进程阻塞用的时间us
    root@e7576f2fbb11:/# redis-cli info|grep save     #####获取持久化相关信息
    rdb_changes_since_last_save:0
    rdb_bgsave_in_progress:0
    rdb_last_save_time:1497084106             ####最后一个RDB时间
    rdb_last_bgsave_status:ok
    rdb_last_bgsave_time_sec:0
    rdb_current_bgsave_time_sec:-1
    root@e7576f2fbb11:/# tail -n 4 /var/log/redis/redis-server.log    ####使用bgsave持久化redis服务产生的日志
    29:M 10 Jun 08:41:46.346 * Background saving started by pid 77
    77:C 10 Jun 08:41:46.380 * DB saved on disk
    77:C 10 Jun 08:41:46.381 * RDB: 0 MB of memory used by copy-on-write
    29:M 10 Jun 08:41:46.385 * Background saving terminated with success
    

      2.自动触发

        2.1 通过reids.conf配置动触发bgsave

        2.2 当从节点执行全量复制操作时,主节点自动执行bgsave生成bgsave RDB文件并发送给从节点.

        2.3 当使用redis-cli  shutdown关闭redis服务时,如果没有开启AOF持久化功能则也会自动执行bgsave

    root@e7576f2fbb11:/# grep 'save' /etc/redis/redis.conf
    #   save <seconds> <changes>
    #   Will save the DB if both the given number of seconds and the given
    #   In the example below the behaviour will be to save:
    #   Note: you can disable saving completely by commenting out all "save" lines.
    #   It is also possible to remove all the previously configured save
    #   points by adding a save directive with a single empty string argument
    #   save ""
    save 900 1        ###900s内至少一次改动,自动触发bgsave
    save 300 10        ###300s内至少10次改动,自动触发bgsave
    save 60 10000      ###60s内至少10000次改动,自动触发bgsave
    # save ""        ###如果最后一行是save ""则上面自动触发bgsave规则会失效

      3.bgsave运作流程

    • 执行bgsave命令后,redis主进程判断当前是否存在正在执行的(AOF或者RDB)子进程,如果存在则直接返回bgsave命令.
      • root@e7576f2fbb11:/# redis-cli bgsave;redis-cli bgsave
        Background saving started
        (error) ERR Background save already in progress
    • 父进程fork子进程过程中,父进程会短暂的阻塞,通过redis-cli info|grep fork可以获得最近一个fork的操作耗时,单位为us,微秒.
    • 父进程fork子进程成功后,返回Background saving started,并停止阻塞主进程,可以继续响应其它指令.
    • 子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行lastsave命令可以获取最后一次RDB生成的时间.
    • 子进程发送信号给父进程表示完成,父进程更新统计信息.redis-cli  info可以查看redis状态.

      4.RDB文件相关信息

      

    root@e7576f2fbb11:/# egrep -i "filename|dir" /etc/redis/redis.conf
    # line as value of a configuration directive, you'd better put includes
    # interfaces using the "bind" configuration directive, followed by one or
    #   points by adding a save directive with a single empty string argument
    # The filename where to dump the DB
    dbfilename dump.rdb          #RDB文件保存的文件名,默认采取压缩
    # The working directory.
    # The DB will be written inside this directory, with the filename specified
    # above using the 'dbfilename' configuration directive.
    # The Append Only File will also be created inside this directory.
    # Note that you must specify a directory here, not a file name.
    dir /var/lib/redis          ###RDB文件保存目录
    

     在redis正常运行过程中如果默认的RDB存储路径磁盘写满或不能正常写时,可以使用config set dbfilename newfilename和config set dir newdir动态改变默认的存储路径.

    root@e7576f2fbb11:/# redis-cli -h 127.0.0.1 -p 6379  config set dir /var/lib/
    OK
    root@e7576f2fbb11:/# redis-cli -h 127.0.0.1 -p 6379  config set filename newfilename.rdb
    (error) ERR Unsupported CONFIG parameter: filename
    root@e7576f2fbb11:/# redis-cli -h 127.0.0.1 -p 6379  config set dbfilename newfilename.rdb
    OK
    root@e7576f2fbb11:/# redis-cli bgsave
    Background saving started
    root@e7576f2fbb11:/# ls -l /var/lib/newfilename.rdb
    -rw-r--r-- 1 root root 34 Jun 10 09:28 /var/lib/newfilename.rdb
    root@e7576f2fbb11:/# date
    Sat Jun 10 09:29:14 UTC 2017
    root@e7576f2fbb11:/#
    root@e7576f2fbb11:/# redis-check-dump /var/lib/newfilename.rdb        #####使用redis-check-dump 工具检测RDB文件是否有问题.
    ==== Processed 3 valid opcodes (in 17 bytes) ===================================
    CRC64 checksum is OK

    AOF


    AOF(append only file)持久化:使用独立的日志的方式记录每次写的命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的.AOF的主要作用是解决了数据持久化的实时性.

    如果要开启AOF需要修改redis.conf配置:appendonly  yes(默认不开启:appendonly no)

    通过定义appendfilename和dir修改aof文件名和保存路径.

    AOF工作流程:

    1. 所有的写入命令追加到缓冲区中(redis是单线程响应方式,如果实时追加到硬盘,会影响性能.同时也是fsync策略起作用的前提)
    2. AOF缓冲区根据对应的fsync策略向硬盘做同步操作
    3. 随着AOF文件越来越大,需要定期AOF文件进行重写,达到"压缩"文件的目的
    4. 重启redis时,可以加载AOF文件进行数据恢复.

    文件同步

      redis提供多种缓冲区同步文件策略,由参数appendfsync控制,不同值含义如下:

    可配置值说明
    always 命令写入aof_buf后调用fsync同步操作同步到aof文件,fsync同步完成后线程返回
    everysec 命令写入aof_buf后调用系统write操作,write完成后线程返回,fsync操作由专门线程每秒调用一次 (建议配置)
    no 命令写入aof_buf后调用系统write操作,不对aof文件做fsync同步,同步硬盘由操作系统负责,通常最长同步周期30秒

    系统调用write和fsync说明

    • write 操作会触发延迟写机制.Linux在内核提供页缓冲区用来提高IO性能.write操作在写入系统缓冲区后直接返回.同步硬盘操作依赖于系统调度的机制,比如当缓冲区页空间写满或达到特定时间周期时触发.同步文件之前,如果此时系统宕机,缓冲区数据会丢失.
    • fsync这对单个文件操作,做强制磁盘同步,fsync将阻塞知道写入硬盘完成后返回,保证数据持久化.

    重写机制

      随着不断的追加写入,aof文件越来越大,此时重写机制会压缩文件大小.重写指的是:把redis进程内的数据转化为写命令同步到新AOF文件的过程.

      重写使aof文件变小原因:

      1. 过期的数据不会写入
      2. 多余的命令不会写入
      3. 多条命令的合并(lpush list a lpush list b lpush c====>lpush list a b c)  

      重写的触发

      • 手动调用  bgrewriteaof命令
      • 自动触发  根据配置文件中auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机
        • auto-aof-rewrite-min-size: 表示重写aof时,文件的最小体积,default64MB(重写优先条件,必须满足)
        • auto-aof-rewrite-min-percentage: 表示当前aof文件大小和上次重写后aof文件大小的比值.

      重写运作流程

      1. 执行bgrewriteaof请求如果当前正字执行aof,直接返回,如果在执行bgsave则推迟到bgsave完成后再执行
      2. redis调用fork产生一个子进程(开销同RDB)
      3. 主进程持续把新的变动写到aof_buf并仍然沿用appendfsync策略同步到磁盘,即旧的aof文件,由于fork使用写时复制技术,子进程只能共享fork操作时的内存数据,所以新的变动同时也要在aof_rewrite_buf存一份,防止新的aof文件生成期间丢失这部分数据
      4. 根据规则重写aof文件(新)
      5. 新aof文件写入完成后,子进程通知父进程,父进程更新信息.
      6. 父进程把aof_rewrite_buf写入新的aof文件 
      7. 新aof文件替换老的aof文件

     

     

     

    重启加载


    1. AOF持久化开启且存在AOF文件时,优先加载AOF文件

    2. AOF关闭或AOF文件不存在时,加载RDB文件(前提是RDB存在,不存在也会启动)

    3.加载AOF/RDB文件成功后,rdis启动成功

    4. AOF/RDB存在错误时,启动失败

  • 相关阅读:
    Pytorch手写线性回归
    numpy+sklearn 手动实现逻辑回归【Python】
    如何用TensorFlow实现线性回归
    进程、线程和携程的通俗解释【刘新宇Python】
    即时通信WebSocket 和Socket.IO
    gRPC【RPC自定义http2.0协议传输】
    Django中MySQL事务的使用
    模拟电磁曲射炮_H题 方案分析【2019年电赛】【刘新宇qq522414928】
    Gitflow工作流
    雪花算法【分布式ID问题】【刘新宇】
  • 原文地址:https://www.cnblogs.com/diaosir/p/6979780.html
Copyright © 2020-2023  润新知