首页 > 数据库 >redis设计与实现(五)RDB与AOF持久化

redis设计与实现(五)RDB与AOF持久化

时间:2024-06-15 14:58:57浏览次数:14  
标签:AOF 文件 数据库 redis RDB 服务器 重写

RDB持久化

因为Redis是内存数据库,它将自己的数据库状态储存在内存里面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。

为了解决这个问题,Redis提供了RDB持久化功能,这个功能可以将Redis在内存中的数据库状态保存到磁盘里面,避免数据意外丢失。

RDB持久化功能所生成的RDB文件是一个经过压缩的二进制文件,通过该文件可以还原生成RDB文件时的数据库状态 RDB文件是保存在硬盘里的

  • 如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状态。

  • 只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。

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

和SAVE命令直接阻塞服务器进程的做法不同,BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求

服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成为止。

RDB文件结构

每个非空数据库在RDB文件中都可以保存为SELECTDB、db_number、key_value_pairs三个部分

  • SELECTDB常量的长度为1字节,当读入程序遇到这个值的时候,它知道接下来要读入的将是一个数据库号码。
  • db_number保存着一个数据库号码,根据号码的大小不同,这个部分的长度可以是1字节、2字节或者5字节。当程序读入db_number部分之后,服务器会调用SELECT命令,根据读入的数据库号码进行数据库切换,使得之后读入的键值对可以载入到正确的数据库中。
  • key_value_pairs部分保存了数据库中的所有键值对数据,如果键值对带有过期时间,那么过期时间也会和键值对保存在一起。根据键值对的数量、类型、内容以及是否有过期时间等条件的不同,key_value_pairs部分的长度也会有所不同。
  • RDB文件中的每个key_value_pairs部分都保存了一个或以上数量的键值对,如果键值对带有过期时间的话,那么键值对的过期时间也会被保存在内。不带过期时间的键值对在RDB文件中由TYPE、key、value三部分组成。

AOF持久化

与RDB持久化通过保存数据库中的键值对来记录数据库状态不同,AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态的。

在这里插入图片描述

AOF持久化的实现:

AOF持久化功能的实现可以分为命令追加(append)、文件写入、文件同步(sync)三个步骤。

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

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

但是若计算机发生停机,那么保存在内存缓冲区里面的写入数据将会丢失。

为此,系统提供了fsyncfdatasync两个同步函数,它们可以强制让操作系统立即将缓冲区中的数据写入到硬盘里面,从而确保写入数据的安全性

因为AOF文件里面包含了重建数据库状态所需的所有写命令,所以服务器只要读入并重新执行一遍AOF文件里面保存的写命令,就可以还原服务器关闭之前的数据库状态。

AOF重写:

因为AOF持久化是通过保存被执行的写命令来记录数据库状态的,AOF文件中的内容会越来越多,体积过大的AOF文件很可能对Redis服务器、甚至整个宿主计算机造成影响,并且AOF文件的体积越大,使用AOF文件来进行数据还原所需的时间就越多。

为此Redis提供了AOF文件重写功能,Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新AOF文件不会包含任何浪费空间的冗余命令,所以新AOF文件的体积通常会比旧AOF文件的体积要小得多。

但实际上,AOF文件重写并不需要对现有的AOF文件进行任何读取、分析或者写入操作,而是通过读取服务器当前的数据库状态来实现的。

首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这就是AOF重写功能的实现原理。

在实际中,为了避免在执行命令时造成客户端输入缓冲区溢出,重写程序在处理列表、哈希表、集合、有序集合这四种可能会带有多个元素的键时,会先检查键所包含的元素数量,如果元素的数量超过了redis.h/REDIS_AOF_REWRITE_ITEMS_PER_CMD常量的值,那么重写程序将使用多条命令来记录键的值,而不单单使用一条命令。

作为一种辅佐性的维护手段,Redis不希望AOF重写造成服务器无法处理请求,所以Redis决定将AOF重写程序放到子进程里执行,这样做可以同时达到两个目的:

  • 子进程进行AOF重写期间,服务器进程(父进程)可以继续处理命令请求。

  • 子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。

不过,使用子进程也有一个问题需要解决,因为子进程在进行AOF重写期间,服务器进程还需要继续处理命令请求,而新的命令可能会对现有的数据库状态进行修改,从而使得服务器当前的数据库状态和重写后的AOF文件所保存的数据库状态不一致。

为了解决这种数据不一致问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行完一个写命令之后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区

