前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Redis持久化 aof和rdb的原理

Redis持久化 aof和rdb的原理

作者头像
ITer.996
发布于 2022-11-22 06:56:03
发布于 2022-11-22 06:56:03
69800
代码可运行
举报
文章被收录于专栏:PHPer技术栈PHPer技术栈
运行总次数:0
代码可运行

一.介绍

由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。

redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时 dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)

本篇为综合整理的文档,若要深入了解可查阅Redis官网文档

二.RDB持久化(全量写入)

rdb原理

RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发

过程:

  • 1)执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,如RDB/AOF子进程,如果存在bgsave命令直接返回。
  • 2)父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看latest_fork_usec选项,可以获取最近一个fork操作的耗时,单位为微秒。
  • 3)父进程fork完成后,bgsave命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。
  • 4)子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换 执行lastsave命令可以获取最后一次生成RDB的时间,对应info统计的rdb_last_save_time选项。
  • 5)进程发送信号给父进程表示完成,父进程更新统计信息,具体见info Persistence下的rdb_*相关选项。

rdb模式

SAVE 阻塞式的RDB持久化,当执行这个命令时间时rdis的主进程把内存里的数据库状态写入到rdb文件中,直到该文件创建完毕的这段时间内redis讲不能处理任何命令请求

BGSAVE 非阻塞式的持久化,它会创建一个子进程,专门去把内存中的数据库状态写入RDB文件,同时主进程还可以处理来自客户端的请求命令,但子进程基本是复制父进程,这等于两个相同大小的redis进程在系统上运行,会造成内存使用率的大幅增加。

rdb触发情况

1.手动执行bgsave或save命令 2.根据配置文件的save选项自动触发 3.主从结构时,从节点执行全量复制操作,主节点自动执行,将生成的RDB文件发送给从 4.执行debug reload命令重新加载Redis时 5.默认情况下执行shutdown命令关闭redis时,如果没有开启AOF持久化功能则自动执行

rdb优势和劣势

优势:

  • 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对可以定时每天可以备份出一个整个的数据文件。
  • 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
  • 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。

劣势:

  • 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。

rdb文件配置

redis.conf文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#注释所有save行则停止rdb持久化

#900秒(15分钟)内至少1个key值改变(则进行数据库保存--持久化)

save 900 1

#300秒(5分钟)内至少10个key值改变(则进行数据库保存--持久化)

save 300 10
#60秒(1分钟)内至少10000个key值改变(则进行数据库保存--持久化)

save 60 10000
#当RDB持久化出现错误后,再写入数据会报错,用于提示用户出问题了。

#yes是开启,no是关闭,默认开启

stop-writes-on-bgsave-error yes
#是否压缩rdb文件,rdb文件压缩使用LZF压缩算法,压缩会消耗一些cpu,不压缩文件会很大

#yes开启,no关闭,默认开启

rdbcompression yes
#使用CRC64算法来进行数据校验,防止RDB是错误的,但是这样做会增加大约10%的性能消耗

#yes开启,no关闭,默认开启

rdbchecksum yes

rdb命令配置

阻塞当前Redis服务器 直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。 save

Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。 bgsave

查看latest_fork_usec选项,可以获取最近一个fork操作的耗时,单位为微秒。 info stats

rdb数据恢复

1.将RDB备份放到配置文件指定的数据目录下,启动redis将会自动恢复。加载期间将会阻塞,无法进行其它操作。

2.上述方法不行,或者恢复的集群,可以使用redis-migrate-tool工具进行恢复。

三.AOF持久化(增量写入)

aof原理

以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

写入的数据具有可读性,同步时先写入缓冲区,再放入硬盘。如果直接写入硬盘,性能将取决于磁盘负载,并且放到缓冲区,可以提供各种同步策略。

过程:

  • 1)所有的写入命令会追加到aof_buf(缓冲区)中。
  • 2)AOF缓冲区根据对应的策略向硬盘做同步操作。
  • 3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
  • 4)当Redis服务器重启时,可以加载AOF文件进行数据恢复

aof触发情况

1.根据配置文件自动触发

aof优势和劣势

优势:

  • 该机制可以带来更高的数据安全性,即数据持久性。根据策略不同,从而对数据安全性不同,可以在性能和安全区选择一个。
  • 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。
  • 如果日志过大,将自动启用rewrite机制。以append模式不断的将修改数据写入到老的磁盘文件中,同时还会创建一个新的文件用于记录此期间有哪些修改命令被执行,保证安全性。
  • AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。

