《面试官之你说我听》:简明的图解Redis RDB持久化、AOF持久化
欢迎关注文章这一系列,一起学习
《提升能力,涨薪可待篇》
《面试知识,工作可待篇》
《实战演练,拒绝996篇》
如果此文对你有帮助、喜欢的话,那就点个赞呗,点个关注呗!
1.持久化
1.1 持久化简介
持久化(Persistence),持久化是将程序数据在持久状态和瞬时状态间转换的机制,即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。
1.2 redis持久化
redis为内存数据库,为了防止服务器宕机以及服务器进程退出后,服务器数据丢失,Redis提供了持久化功能,即将Redis中内存数据持久化到磁盘中。Redis 提供了不同级别的持久化方式:
RDB持久化方式:可以在指定的时间间隔能对数据进行快照存储.
AOF持久化方式:记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.
如果服务器开启了AOF持久化功能。服务器会优先使用AOF文件还原数据。只有关闭了AOF持久化功能,服务器才会使用RDB文件还原数据
2. RDB持久化
2.1 RDB文件格式
RDB文件是一个经过压缩的二进制文件(默认的文件名:dump.rdb),由多个部分组成,RDB格式:
2.2 RDB文件持久化创建与载入
在 Redis持久化时, RDB 程序将当前内存中的数据库状态保存到磁盘文件中, 在 Redis 重启动时, RDB 程序可以通过载入 RDB 文件来还原数据库的状态。
2.3 工作方式
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:
Redis 调用forks。同时拥有父进程和子进程。
子进程将数据集写入到一个临时 RDB 文件中。
当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。
2.4 创建方式
SAVE
同步操作,在执行该命令时,服务器会被阻塞,拒绝客户端发送的命令请求
redis> save
BGSAVE
异步操作,在执行该命令时,子进程执行保存工作,服务器还可以继续让主线程处理客户端发送的命令请求
redis>bgsave
自动创建
由于BGSAVE命令可不阻塞服务器进程下执行,可以让用户自定义save属性,让服务器每个一段时间自动执行一次BGSAVE命令(即通过配置文件对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动进行数据集保存操作)。
比如:
/*服务器在900秒之内,对数据库进行了至少1次修改*/
Save 900 1
/*服务器在300秒之内,对数据库进行了至少10次修改*/
Save 300 10
/*服务器在60秒之内,对数据库进行了至少10000次修改*/
Save 60 10000
只要满足其中一个条件就会执行BGSAVE命令
2.5 RDB 默认配置
################################ SNAPSHOTTING ################################
#
# Save the DB on disk:
#在给定的秒数和给定的对数据库的写操作数下,自动持久化操作。
# save <seconds> <changes>
#
save 900 1
save 300 10
save 60 10000
#bgsave发生错误时是否停止写入,一般为yes
stop-writes-on-bgsave-error yes
#持久化时是否使用LZF压缩字符串对象?
rdbcompression yes
#是否对rdb文件进行校验和检验,通常为yes
rdbchecksum yes
# RDB持久化文件名
dbfilename dump.rdb
#持久化文件存储目录
dir ./
3. AOF持久化
3.1 AOF持久化简介
AOF持久化是通过保存Redis服务器所执行的写命令来记录数据库状态
AOF持久化功能实现:
append命令追加:当AOF持久化功能处于打开状态时,服务器执行完一个写命令会协议格式被执行的命令追加服务器状态的aof_buf缓冲区的末尾。
reids>SET KET VAULE //协议格式 \r\n$3\r\nSET\r\n$3\r\nKEY\r\n$5\r\nVAULE\r\n
文件写入和同步sync:Redis的服务器进程是一个事件循环,这个文件事件负责接收客户端的命令请求以及向客户端发送命令回复。当执行了append命令追加后,服务器会调用flushAppendOnlyFile函数是否需要将AOF缓冲区的内容写入和保存到AOF文件
redis> SET msg "Ccww"
redis> SADD persistence "rdb" "aof"
redis> RPUSH size 128 256 512
3.2 AOF持久化策略
AOF持久化策略(即缓冲区内容写入和同步sync到AOF中),可以通过配置appendfsync属性来选择AOF持久化策略:
always:将aof_buf缓冲区中的所有内容写入并同步到AOF文件,每次有新命令追加到 AOF 文件时就执行一次 fsync。
everysec(默认):如果上次同步AOF的时间距离现在超过一秒,先将aof_buf缓冲区中的所有内容写入到AOF文件,再次对AOF文件进行同步,且同步操作由一个专门线程负责执行。
no:将aof_buf缓冲区中的所有内容写入到AOF文件,但并不对AOF文件进行同步,何时同步由操作系统(OS)决定。
AOF持久化策略的效率与安全性:
Always:效率最慢的,但安全性是最安全的,即使出现故障宕机,持久化也只会丢失一个事件 循环的命令数据
everysec:兼顾速度和安全性,出现宕机也只是丢失一秒钟的命令数据
No:写入最快,但综合起来单次同步是时间是最长的,且出现宕机时会丢失上传同步AOF文件之后的所有命令数据。
3.3 AOF重写
由于AOF持久化会把执行的写命令追加到AOF文件中,所以随着时间写入命令会不断增加, AOF文件的体积也会变得越来越大。AOF文件体积大对Reids服务器,甚至宿主服务器造成影响。
为了解决AOF文件体积膨胀的问题,Redis提供了AOF文件重写(rewrite)功能:
生成一个不保存任何浪费空间的冗余命令新的AOF文件,且新旧AOF文件保存数据库状态一样的
新的AOF文件是通过读取数据库中的键值对来实现的,程序无须对现有的AOF文件进行读入,分析,或者写入操作。
为防止缓冲区溢出,重写处理list,hash,set以及Zset时,超过设置常量数量时会多条相同命令记录一个集合。
Redis 2.4 可以通过配置自动触发 AOF 重写,触发参数
auto-aof-rewrite-percentage
(触发AOF文件执行重写的增长率) 以及auto-aof-rewrite-min-size
(触发AOF文件执行重写的最小尺寸)
AOF重写的作用:
减少磁盘占用量
加速数据恢复
Redis服务器使用单个线程来处理命令请求,服务器大量调用aof_rewrite函数,在AOF重写期间,则无法处理client发来的命令请求,所以AOF重写程序放在子进程执行,好处:
子进程进行AOF重写期间,服务器进程可以继续处理命令请求
子进程带有服务器进程的数据副本,保证了数据的安全性。
AOF重写使用子进程会造成数据库与重写后的AOF保存的数据不一致,为了解决这种数据不一致,redis使用了AOF重写缓冲区 实现:
BGREWRITEAOF命令实现原理(只有信号处理函数执行时才对服务器进程造成阻塞):
执行命令,同时将命令追加到AOF缓冲区和AOF重写缓冲区
当AOF子进程重写完成后,发送一个信号给父进程,父进程将执行AOF重写缓冲区中的所有内容写入到新AOF文件中,新AOF文件保存的数据库状态将和服务器当前的数据库状态一致。
对新的AOF文件进行改名,原子性地覆盖现有AOF文件,完成新旧两个AOF文件替换处理完成。
3.4 AOF持久化默认参数
############################## APPEND ONLY MODE ###############################
#开启AOF持久化方式
appendonly no
#AOF持久化文件名
appendfilename "appendonly.aof"
#每秒把缓冲区的数据fsync到磁盘
appendfsync everysec
# appendfsync no
#是否在执行重写时不同步数据到AOF文件
no-appendfsync-on-rewrite no
# 触发AOF文件执行重写的增长率
auto-aof-rewrite-percentage 100
#触发AOF文件执行重写的最小size
auto-aof-rewrite-min-size 64mb
#redis在恢复时,会忽略最后一条可能存在问题的指令
aof-load-truncated yes
#是否打开混合开关
aof-use-rdb-preamble yes
4 持久化方式总结与抉择
4.1 RDB优缺点
RDB的优点
RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集.
基于RDB文件紧凑性,便于复制数据到一个远端数据中心,非常适用于灾难恢复.
RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.
与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.
RDB的缺点
如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你.虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据.
RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度.
4.2 AOF的优缺点
AOF的优点:
使用AOF 会让你的Redis更加耐久:使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.
AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也可使用redis-check-aof工具修复问题.
Redis可以在AOF文件体积变得过大时,自动对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单(例如, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态)。
AOF 缺点:
对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
4.3 如何选择使用哪种持久化方式?
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。
也欢迎关注公众号【Ccww笔记】,原创技术文章第一时间推出
如果此文对你有帮助、喜欢的话,那就点个赞呗,点个关注呗!
《面试官之你说我听》:简明的图解Redis RDB持久化、AOF持久化的更多相关文章
- 面试官问我JVM内存结构,我真的是
面试官:今天来聊聊JVM的内存结构吧? 候选者:嗯,好的 候选者:前几次面试的时候也提到了:class文件会被类加载器装载至JVM中,并且JVM会负责程序「运行时」的「内存管理」 候选者:而JVM的内 ...
- 面试官:RabbitMQ有哪些工作模式?
哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 今天又.又.又来面试了,还是老规 ...
- 吊打面试官系列:Redis 性能优化的 13 条军规大全
1.缩短键值对的存储长度 键值对的长度是和性能成反比的,比如我们来做一组写入数据的性能测试,执行结果如下: 从以上数据可以看出,在 key 不变的情况下,value 值越大操作效率越慢,因为 Redi ...
- 关键词:ACM & 大小端 & 面试官
关于“ACM” fender0107401 :面试了一个在ACM拿过奖的人 我问了他几个问题: 读取数组中的一个元素,计算复杂度是多少,回答不清楚. 往链表里面存一个数,不排序的情况下,计算复杂度是多 ...
- Android开发面试经——5.常见面试官提问Android题①
版权声明:本文为寻梦-finddreams原创文章,请关注:http://blog.csdn.net/finddreams 关注finddreams博客: http://blog.csdn.net/f ...
- 漂亮回答面试官struts2的原理
众所周知,Struts2是个非常优秀的开源框架,我们能用Struts2框架进行开发,同时能快速搭建好一个Struts2框架,但我们是否能把Struts2框架的工作原理用语言表达清楚,你表达的原理不需要 ...
- Android相关面试题---面试官常问问题
版权声明:本文为寻梦-finddreams原创文章,请关注: http://blog.csdn.net/finddreams/article/details/44513579 一般的面试流程是笔试完就 ...
- Tomcat相关面试题,看这篇就够了!保证能让面试官颤抖!
Tomcat相关的面试题出场的几率并不高,正式因为如此,很多人忽略了对Tomcat相关技能的掌握. 这次整理了Tomcat相关的系统架构,介绍了Server.Service.Connector.Con ...
- 当面试官说 “你还有什么问题想问的” ,你该如何回答?
阅读本文大概需要 4 分钟. 作者:黄小斜 来源:程序员江湖 程序员面试时经常会听到面试官说一些套话,比如"今天的面试就到这里了,回去等通知吧","你还有什么问题想问我的 ...
随机推荐
- 百万年薪python之路 -- MySQL数据库之 存储引擎
MySQL之存储引擎 一. 存储引擎概述 定义: 存储引擎是mysql数据库独有的存储数据.为数据建立索引.更新数据.查询数据等技术的实现方法 首先声明一点: 存储引擎这个概念只有MySQL才有. ...
- Java基础(三十六)日期和时间
1.Date类 (1)无参数构造方法创建的对象可以获取本机当前时间 (2)有参数构造方法创建的对象表示举例计算机系统自身时间的距离为给定的参数 Date date = new Date(); // 当 ...
- unity射线检测
unity中射线检测时非常实用也经常实用的一种手段.下面讲解一下射线检测问题. 1)Ray 根据射线端点和射线的方向定义一条射线 Ray ray= new Ray(transform.position ...
- ArangoDB图数据库--总参
参考文章: ArangoDB原生多模型数据库(百科) ArangoDB官网 ArangoDB数据库入门 arangodb-vs-cassandra arangodb-vs-mongodb2 Arang ...
- zabbix导入数据库报错1046 (3D000) : No database selected
Zabbix导入数据库时报错 使用如下命令导入Zabbix数据库时报错 zcat /usr/share/doc/zabbix-server-mysql/create.sql.gz | mysql -u ...
- sql中实现先排序后分组
数据表结构和数据如下: CREATE TABLE `commun_message_chat_single` ( `id` ) NOT NULL AUTO_INCREMENT, `chat_id` ) ...
- 12 Zabbix4.4.0系统sendEmail邮件报警优化
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 12 Zabbix4.4.0系统sendEmail邮件报警优化 接上一章节 Zabbix4.4. ...
- NIO 在Tomcat中的应用
对NIO的理解 个人单方面认为,NIO与BIO的最大区别在于主动和被动,使用BIO的方式需要等待被调用方返回数据,很明显此时调用者是被动的. 举个例子 阻塞IO 假设你是一个胆小又害羞的男孩子,你约了 ...
- 学习笔记25_MVC前台API
**当请求url的规则有所改变时,前台的所有超链接的href都得改,为了避免多处修改,可以href = "< %=url.Action("Controller",& ...
- CSPS模拟 92
为什么每次我的flag都会倒? skyh:12:15之前你把T2改出来我吃屎. ----12:10 于是12:12把线段树打完 12:13把主函数打完,过样例,带着一个sb错误交了,WA飞. 然后我就 ...