目录

  • 前言
  • 1.什么是Redis持久化?
  • 2.为什么Reids要做持久化?
  • 3.Redis怎么做持久化呢?
    • RDB快照方式
    • AOF顺序指令方式
    • 混合持久化

前言

1. 一文干翻Integer、int等基础数据类型和包装类型相关问题
2. 面试必问 容器 ArrayList
3. 面试必问 Redis 持久化
4. 面试必问 Redis 数据结构底层原理一
5. 面试必问 Redis 数据结构底层原理二

本文采用一问一答的对话方式进行阐述,场景是给公司级别低一点儿的小老弟解释相关技术原理,回答一下他们的技术困惑。适合饭前饭后,办公室哈牛逼,希望你们看了以后能有收获,后边跟其他人吹牛逼的时候,也可以吹的大声点不是吗,O(∩_∩)O哈哈~。

人员:

  • 李哥:(也就是本博主了)8年一线码厂老司机
  • 阿水:3年工龄开发一枚

场景:

由于办公地点离食堂路程大概有5-6分钟的路程,于是乎在干饭的路上就产生了下面的对话。

【阿水】:李哥,年底了,我上周去面试了家小厂,面试官问我redis持久化的东西,我几句话就答完了,感觉没什么亮点,有点裂开的感觉,能不能给我来点儿逼格高一点的讲解啊。

【李哥】:(清了清10年的老烟嗓子)那必须滴啊,直接干他个30分钟,你看啊,咱们叙述事情最好要有条理,讲清楚前因后果,凡事儿一二三四五,逻辑要有闭环,才能给人眼前一亮的感觉。

对不对啊,阿水,那么我们就以经典方法论“3W法”是什么(what),为什么(why),怎么办(how)的思路来阐述一下“redis持久化”这个话题。

那么第一个问题就是什么是持久化

1.什么是Redis持久化?

简单的来说其实就是把内存中的数据已文件的形式存储到硬盘中,延长数据的生命周期,实现数据的长久存储,方便数据迁移、备份。

然后在Redis的重启或者操作系统的重启之后数据还能够找到并恢复。

2.为什么Reids要做持久化?

举个栗子:我们Redis里面缓存了500w条车辆基本信息,平时我们都是直接从Redis查询,那是多么的愉快,但是如果有一天Redis突然挂了或者被运维误杀了,那我们就裂开了,首先赶紧重启Redis,但是Redis里面的数据如果没做持久化,那么重启之后,数据可就全没了,如果这个时候大量请求过来,数据库可能直接被打挂了,就算没有大量请求,之前缓存的大量数据也只能重新从数据库一点点初始化数据到缓存,这种方式太慢了,如果我们之前缓存了50g,那不知道要恢复到猴年马月了,所以需要实现数据快速恢复机制增强redis系统的可用性

3.Redis怎么做持久化呢?

Redis 提供了两种持久化的方式,分别是 RDBAOF

  • RDB : Redis的默认持久化方式,是基于 快照 来实现的,当符合一定条件的时候 Redis 会自动将内存中的数据进行快照然后持久化到磁盘中。
  • AOF : Redis默认没有开启 AOF 持久化,需要在配置文件中设置 appendonly true 开启。它存储的是 Redis顺序指令序列

【阿水】:李哥,我擦,我就是这么回答的,感觉回答的太少了,体现不了牛逼之处啊。

【李哥】:那肯定啊,可以这么说基本上90%的程序员都能回答道这里,咱们必须再继续整活儿啊,体现出与众不同啊,“3W”理论继续干起来。继续拆解RDB、AOF。

RDB快照方式

什么是RDB方式持久化?

RDB持久化是将Redis中某个时间点上存储数据的全部拷贝,形成一个二进制数据的副本,保存的文件后缀为rdb。 此文件 dump.rdb(默认文件名) 保存了当前redis中的全部数据, 可以对此文件进行备份、迁移操作。生成快照文件后,Redis在重新启动时,会自动的加载快照中的数据。