劣势:

  • 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
  • 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。

aof文件配置

在Redis的配置文件中存在三种同步方式,它们分别是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#是否开启aof持久化。默认no,要打开

appendonly yes

#位置

appendfilename "appendonly.aof"

#每次有数据修改发生时都会写入AOF文件

#命令写入aof_buf后调用系统fsync操作同步AOF文件,fsync完成后线程返回

appendfsync always

#每秒钟同步一次,该策略为AOF的缺省策略

#命令写入aof_buf后调用系统write操作,write完成后线程返回。fsync同步文件操作由专门线程每秒调用一次

#这个模式兼顾了效率的同时也保证了数据的完整性,即使在服务器宕机也只会丢失一秒内对redis数据库做的修改

appendfsync everysec

#不加入缓冲区,直接写到硬盘,速度最快,不安全

#命令写入aof_buf后调用系统write操作,不对aof文件做fsync同步,同步硬盘操作由操作系统负责,通常同步周期最长30秒

#这种模式下效率是最快的,但对数据来说也是最不安全的,如果redis里的数据都是从后台数据库如mysql中取出来的,属于随时可以找回或者不重要的数据,那么可以考虑设置成这种模式。

appendfsync no

aof命令配置

aof文件重写手动触发 bgrewriteaof

aof文件重写自动触发,配置文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#新的aof文件大小是上次的aof文件的大小2倍(100)时,进行重写

auto-aof-rewrite-percentage 100

#表示运行AOF重写时文件最小体积, 默认为64MB

auto-aof-rewrite-min-size 64mb

aof数据恢复

  • 将AOF备份放到配置文件指定的数据目录下,启动redis将会自动恢复。加载期间将会阻塞,无法进行其它操作。
  • 上述方法不行,或者恢复的集群,可以使用redis-migrate-tool工具进行恢复。
  • 可以使用pipline方式批量硬写入,但效率会低

四.总结

二者选择的标准,就是看系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。

