美文网首页
简介redis之持久化

简介redis之持久化

作者: 温岭夹糕 | 来源:发表于2021-03-01 22:34 被阅读0次

    前言

    为避免因服务器宕机,导致内存数据全部丢失的情况,Redis提供了AOF日志和RDB快照的持久化机制

    思考

    1.AOF的特点,三种解决aof日志阻塞问题策略的缺点,如何重写AOF日志
    2.RDB快照时数据能修改吗

    AOF(Append Only File)

    mysql的innodb引擎在记录日志时先写redolog再写binlog,其中redolog为写前日志(Write Ahead Log,WAL),在写实际数据前,先把修改的数据记录到日志文件中。
    而redis的AOF日志为写后日志,在命令执行后再记录日志

    开启AOF:
    –appendonly yes

    实验如下:

    vim redis.sh
    //内容如下
    #! /bin/bash
    docker run -d -p 6379:6379 --name redis -v /home/docker/redis/redis.conf:/etc/redis/redis.conf -v /home/docker/redis/data:/data redis:5.0.5 redis-server /etc/redis/redis.conf
    //启动脚本,运行docker容器
    ./redis.sh
    //进入容器
    docker exec -it redis redis-cli
    //进入容器执行set操作并退出容器
    set name z3
    quit
    //查看是否生成aof后缀文件
    ll ./data && cat ./data/*.aof
    //停止并删除当前redis容器
    docker stop redis
    docker rm -f $(docker ps  -aq) //不推荐这样操作因为我当前只有一个容器
    //重新运行脚本生成全新的redis容器
    ./redis.sh
    docker exec -it redis redis-cli
    get name //结果为z3
    

    通过上述实验我们知道aof日志记录的是redis收到的每一条命令且以文本形式存在,当重启redis时会自动读取加载aof里的内容

    虽然aof不会阻塞当前操作,但是会对下一个操作带来阻塞风险(aof也在主线程中执行,把日志写入磁盘 ,磁盘写压力大时,导致写盘慢,后续操作被阻塞)
    对于这个问题aof提供了三个选项

    appendfsync的值
    always:同步写回,顾名思义,执行完命令立即写
    everysec:每秒,先写缓冲区,隔一秒写入
    no: 操作时间由系统决定

    但三种策略都不是完美无缺

    aof日志文件过大怎么办

    aof是以文件形式记录并追加所有命令,随着时间的推移,文件会越来越大,文件太大,除了追加命令的效率也低,也会造成恢复redis数据非常缓慢的现象
    aof提供了重写机制
    在重写时会创建新的AOF文件,同时为了缩小文件体积,会将旧文件中的多条命令合并成一条(当一个键被反复修改时,重写只用一条)
    重写日志和aof主日志不同,为避免阻塞由后台bgrewriteaof完成,重写过程为“一个拷贝,两处日志”

    一个拷贝:主线程fork出后台进程,并将内存拷贝给它,用于重写
    两处日志:主线程未阻塞,当有写操作,第一处日志指正在使用的aof日志,redis会把操作写到缓冲区;第二处指新的aof重写日志,这个操作也会写道重写日志缓冲区,拷贝完后写入

    RDB(Redis DataBase)

    与AOF记录所有命令相比,RDB记录的是某一时刻的数据,所以在做恢复的时候,可以直接把RDB文件读入内存,很快完成恢复(rdb是redis默认的持久化方案,会生成dump.rdb文件),同时conf文件内的save配置可设置快照的时间
    主动生成RDB文件命令

    save:在主线程中执行,会阻塞(这肯定不能接受)
    bgsave:创建子进程用于写rdb文件

    快照时数据能修改吗

    为了保证快照的完整性,暂停写操作,这redis肯定不能接受,所以这个时候,redis会借助操作系统提供的写时复制技术(copy-on-write,COW)
    bgsave子进程由主线程fork生成,共享主线程内的所有内存数据。
    此时某个时间点主线程要修改一块数据(set name a),那么这块数据就会被复制一份生成该数据的副本,bgsave子进程把这个副本数据写入文件,这个过程中主线程仍可直接修改原数据。

    混合方案

    虽然RDB比aof恢复快,但是快照的频率很难把握(过多会增加磁盘写压力),因此redis4.0提出了混合使用的方案

    aof-use-rdb-preamble yes

    相关文章

      网友评论

          本文标题:简介redis之持久化

          本文链接:https://www.haomeiwen.com/subject/avcwfltx.html