为什么用RDB方式?

  • 数据是完全备份的,不同时间的数据集备份可以做到多版本恢复,适合用来做冷备

  • 紧凑二进制文件,方便网络传输,适合灾难恢复

  • 恢复大数据集速度快

  • 对redis对外提供的读写服务影响非常小,因为fork了一个子进程来做快照的创建工作

RDB方式是怎么玩的呢?

既可以主动式生成快照,也可以被动式生成快照

主动式

  • 客户端主动发送保存命令SAVEBGSAVE

  • Redis 正常关闭的时候

  • 主从复制进行第一次全量复制的时候

被动式

使用 save 相关配置触发,比如 “save m n”,表示在 m 秒内数据库存在 n 次修改时,自动触发BGSAVE 。Redis 默认配置如下:

save 900 1      # 在 900 秒内如果至少有 1 个 key 的值变化,则触发
save 300 10     # 在 300 秒内如果至少有 10 个 key 的值变化,则触发
save 60 10000   # 在 60 秒内如果至少有 10000 个 key 的值变化,则触发
#禁用RDB配置:save " "

当实际操作满足配置(满足一个条件即可)的 save 形式时就会进行 RDB 持久化,将当前的数据快照保存,每次都会生成一个新的快照,覆盖之前的老的快照,即只有一个文件 dump.rdb

这种save配置方式非常的巧妙,即解决了定时中,一个周期大量突发key问题, 又解决了定量中,很久才更新的问题,值得学习一手。

这里要注意一下,SAVEBGSAVE的区别。

SAVE :命令是同步操作,会阻塞当前 Redis 服务器直到RDB 持久化过程完成为止,对于内存比较大的实例会造成长时间阻塞,在服务器进程阻塞期间,服务器不能处理任何命令请求,不建议在线上环境使用,适合停机维护,服务低谷时段。

BGSAVE :命令会执行 fork 操作创建一个子进程,由子进程完成 RDB 持久化过程,完成后自动结束,服务器进程(即父进程)继续处理命令请求,阻塞只发生在 fork 过程,一般时间很短。基本上 Redis 内部的 RDB 操作都是采用 BGSAVE 命令。

【阿水】fork是个啥?这么叼?

【老李】fork是操作系统的一个函数,fork用于创建一个子进程,注意是子进程,不是子线程。fork出来的子进程共享其父类的内存数据,注意不是复制一份,否则内存都被浪费掉了。仅仅是共享fork出子进程的那一刻的内存数据,后期主进程修改数据对子进程不可见,同理,子进程修改的数据对主进程也不可见。当主进程修改数据的时候采用写时复制技术,复制需要修改的那一页,而不是全部的内存,其余的页还是共享主进程的,来实现数据的隔离。

【阿水】:这个fork+写时复制是真的秀啊!!!

【老李】:嗯,但是呢!最大的问题是会丢失最近写入、修改的而未能持久化的数据,所以来看看后面的AOF方式。

AOF顺序指令方式

什么是AOF持久化?

在持久化的时候往AOF 日志中存放的是Redis操作指令,会将客户端对于redis的操作(查询除外)以一个字符串的形式拼接到磁盘的文件末尾,而在重启redis的时候会去读取这一个文件,将命令重演

为什么用AOF持久化?

  • 因为rdb的方式会丢失最近写入、修改的而未能持久化的数据,AOF通过配置基本上(后面会介绍)可以在服务出现故障时,不丢失任何数据。
  • AOF 文件的格式可读性较强,可以二开,实现定制需求
  • 提供了多种同步频率,即使使用默认的同步频率每秒同步一次,Redis 最多也就失去 1 秒的数据
  • AOF写入性能高,以append-only的方式写入文件尾部

AOF持久化怎么实现的?

默认是关闭AOF的,打开的话可以参考下配置:

# 默认为no,需修改为yes
appendonly yes
# AOF默认的持久化文件的文件名称
appendfilename "appendonly.aof"

在打开AOF持久化的配置选项后,redis每次接收一条写命令,将内容写入到某个文件里面时,为了提高效率,系统通常不会直接将内容写入硬盘里面,而是先将内容放入一个内存缓冲区(buffer)里面,等到缓冲区被填满,或者用户执行fsync调用和fdatasync调用时才将储存在缓冲区里的内容真正的写入到硬盘里。未写入磁盘之前,数据可能会丢失。