启动加载流程:

  • AOF持久化开启且存在AOF文件时, 优先加载AOF文件
  • AOF关闭或者AOF文件不存在时, 加载RDB文件
  • 加载AOF/RDB文件成功后, Redis启动成功
  • AOF/RDB文件存在错误时, Redis启动失败并打印错误信息
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-07-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PHPer技术栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android权限机制,你真的了解吗?
一、Android的权限机制 Android是目前最流行的智能手机软件平台之一,在智能移动终端如火如荼发展的同时,其安全态势也日益严峻。有调查表明,恶意软件的数量在持续的上升,Google在Android安全机制上面也做了很多工作,并且一直在持续的更新,其Android的安全模型由3个部分组成:Linux安全机制、Android本地库及运行环境安全与Android特有的安全机制,如下图: 本文只涉及到其中的权限机制介绍,其他的部分如果有感兴趣的,我们可以后续一起探讨。 Android的权限管理遵循的是
腾讯移动品质中心TMQ
2018/02/05
6.6K0
Android权限机制,你真的了解吗?
Android权限管理PermissionsDispatcher2.3.2使用+原生6.0权限使用
PermissionsDispatcher2.3.2使用 Android6.0权限官网 https://developer.android.com/about/versions/marshmallo
庞小明
2018/03/07
1.6K0
Android权限管理PermissionsDispatcher2.3.2使用+原生6.0权限使用
聊一聊Android 6.0的运行时权限
Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注。因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变。
技术小黑屋
2018/09/05
1.1K0
聊一聊Android 6.0的运行时权限
PermissionX 1.7发布,全面支持Android 13运行时权限
还记得上次发布PermissionX 1.6版本还是在去年10月份的时候,当时是对Android 12系统进行了支持。详情可以参考这篇文章 PermissionX 1.6发布,支持Android 12,可能是今年最大的版本升级 。
用户1158055
2022/11/07
3.6K0
PermissionX 1.7发布,全面支持Android 13运行时权限
Android6.0运行时权限处理
ContextCompat.checkSelfPermission:用于检测某个权限是否已经被授予
用户1205080
2018/12/17
1.1K0
跨程序共享数据——Content Provider 之 运行时权限解析以及申请的实现(可完美解决java.lang.SecurityException:Permission Denial 问题)
本模块共有四篇文章,参考郭神的《第一行代码》,对Content Provider的学习做一个详细的笔记,大家可以一起交流一下:
凌川江雪
2018/09/13
13.1K2
跨程序共享数据——Content Provider 之 运行时权限解析以及申请的实现(可完美解决java.lang.SecurityException:Permission Denial  问题)
Android 6.0 运行时权限处理问题
序 自从升级到Android M以来,最大的改变就是增加了运行时权限RuntimePermission,6.0以上的系统如果没有做适配,运行了targetSDK=23的App时就会报权限错误。我们知道6.0以下的系统是按照的时候权限申请的,6.0和之后的版本是我们想要使用某个app的权限,去动态申请的,这也是基于安全上的考虑吧(比如:单机的象棋对战,请求访问通讯录权限等不合理的权限,这肯定是有问题的)。 为了保护用户的隐私,谷歌官方将权限分为了两类,一个是正常权限(Normal Permissions),这
xiangzhihong
2018/02/05
1.1K0
Android 6.0 运行时权限处理问题
因为Android M权限问题导致的"Permission Denial: reading com.android.providers.media.MediaProvider"解决办法
最后查明是因为API过高权限访问有修改, 在API级别>=23时, 权限访问被分为三个级别, 分别为”PROTECTION_NORMAL, PROTECTION_DANGEROUS, 和PROTECTION_SIGNATURE(还有两个标志可以和SIGNATURE联合使用才有意义)”. PROTECTION_NORMAL是普通权限, 通过manifest文件在安装时被授予. PROTECTION_SIGNATURE是签名权限, 通过”检查manifest和app签名是否匹配app中声明的权限”在安装时授予. 对于 PROTECTION_DANGEROUS, 不仅需要在manifest中声明, 还需要在运行时通过requestPermissions获得, 也就是弹出来一个个对话框, 让用户确认是否授予app这些权限. 这些是常见PROTECTION_DANGEROUS权限, 如果你在程序中使用了, 那么在API>=23, 很可能会不正常工作. ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION ADD_VOICEMAIL BODY_SENSORS CALL_PHONE CAMERA GET_ACCOUNTS PROCESS_OUTGOING_CALLS READ_CALENDAR READ_CALL_LOG READ_CELL_BROADCASTS READ_CONTACTS READ_EXTERNAL_STORAGE READ_PHONE_STATE READ_SMS RECEIVE_MMS RECEIVE_SMS RECEIVE_WAP_PUSH RECORD_AUDIO SEND_SMS USE_SIP WRITE_CALENDAR WRITE_CALL_LOG WRITE_CONTACTS WRITE_EXTERNAL_STORAGE
望天
2018/08/02
2.7K0
一个类快速实现 Android 6.0 运行时权限适配
现在来谈 Android 6.0 运行时权限适配,可以说是很过时了,可是为什么还要写呢? 一是试用了目前 GitHub 上排名比较靠前的开源项目,确实都很棒,但是在易用性还是难以令人满意,便萌生了自己撸一个的想法。 二是看了下目前国内主流的应用,发现很多都还没有适配 Android 6.0 ,因此觉得这篇文章还有它的意义。
全栈程序员站长
2021/06/22
2790
React Native之Permissions权限适配
做过Android开发的同学都知道,在Android6.0版本之后,系统新增了运行时权限RuntimePermission,这个或许是借鉴的苹果吧(ps,关于详细的介绍请查看: Android 6.0 运行时权限适配)。那么,在RN开发中,怎么适配Android6.0以上版本呢?其实,RN为Android同学提供了PermissionsAndroid模块,用来访问Android M(也就是6.0)权限模型。 对于Android 6.0以上版本来说,系统将权限分为普通权限、敏感权限和危险权限。有一些普通权
xiangzhihong
2018/02/06
2.1K0
6.0 运行时权限处理
6.0 运行时权限处理 在6.0以前 权限都是在安装时授权的,如果用户不授权就无法安装; Android从6.0(API 23)开始 使用运行时权限,而不是像以前那样安装时授权。当你需要某些权限时,系统会向用户去申请权限。用户可以随时取消授权给你的权限。 6.0中权限分为两类 普通权限和危险权限,普通权限在AndroidManifest 文件中注册就可以得到,对于能获得用户隐私的权限属于危险权限。在使用的时候必须用户授权才能使用。例如 拍照,录音 sd卡的操作,危险权限被分为很多组,只要一组中的其中一项被授
佛系编码
2018/05/22
7520
PermissionX 1.5发布,支持申请Android特殊权限啦
Hello大家早上好,说起PermissionX,其实我已经有段时间没有更新这个框架了。一是因为现在工作确实比较忙,没有过去那么多的闲暇时间来写开源项目,二是因为,PermissionX的主体功能已经相当稳定,并不需要频繁对其进行变更。
用户1158055
2021/07/29
1.1K0
PermissionX 1.5发布,支持申请Android特殊权限啦
Android6.0动态权限适配&XMPermissions
从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限。它还让用户可以对应用的功能进行更多控制;例如,用户可以选择为相机应用提供相机访问权限,而不提供设备位置的访问权限。用户可以随时进入应用的“Settings”屏幕调用权限。摘自Android官网:在运行时请求权限。
静默加载
2020/05/29
1.3K0
Android EasyPermission优雅地实现动态权限申请
Google开源的动态权限适配库,用起来比较简洁和清晰,总体还不错,如果喜欢链式调用的就用 RxPermission 或者 AndPermission 都是不错的选择。
程序员飞飞
2020/02/27
2.2K0
Android开发笔记(一百五十八)运行时动态授权管理
App开发过程中,涉及到硬件设备的操作,比如拍照、录音、定位等等,都要在AndroidManifest.xml中声明相关的权限。可是Android系统为了防止某些App滥用权限,从而允许用户在系统设置里面对App禁用某些权限。然而这又带来另一个问题,用户打开App之后,App可能因为权限不足导致无法正常运行,甚至直接崩溃闪退。遇到这种情况,只需用户在系统设置中开启相关权限即可恢复正常,但是用户并非专业的开发者,他怎知要去启用哪些权限呢?再说,每次都要用户亲自打开系统设置页面,再琢磨半天精挑细选那些必须开启的权限,不但劳力而且劳神,这种用户体验实在差劲。 有鉴于此,Android从6.0开始引入了运行时权限管理机制,允许App在运行过程中动态检查是否拥有某项权限,一旦发现缺少某种必需的权限,则系统会自动弹出小窗提示用户去开启该权限。如此这般,一方面开发者无需担心App因权限不足而闪退的问题,另一方面用户也不再头痛是哪个权限被禁止导致App用不了的毛病,这个贴心的动态权限授权功能可谓是皆大欢喜。下面就来看看如何在代码中实现运行时权限管理机制。 首先要检查Android系统是否为6.0及以上版本,因为运行时权限管理机制是6.0才开始支持的功能。其次调用ContextCompat.checkSelfPermission方法,检查检查当前App是否开启了指定的权限。倘若检查结果是尚未开启权限,则再调用ActivityCompat.requestPermissions方法,请求系统弹出开启权限的确认对话框。详细的权限校验代码如下所示:
aqi00
2019/01/18
1.2K0
Android运行时权限终极方案,用PermissionX吧
有些朋友的阅读速度真是令人印象深刻,我记得在《第三行代码》刚刚发售一周不到的时间里,竟然就有人已经读到第9章了(因为公众号后台有人回复第9章里隐藏的关键字)。现在,《第三行代码》已经出版一个月有余了,相信已经有不少朋友将全本书都看完了。
用户1158055
2020/05/27
1.2K0
Android运行时权限终极方案,用PermissionX吧
android:运行时权限工具类的封装
众所周知,Android 从 6.0开始引入运行时权限机制,将权限分为了普通权限和危险权限 ,对于危险权限我们必须在使用的时候动态的去申请。
CnPeng
2020/08/11
1.5K0
Android 6.0运行时权限理解
<protectionLevel>属性是必须的,告诉系统当app申请该权限的时候,要怎样通知用户。
用户3004328
2018/09/06
8150
Android 6.0运行时权限理解
【Android从零单排系列四十四】《聊一下Android数据权限permission》
小伙伴们,在前面的几篇文章中,我们谈到了Android开发中的几种数据存储方式及数据持久化,本文我们介绍下Android开发中的另一部分内容,权限管理。
再见孙悟空_
2023/07/17
1.1K0
TI--安卓运行时权限完美封装
零、前言: [1]两行代码解决运行时权限 [2]用户拒绝后显示提示信息,有再次验证功能 [3]验证成功回调 一个权限效果: 一个权限效果.gif 六个权限演示: 六个权限演示.gif 一、代
张风捷特烈
2018/09/26
8460
推荐阅读
相关推荐
Android权限机制,你真的了解吗?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档