热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

图解redis的持久化存储机制RDB和AOF的原理和优缺点

本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了图解redis的持久化存储机制 RDB和AOF相关的知识,希望对你有一定的参考价值。



redis的持久化存储策略

redis是一个高性能的缓存数据库,既然是缓存,它的数据就是存储在内存中的,如果说服务器断电了, 或者重启了,或者redis宕机了,他的数据就一定会丢失,所以为了解决这个问题,在丢失数据之前就将数据给持久化保存到磁盘,这种持久化技术,就是RDB和AOF


什么是RDB

redis Database 的简写,是将redis内存中的数据保存为一个快照文件,类似Jmap的dump堆转储功能,但rdb是时点性的,只能存储某一时刻的快照,不能实时存储,如果单单使用rdb,它的数据就一定会丢失;


RDB优点


  1. 以快照的方式存储,所以恢复速度相对较快,
  2. 不支持拉链式的快照,也就是说,生成的快照文件永远只有一个;

RDB缺点


  1. 因为是时点性的,在持久化时将数据保存到磁盘需要一定的时间,在这段时间内可能会有其他的写操作,所以容易丢失数据

持久化触发方式

RDB的持久化触发方式有2种,分别为手动触发和自动触发,手动触发只需要登陆redis后输入相应的命令即刻,自动触发需要配置持久化的规则;


1、手动触发RDB

手动触发RDB持久化方式的命令有2种,分别是阻塞和异步:


  • save:执行save命令后redis进入阻塞状态,在RDB生成快照期间,redis不能执行其他命令,直到RDB完成方可解除阻塞状态;
  • bgsave:执行bgsave命令后,redis会以异步的方式进行持久化操作,以fork的方式创建一个子进程(注意是进程,不是线程);RDB持久化操作由子进程负责,完成后自动结束子进程;在异步持久化期间,redis可以正常执行命令;不会有任何影响;阻塞只发生在fork阶段,一般时间很短

注意事项


  1. 在命令行登录redis后输入save或者bgsave即可持久化存储;
  2. 基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。
  3. 执行执行 flushall 命令,也会产生dump.rdb快照文件,但里面是空的.

2、自动触发RDB

先进入redis目录,打开redis.conf配置文件,找到以下几项配置:


  • rdbcompression yes :默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。
  • rdbchecksum yes:默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
  • dbfilename dump.rdb: 设置快照的文件名,默认是 dump.rdb
  • dir /usr/local/redis/rdb: 设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。默认是和当前配置文件保存在同一目录。

自动触发RDB的持久化条件


  • save "" :如果不想要使用RDB,可以使用此配置关闭 RDB功能
  • save 900 1: 900 秒内如果至少有 1 个 key 的值变化,则进行持久化保存
  • save 300 10: 300 秒内如果至少有 10 个 key 的值变化,则进行持久化保存
  • save 60 10000:60 秒内如果至少有 10000 个 key 的值变化,则进行持久化保存

bgsave底层原理

前置知识 - linux的fork函数、copy on write(流程图)

在了解异步RDB原理之前,我们需要先了解fork是个什么玩意;

调用fork函数后,linux会创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。

一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

在克隆时,需要满足2个条件,


  1. 速度要快
  2. 占用内存空间要小

为了满足以上2点要求,linux使用了copy on write机制(写入时复制),也就是说,虽然是克隆了2一个子进程出来,但是父子进程种变量的内存指针还是指向同一个内存空间,比如一开始都父子进程的变量A的值都是123,但我修改子进程变量A的值时,改为456,那么操作系统会先在内存写入新的值456,然后在将子进程的变量A指向新的内存值456;

克隆后的进程为子进程,常规情况下,子进程和主进程之间的数据完全隔离;互不影响;子进程的修改不会破坏父进程,父进程的修改也不会破坏子进程;

bgsave原理(流程图)

在输入bgsave命令后,redis在内部做了以下几件事


  1. 通过fork函数创建一个子进程;此方法会产生阻塞,但时间很短;
  2. redis的增删改查由父进程负责;
  3. 持久化RDB由子进程负责;
  4. 持久化完成后,子进程自动结束;

AOF

append only file的简写,意思是只会向文件追加,指的是客户端对redis的增、删、改操作,会以追加的形式将操作语句保存到文件中;


AOF优点


  1. 恢复时丢失数据少
  2. RDB和AOF可同时开启;在4.0以前恢复时只用aof恢复;4.0以后使用混合型的持久化机制,下文会介绍

AOF缺点


  1. 速度较慢,每次写操作都会写磁盘;

rewrite机制(重写)


为什么需要rewrite

我们都知道磁盘空间是有限的,但是redis的增删改的命令却是无穷无尽的,为了保证磁盘不被占满,就需要引入rewrite机制;在命令行输入以下指令即可触发rewrite重写AOF文件;

BGREWRITEAOF

rewrite原理