appendfsync everysec:fsync持久化策略

关于fsync操作,redis的配置文件中提供了 appendfsync选项来支持不同的选择策略,可配置策略如下:

  • always: 每个写命令都要同步到硬盘,降低了redis的速度
  • everysec: redis的默认配置选项,每秒执行一次同步
  • no: 让操作系统来决定应该何时进行同步。

当我们不停的往AOF文件写入命令,那么AOF的文件会越来越大。怎么办呢?为了解决AOF文件不断增大的问题,redis引入了重写机制来解决,需要特别说明的是重写是对redis中的数据转化为写命令,不会对旧的AOF文件进行任何的读取和写入操作。

相关配置如下

# 当AOF的持久化文件大小的增长率大于此配置时,自动开启重写,redis会自动执行“BGREWRITEAOF”命令;
auto-aof-rewrite-percentage 100
# 当AOF的持久化文件大小大于此配置时,自动开启重写,redis会自动执行“BGREWRITEAOF”命令;
auto-aof-rewrite-min-size 3000mb

【阿水】: AOF方式这么叼,还要RDB方式干嘛呢,而且默认的方式还是RDB?

【李哥】: 很经典的一句话,存在就有其道理,AOF也不是完美的。

  • 对于同样的数据,通常AOF文件的大小会比RDB的要大;
  • 数据恢复的时候AOF存的是命令而不是二进制数据,以命令重演方式恢复,所以恢复数据时较慢
  • AOF开启之后,支持写的QPS会比RDB支持写的QPS低

还就就是AOF也是无法做到不丢失数据的Redis 中的 AOF先执行命令再存日志的。这和 MySQL 中的 WAL 机制截然相反。

【阿水】:那如果2种持久化都开启,redis重启的时候会加载哪种文件呢?

【李哥】:在这种情况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。

【阿水】:李哥,那有没有什么办法能把RDBAOF两种持久化方式优点结合一下呢?

混合持久化

【李哥】:Good question! Redis 4.0 以后开始支持 rdb 和 aof 的混合持久化(默认关闭)。如果把混合持久化打开,AOF在进行文件重写时 , 将重写这一刻之前的内存rdb快照文件的内容和增量的AOF修改内存数据的命令日志文件存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换。

开启混合持久化:
aof-use-rdb-preamble yes

从文件格式可以看到,混合持久化appendonly.aof文件由rdb格式和aof指令格式两大部分组成
Redis在重启时,先读取RDB部分到内存,然后再读取AOF部分到内存,重启效率高,还能减少数据的丢失。缺点也是有的, appendonly.aof里面的 RDB部分就是压缩格式不再是指令,可读性差。

【阿水】:(发出 哼哼哼的声音),我感觉我又行了,下次哈牛逼,可以很大声了O(∩_∩)O哈哈~

参考:

https://juejin.cn/post/6844903992649056263

http://c.biancheng.net/view/1272.html

https://juejin.cn/post/6844903655527677960

https://www.jianshu.com/p/a0bf258d1b5a

https://juejin.cn/post/6844903655527677960

https://www.cnblogs.com/yulibostu/articles/13581132.html


QQ群【837324215
关注我的公众号【Java大厂面试官】,回复:架构资源等关键词(更多关键词,关注后注意提示信息)获取更多免费资料。

公众号也会持续输出高质量文章,和大家共同进步。

