美文网首页
redis持久化

redis持久化

作者: 杨健kimyeung | 来源:发表于2020-08-19 10:11 被阅读0次

    一、概要

    Redis主要提供了两种持久化机制,主要用于宕机或者重启后,redis的恢复工作

    • RDB
    • AOF

    如果你没有数据持久化的需求,也可以完全关闭RDB和AOF方式,提高性能

    二、RDB

    1、概念

    Redis DataBase 默认开启,会按照配置的指定时间将内存中的数据快照到磁盘中,创建一个dump.rdb文件,redis启动时再恢复到内存中。

    2、工作过程

    1. redis会单独创建fork()一个子进程
    2. 将当前父进程的数据库数据复制到子进程的内存中
    3. 然后由子进程将数据先写入临时文件
    4. 写入成功后,再替换之前的文件
    5. 二进制压缩存储
    6. 然后子进程退出,内存释放

    3、注意事项

    • 每次快照持久化都会将主进程的数据库数据复制一遍,导致内存开销加倍
    • 若此时内存不足,则会阻塞服务器运行,直到复制结束释放内存;
    • 都会将内存数据完整写入磁盘一次,所以如果数据量大的话,
    • 而且写操作频繁,必然会引起大量的磁盘I/O操作,严重影响性能,
    • 并且最后一次持久化后的数据可能会丢失;

    5、缺点

    • 持久化粒度比较大,如果save, shutdown, slave 之前宕机或者重启了,则中间的操作没办法恢复
    • fork的需要考虑内存的消耗
    • fork过程比较耗时,可能会影响客服端访问

    5、配置相关

    redis.conf

    save [seconds] [changes]
    # 如果要禁用功能则使用: 
    save ""
    
    # 如果在900秒内有1次改动(增删改),则保存到硬盘中
    save 900 1
    # 如果在300秒内有10次改动(增删改),则保存到硬盘中
    save 300 10 
    
    save 60 10000
    # 如果在60秒内有10000次改动(增删改),则保存到硬盘中
    # 多个策略可以并用,可以配置多个save...
    

    压缩配置

    # 默认是开启 会造成cpu压力,不建议关闭
    rdbcompression yes
    

    自定义本地数据库文件

    dbfilename dump.rdb
    

    指定本地数据库存放目录

    # 上面这个./是个变动的值,启动的命令在哪个路径,那么就是在哪个路径
    dir  ./
    

    6、保存命令

    # 当写入数据到硬盘出错,则停止保存到硬盘
    stop-writes-on-bgsave-error yes
    # 存储快照后,进行数据校验
    rdchecksum yes
    

    手动保存命令

    # 阻塞操作,其他操作不能执行 因为redis是单线程 开发中不建议使用
    save
    
    # 后台异步执行保存快照操作
    bgsave 
    

    查看快照命令

    # 查看最后一次成功执行快照的时间
    lastsave
    

    三、AOF

    1、概念

    Append Only File,即只允许追加不允许改写的文件

    将redis执行过的所有写指令记录在日志中,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了

    2、AOF持久化策略

    • **AOF_FSYNC_NO **

      每次都会把aof_buf中的内容写入到磁盘,但是不会调用fsync函数;

    • AOF_FSYNC_ALWAYS

      每次都会把aof_buf中的内容写入到磁盘,同时调用fsync函数;

    • AOF_FSYNC_EVERYSEC

      定期(至少1s)去调用fsync,并且该操作是放到一个异步队列中(线程)去执行,因此不会阻塞主进程

      会丢失 1 秒钟的数据

    说明

    • AOF_FSYNC_ALWAYS 每次都写入文件都会调用fsync,所以这种flush策略可以保证数据的完整性,缺点就是性能太差(因为fysnc是个同步调用,会阻塞主进程对客户端请求的处理)
    • AOF_FSYNC_NO 由于依赖于操作系统自动sync,因此不能保证数据的完整性
    • AOF_FSYNC_EVERYSEC 折中方案 既能不过分降低系统的性能,又能最大程度上的保证数据的完整性

    3、AOF重写

    AOF 的工作过程是不断地将命令追加到文件的末尾, 但随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。例如对商品的库存递减的操作时,可能恢复的时候我只需要最终的结果,但Redis会将递减的过程的命令也会记录下来 ,为了解决这种问题,redis提供了一种解决方法 **重建(rebuild) **。

    执行 BGREWRITEAOF 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令

    触发机制是当aof文件大小是上次重写后大小的一倍且文件大于64M时触发

    4、工作过程

    1. 开始重写,redis会创建(fork)一个重写子进程,这个子进程会首先读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中。
    2. 与此同时,主工作进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外。
    3. 重写子进程完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中。
    4. 当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中了。

    5、AOF文件出现了被写坏的情况

    1. 备份被写坏的AOF文件
    2. 运行redis-check-aof –fix进行修复
    3. 用diff -u来看下两个文件的差异,确认问题点
    4. 重启redis,加载修复后的AOF文件

    四、两种方式的优缺点

    • RDB需要定时持久化,风险是可能会丢两次持久之间的数据,量可能很大。

    • AOF每秒fsync一次指令硬盘,如果硬盘IO慢,会阻塞父进程;风险是会丢失1秒多的数据;在Rewrite过程中,主进程把指令存到mem-buffer中,最后写盘时会阻塞主进程。

    五、如何选择

    没有最优的方案,只有合不合适 具体根据实际工作情况来定

    1. 一般来说,如果想尽可能的保证数据安全性, 你应该同时使用两种持久化功能并且官方也推荐我们这么做。
    2. 如果可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
    3. AOF每秒fsync一次指令硬盘,如果硬盘IO慢,会阻塞父进程;风险是会丢失1秒多的数据;在Rewrite过程中,主进程把指令存到mem-buffer中,最后写盘时会阻塞主进程

    六、备份与恢复

    redis的备份和还原,可以借助第三方的工具redis-dump

    1、备份

    导出

    # 导出命令
    redis-dump –u 127.0.0.1:6379 > back_20191116.json
    # 导出指定数据库数据
    redis-dump -u 127.0.0.1:6379 -d 15 > back_20191116.json
    # 如果redis设有密码
    redis-dump –u :password@127.0.0.1:6379 > back_20191116.json
    

    导入

    < back_20191116.json redis-load
    # 如果redis设有密码
    < back_20191116.json redis-load -u :password@127.0.0.1:6379
    

    2、恢复过程

    当两种方式同时开启时

    • 数据恢复redis会优先选择AOF恢复。
    • 一般情况下,只要使用默认开启的RDB即可,因为相对于AOF,RDB便于进行数据库备份,并且恢复数据集的速度也要快很多

    相关文章

      网友评论

          本文标题:redis持久化

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