当子进程完成AOF重写工作之后,它会向父进程发送一个信号,父进程在接到该信号之后,会调用一个信号处理函数,并执行以下工作:

  • 将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新AOF文件所保存的数据库状态将和服务器当前的数据库状态一致。

  • 对新的AOF文件进行改名,原子地(atomic)覆盖现有的AOF文件,完成新旧两个AOF文件的替换。

在整个AOF后台重写过程中,只有信号处理函数执行时会对服务器进程(父进程)造成阻塞,在其他时候,AOF后台重写都不会阻塞父进程,这将AOF重写对服务器性能造成的影响降到了最低。

标签:AOF,文件,数据库,redis,RDB,服务器,重写
From: https://blog.csdn.net/m0_74973115/article/details/139702605

相关文章

  • Redis
    Redis概念Redis的安装Redis命令入门Java操作RedisRedis的持久化配置Redis的淘汰策略一.Redis概念1.NOSQL1.1.什么是NOSQLNoSQL(NoSQL=NotOnlySQL),意即“不仅仅是SQL”,它泛指非关系型的数据库。关系型数据库:以关系(由行和列组成的二维表)模型建模的数据库。简单理......
  • 【redis】互斥锁
    1.创建一个Go程序来实现基于Redis的互斥锁。这个程序将尝试获取一个锁,成功后对文件进行操作,并且在完成操作后释放锁packagemainimport("context""fmt""github.com/go-redis/redis/v8""os""time")varctx=context.Background()funcma......
  • Docker的通俗理解和通过宿主机端口访问Redis容器的实例
    前言本文解决的问题:入门docker理解镜像与容器、宿主机的概念理解Docker的常用指令创建redis容器,并通过宿主机端口访问默认读者的知识背景:使用过git初次使用Docker本文不会对Docker的定义作出解释,不会涉及Docker的实现原理,旨在帮助读者快速入门docker,理解......
  • 一篇文章看懂Redission原理
    文章目录☃️可重入锁原理☃️锁重试和WatchDog机制☃️MutiLock原理上一篇文章讲解了Rediision的使用,这篇文章讲解其原理☃️可重入锁原理在Lock锁中,他是借助于底层的一个voaltile的一个state变量来记录重入的状态的,比如当前没有人持有这把锁,那么state=0,假如有人......
  • RDB和AOF两种持久化机制的介绍
    RDB持久化机制,对redis中的数据执行周期性的持久化AOF机制对每条写入命令作为日志,以append-only的模式写入一个日志文件中,在redis重启的时候,可以通过回放AOF日志中的写入指令来重新构建整个数据集如果我们想要redis仅仅作为纯内存的缓存来用,那么可以禁止RDB和AOF所有的持久化机制......
  • Redis之线程IO模型
    引言Redis是个单线程程序!这点必须铭记。除了Redis之外,Node.js也是单线程,Nginx也是单线程,但是他们都是服务器高性能的典范。Redis单线程为什么能够这么快!因为他所有的数据都在内存中,所有的运算都是内存级别的运算。正因为Redis是单线程,所以要小心使用Redis指令,对于那些时......
  • Java面试:Redis如何保证数据一致性?
    Redis是一个内存数据结构存储系统,广泛用于缓存、会话管理等场景。尽管Redis本身不是传统的关系型数据库,它仍然提供了一些机制来保证数据一致性。以下是Redis保证数据一致性的一些方法和机制:1.事务机制(Transactions)Redis支持事务,通过MULTI、EXEC、DISCARD、WATCH等命令实......
  • 【2024最新精简版】Redis面试篇
    文章目录什么是红锁Redis有哪些框架?你们项目中哪里用到了Redis?Redis的常用数据类型有哪些?Redis的数据持久化策略有哪些?Redis的数据过期策略有哪些?Redis的数据淘汰策略有哪些?你们使用Redis是单点还是集群?哪种集群?Redis集群有哪些方案,知道嘛?什么是Red......
  • redis自学(47)批处理优化
    大量数据的导入的方式    Redis提供的批处理方案   M操作比Pipeline快,因为M操作是内部操作,原子操作,而Pipeline不是。  集群下的批处理如MSET或Pipeline这样的批处理需要在一次请求中携带多条命令,而此时如果redis是一个集群,那批处理命令的多个key必须......
  • Redis的两种持久化RDB和AOF
    目录一、简介二、RDB详解三、AOF详解​四、RDB与AOF对比一、简介什么是持久化?利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化。说白了Redis是基于内存的,快是快,但一关机数据就没了,这样肯定不行啊,所以就要把数据都存在磁盘上,这......