zoukankan      html  css  js  c++  java
  • Redis基础(三)Redis持久化:RDB与AOF

    什么是Redis持久化?

    Redis是键值对的内存数据库,它将数据存储在内存里。客户端发送命令到服务器,再由服务器到内存里查找数据。

    image

    一旦Redis服务器进程退出,存储在内存里的数据就会丢失。

    image

    为了解决这个问题,Redis提供了持久化机制,即将数据保存到磁盘里,以便Redis服务器进程初始化或重启后重新加载数据,避免数据丢失。

    image

    Redis提供两种持久化方案,分别是RDB(Redis DataBase)和AOF(Append Only File)。

    RDB持久化

    RDB采用快照的方式来实现持久化,把数据库数据保存到RDB文件里,也可以通过RDB文件还原数据库数据。

    image

    开启RDB持久化的方式

    RBD是Redis默认的持久化方案,可以通过三种方式来生成RDB文件:SAVE、BGSAVE和自动触发,其中前两种是主动操作,后一种是被动操作,由Redis服务器控制。

    SAVE

    SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完成,在服务器进程阻塞期间,服务器不能处理任何命令请求。

    redis> Save // 等待直到RDB文件创建完成
    OK
    

    image

    BGSAVE

    和SAVE命令直接阻塞服务器进程不同,BGSAVE命令会fork一个子进程来负责创建RDB文件,服务器进程继续处理命令请求。

    redis> BGSAVE // fork子进程,并由子进程创建RDB文件
    Background saving started
    

    image

    自动触发

    Redis允许用户通过设置服务器配置的save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。用户可以通过save选项设置多个条件,只要满足其中任意一个条件,服务器就会执行BGSAVE命令。

    save 900 1 // 服务器在900秒内,至少1次修改
    save 300 10 // 服务器在300秒内,至少10次修改
    save 60 10000 // 服务器在60秒内,至少10000次修改
    

    AOF持久化

    除了RDB外,Redis还提供了AOF。与RDB通过保存数据库快照不同,AOF是通过保存命令来记录数据库数据的。默认情况下,Redis是没有开启AOF的,可以通过配置redis.conf文件来开启AOF持久化,关于AOF的配置如下:

    # appendonly参数开启AOF持久化
    appendonly no
    
    # AOF持久化的文件名,默认是appendonly.aof
    appendfilename "appendonly.aof"
    
    # AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的
    dir ./
    
    # 同步策略
    # appendfsync always
    appendfsync everysec
    # appendfsync no
    
    # aof重写期间是否同步
    no-appendfsync-on-rewrite no
    
    # 重写触发配置
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    
    # 加载aof出错如何处理
    aof-load-truncated yes
    
    # 文件重写策略
    aof-rewrite-incremental-fsync yes
    

    AOF持久化实现

    AOF需要记录Redis的每个命令,步骤分为:命令追加(append)、文件写入(write)和文件同步(sync)。

    命令追加

    当AOF持久化功能处于打开状态时,服务器在执行完一个写命令之后,会以协议格式将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾。

    文件写入和同步

    关于何时将 aof_buf 缓冲区的内容写入AOF文件中,Redis提供了三种策略:

    • appendfsync always:将aof_buf缓冲区中的所有内容写入并同步到AOF文件。
    • appendfsync everysec:将aof_buf缓冲区中的所有内容写入到AOF文件,如果上次同步AOF文件的时间距离现在超过1秒,那么两次对AOF文件进行同步,并且这个同步操作是由一个线程专门负责执行的。
    • appendfsync no:将aof_buf缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,何时同步由操作系统来决定。

    关于AOF的同步策略是涉及到操作系统的 write 函数和 fsync 函数的,在《Redis设计与实现》中是这样说明的:

    为了提高文件写入效率,在现代操作系统中,当用户调用write函数,将一些数据写入文件时,操作系统通常会将数据暂存到一个内存缓冲区里,当缓冲区的空间被填满或超过了指定时限后,才真正将缓冲区的数据写入到磁盘里。


    这样的操作虽然提高了效率,但也为数据写入带来了安全问题:如果计算机停机,内存缓冲区中的数据会丢失。为此,系统提供了fsyncfdatasync同步函数,可以强制操作系统立刻将缓冲区中的数据写入到硬盘里,从而确保写入数据的安全性。

    AOF重写

    AOF会记录每个Redis命令到AOF文件,随着时间越来越长,AOF文件会变得越来越大。如果不加以控制,会对Redis服务器,甚至对操作系统造成影响,而且AOF文件越大,数据恢复也越慢。

    为了解决AOF文件体积膨胀的问题,Redis提供AOF文件重写功能来对AOF文件进行“瘦身”。Redis通过创建一个新的AOF文件来替换现有的AOF,新旧两个AOF文件保存的数据相同,但新AOF文件没有了冗余命令。

    RDB和AOF对比

    关于RDB和AOF的优缺点,官网上面也给了比较详细的说明redis.io/topics/pers…

    RDB

    优点:

    • RDB快照是一个压缩过的非常紧凑的文件,保存着某个时间点的数据集,适合做数据的备份,灾难恢复;
    • 可以最大化Redis的的性能,在保存RDb文件,服务器进程只需要fork一个子进程来完成RDB文件的创建,父进程不需要做IO操作;
    • 与AOF相比,恢复大数据集的时候会更快;

    缺点:

    • RDB的数据安全性是不如AOF的,保存整个数据集的过程是比繁重的,根据配置可能要几分钟才快照一次,如果服务器宕机,那么就可能丢失几分钟的数据;
    • Redis数据集较大时,fork的子进程要完成快照会比较耗CPU、耗时;

    AOF

    优点:

    • 数据更完整,安全性更高,秒级数据丢失(取决fsync策略,如果是everysec,最多丢失1秒的数据);
    • AOF文件是一个只进行追加的日志文件,且写入操作是以Redis协议的格式保存的,内容是可读的,适合误删紧急恢复;

    缺点:

    • 对于相同的数据集,AOF文件的体积要大于RDB文件,数据恢复也会比较慢;
    • 根据所使用的fsync策略,AOF的速度可能会慢于RDB。 不过在一般情况下,每秒fsync的性能依然非常高;

    RDB和AOF如何选择

    通常来说,应该同时使用两种持久化方案,以保证数据安全。

    • 如果数据不敏感,且可以从其他地方重新生成,可以关闭持久化。
    • 如果数据比较重要,且能够承受几分钟的数据丢失,比如缓存等,只需要使用RDB即可。
    • 如果是用做内存数据,要使用Redis的持久化,建议是RDB和AOF都开启。

    当RDB与AOF两种方式都开启时,Redis会优先使用AOF恢复数据,因为AOF保存的文件比RDB文件更完整。

    参考资料

  • 相关阅读:
    洛谷P3233 世界树
    线性基
    CF321E Ciel and Gondolas
    洛谷P2619 Tree I
    重温一下基本数据类型以及自动提升数据类型的问题
    不可理喻的JSTL标签库
    理解RESTful架构(转)
    Node.js的优点和缺点(转载)
    自制双色球随机号码
    编程, 细心永远都不嫌多(记录java连接数据库的一个错误)
  • 原文地址:https://www.cnblogs.com/liang24/p/13888979.html
Copyright © 2011-2022 走看看