看故事学知识 三年工龄了还讲不清redis持久化!相关推荐

  1. 看故事学知识,这篇Java代理的文章妙啊!

    这是我的第 208 期分享 作者 | java金融 来源 | java金融(ID:java4299) 分享 | Java中文社群(ID:javacn666) 什么是代理 代理模式是常用的java设计模 ...

  2. 看代码学知识之(2) ListView无数据时显示其他View

    看代码学知识之(2) ListView无数据时显示其他View 今天看的一块布局是这样的: <!--The frame layout is here since we will be showi ...

  3. 看故事学Redis:再不懂,我怀疑你是假个开发

    摘要:还不懂Redis?看完这个故事就明白了! 本文转载自博客园社区<还不懂Redis?看完这个故事就明白了!>,作者:轩辕之风 我是Redis 你好,我是Redis,一个叫Antirez ...

  4. 看漫画学知识:详解获得苹果推荐的4大要素

    随着移动游戏市场的竞争越来越激烈,相对应的推广成本也水涨船高,对于一款app来说,如果能获得苹果编辑的青睐,登上AppStore的推荐位的话,能大幅提升游戏的排名和收入.但是苹果的推荐也不是那么好拿的 ...

  5. 【云计算】云计算四个必学知识看这里

    近几年,企业上云进程加快,云计算呈快速上涨模式:未来云计算也会以更多样化的形式出现助力企业加速完成数字化转型.所以企业一定要了解云计算,要知道云计算相关知识. 云计算四个必学知识看这里! 知识一.云计 ...

  6. 看漫画学python电子书-看漫画还能学Python❓❓❓| 0基础小白福音

    ��你还在枯燥无味地学编程吗?你还在闷头背诵那些根本没有理解的内容?根本不用那么煎熬!想不想来体验一下翻着漫画就搞定Python的感觉?? <看漫画学Python:有趣.有料.好玩.好用(全彩版 ...

  7. 租房子看“肥学”⚡依托某地图和爬虫找房⚡(python知识学习)

    租房子看肥学一条龙服务 导读

  8. 跟vczh看实例学编译原理——一:Tinymoe的设计哲学

    自从<序>胡扯了快一个月之后,终于迎来了正片.之所以系列文章叫<看实例学编译原理>,是因为整个系列会通过带大家一步一步实现Tinymoe的过程,来介绍编译原理的一些知识点. 但 ...

  9. TC---教学知识与能力

    第一章----教育基础知识和基本原理 1.教育及其产生与发展 1.1 教育的概念 教育一词的由来 "教育"一词最早出现在<孟子-尽心上>:"得天下英才而教育之 ...

最新文章

  1. div+css中设置了float属性后如何让外层的高度随着内层的高度大小自动调整
  2. JavaScript 中的闭包和作用域链(读书笔记)
  3. delphi7 mysql控件_Delphi7连接MySql数据库-DBGrid控件显示数据
  4. 2018web前端面试题总结
  5. visual stdio打开之后与屏幕尺寸不匹配_柔和点亮桌面,让眼睛更舒服,雷神屏幕挂灯L1体验...
  6. Python 之父 Guido van Rossum 退休失败,正式加入微软搞开源!
  7. 二叉搜索树的后序遍历
  8. Vue 当中的计算属性computed
  9. Caffe(13)--(SSRNet模型)Keras转Caffe教程
  10. QImage缩放后图片更清晰处理
  11. laydate使用官方使用方法
  12. 第108章 属性关键字 - Required
  13. JS原生实现照片抽奖
  14. [USACO2.1]Healthy Holsteins 健康的荷斯坦奶牛 题解(DFS/BFS详解)
  15. python打包成独立exe_用PyInstaller把Python代码打包成单个独立的exe可执行文件
  16. GNU gettext
  17. 局域网内用QQ传文件,会经过腾讯的服务器么?
  18. JDK8详细图文安装教程
  19. Python-心型照片墙
  20. selenium谷歌浏览器驱动配置

热门文章

  1. Atlas深度学习模型转换及运行
  2. UVa 202 - Repeating Decimals —— 分数循环节
  3. 远程Linux权限不够
  4. day 15爬虫与反爬虫与反反爬
  5. 戴尔服务器型号用途,戴尔服务器DELLPowerEdgeR610详细参数用途解析-20210408230926.doc-原创力文档...
  6. python index()函数
  7. excel表格末尾添加一行_WPS表格办公—表格隔开不同数据
  8. 洛谷P3723 [AH2017/HNOI2017]礼物
  9. 在线问题反馈模块实战(十五)​:实现在线更新反馈状态功能
  10. html5中怎么把图片放大,HTML5中,如何为图片制作放大镜效果?