rewrite机制是自动触发的,需要设定一个阈值,也就是你的aof文件大小的阈值,比如我设置大小为64M时,当aof文件大小达到64M就会自动触发rewrite机制,会对aod文件做些优化,去掉一些过程重复的命令;比如我连续执行了下面的命令

set name yexindong
set name zhangsan
set name lisi

那其实,name最终的结果是lisi,也就是第三个命令,第一个和第二个执不执行都不会影响最终的结果,所以当aof文件叨叨64M时,rewrite原理触发,就会将下面的语句删除

set name yexindong
set name zhangsan

最后只保留set name lisi的语句;去掉中间没用的语句,优化就完成了;经过这一次瘦身,aof文件就会变得更小了;


AOF使用

同样的,AOF也需要在配置文件中进行相关配置;


  • appendonly no: 默认值为no,也就是说redis 默认使用的是rdb方式持久化,如果想要开启 AOF 持久化方式,需要将 appendonly 修改为 yes。

  • appendfilename "appendonly.aof":AOF文件名称,配置后,就会将写指令追加到这个文件内

  • dir /usr/local/redis/rdb: AOF文件的保存目录,与RDB一致

  • appendfsync:aof持久化策略的配置;


    • no:表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快,但是不太安全;
    • always:表示每次写入都执行fsync,以保证数据同步到磁盘,效率很低;
    • everysec:(默认的)表示每秒执行一次fsync,可能会导致丢失这1s数据。通常选择 everysec ,兼顾安全性和效率。
  • no-appendfsync-on-rewrite:在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。 设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据。默认值为no。

  • auto-aof-rewrite-percentage:默认值为100。这个值是个百分比的数值,aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写(rewrite)。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写(rewrite)过程。

  • auto-aof-rewrite-min-size:64mb。设置允许重写(rewrite)的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写(rewrite)。

  • aof-load-truncated:aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项,出现这种现象 redis宕机或者异常终止不会造成尾部不完整现象,可以选择让redis退出,或者导入尽可能多的数据。如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以。默认值为 yes。


aof使用注意事项

要使用AOF功能,在启动时不能直接运行redis-server。一定要加配置文件运行./redis-server /etc/redis/redis.conf,加了配置文件后AOF功能才会生效


AOF文件内容说明

首先我们执行下面这个命令,看看aof文件中都保存了哪些东西;

set k1 hello

然后通过命令打开aof文件 vim appendonly.aof,可以看到以下内容

*2 // *开头表示是一个新命令,这个命令有2个元素组成
$6 // $开头表示下一行命令的字符长度
SELECT // 选择库的指令,redis有16个库:0~15之间
$1
0 // 和上面的命令组成为:SELECT 0,表示选择0号库
*3 // 下一个命令,这个命令有3个元素组成
$3 // 下一行的命令长度
set // set命令
$2
k1 // key 的名称
$5
hello // key的值,和上面2个命令组成:set k1 hello

Redis是如何进行持久化的(流程图)

在reids4.0的以后,提供了一种混合型的持久化机制,就是RDB + AOF的持久化方式;在配置文件中会有以下配置,设置为yes表示开启,设置为no表示禁用。默认为yes

aof-use-rdb-preamble yes

当开启混合持久化时,主进程先fork出子进程将现有内存副本全量以RDB方式写入aof文件中,然后将缓冲区中的增量命令以AOF方式写入aof文件中,写入完成后通知主进程更新相关信息,并将新的含有 RDB和AOF两种格式的aof文件替换旧的aof文件。

也就是说,RDB 和 AOF文件是在同一个文件里面的,在进行备份的时候,比如是2点整进行备份的,先将这个文件先删除掉,然后将当前的数据以RDB快照的方式保存到aof文件种,最后,以增量的方式将增、删、改命令追加到AOF文件中;这样就可以保证重启或者断电后,恢复数据会保持和断电前一致了;

简单来说:混合持久化方式产生的文件一部分是RDB格式,一部分是AOF格式。

这种方式优点我们很好理解,缺点就是不能兼容Redis4.0之前版本的备份文件了。


数据恢复

启动redis时,redis会自动加载rbd文件和 aof文件进行数据恢复;前提是得先开启相应的配置后才会恢复数据,配置如下

# 开启 AOF 持久化配置
appendonly yes

# 开启 RDB持久化配置
rdbcompression yes

推荐阅读
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 本文介绍了Redis中RDB文件和AOF文件的保存和还原机制。RDB文件用于保存和还原Redis服务器所有数据库中的键值对数据,SAVE命令和BGSAVE命令分别用于阻塞服务器和由子进程执行保存操作。同时执行SAVE命令和BGSAVE命令,以及同时执行两个BGSAVE命令都会产生竞争条件。服务器会保存所有用save选项设置的保存条件,当满足任意一个保存条件时,服务器会自动执行BGSAVE命令。此外,还介绍了RDB文件和AOF文件在操作方面的冲突以及同时执行大量磁盘写入操作的不良影响。 ... [详细]
author-avatar
mobiledu2502912043
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有