之前在平安云面试,面试官问的最多的就是源码知识,比如Spring的源码,Redis的源码,mybatis源码等主要围绕的是spring,Spring Boot源码大家族进行开展。平时在项目上很多东西都是大牛们搭建好的架构,我们只要去写业务就行,不是很注重底层。
自从这次面试以后就非常注重对框架底层的探索。说研究?真的,java框架更新太快根本研究不完,我感觉只要弄懂底层的一些知识,框架再怎么变换都可以理解。而且技术永远学习不完。记得前段时间在微信公众号上看到的文章《千万不要一辈子靠技术生存》我觉得写的挺有道理的(文章链接:https://mp.weixin.qq.com/s/1MSQrpamVaxOcUW1pZKBLA),在没有高等学历,没有异于常人的钻研技术能力(可以说天赋)下,技术研究的越深可能反而越容易迷失自己,使自己迷茫。但是想要提升自己,技术又不得不学,这就变成了哲学问题了,哲学引人深思。
面试官问了我三个问题关于redis的问题:redis持久化方式有什么哪些?Redis两种集群有什么不用?前两个我回答不上来,后面又问了,maven引入的reids名字叫什么?我都没有答上,当时做的项目用多线程,所有自己围绕多线程知识点准备了很久?围绕三个面试题,在京东上买了《Redis设计与实现》,其实可以根据redis官方文档去学习。今天围绕redis两种持久化模式去说一说,面试时应该怎么回答?
RDB持久化
- RDB基本概念
RDB持久化既可以手动执行,也可以根据服务器配置选项定期执行,该功能可以将某个时间点上的数据库状态保存到一个RDB文件中。
RDB持久化功能所生成的RDB文件是一个经压缩的二进制文件,通过该文件可以还原RDB文件时的数据库状态。
RDB持久化通过保存数据库中的键值对来记录数据库状态的不同。
- RDB文件的创建与载入
有两个redis命令用于生成RDB文件,一个是SVAE,一个是BGSAVE。
1.SAVE命令有服务器进程直接指向保存操作,会阻塞服务器。
2.BGASVE命令由子进程执行保存操作,所有该命令不会阻塞服务器。
第三. 服务器载入文件流程
RDB文件的载入工作是在服务器启动时自动执行的,所有redis并没有专门用于载入RDB文件的命令,只要Redis启动时检测到了RDB文件,它就会自动载入RDB文件。但AOF文件的更新频率通常比RDB文件的更新频率高,于是就涉及到载入文件的流程。
Redis服务启动载入文件流程
1. 服务器启动。
2. 执行载入程序。
3. 判断是否开启AOF持久化。
4. 是就载入AOF,不是就载入RDB。
小结:也就是说,RDB的载入不是一定会被载入的。另外服务器在载入RDB文件期间,会一直处于阻塞状态,知道载入工作完成为止。
第四.通过设置save去满足RDB特定时间持久化
通过设置save选项设置多个保存条件:
如:
Save 900 1 服务器在900秒之内,对数据库进行至少1次修改
Save 300 10 服务器在300秒之内,对数据库进行至少10次修改
Save 60 10000 服务器在60秒之内,对数据库进行至少10000 次修改
AOF(append only file)持久化
- AOF基本概念
- AOF持久化是通过Redis服务器所执行的写命令来记录数据库状态。
2. 命令请求会保存到AOF缓冲区里面,之后再定期写入并同步到AOF文。
AOF持久化的实现
AOF持久化的实现,三个步骤:
1. 命令追加(append)
2. 文件写入
3. 文件同步(Sync)
AOF重写
AOF重写,因为AOF持久化是通过保存被执行的写命令来记录数据库状态的,所有AOF文件中的内容会越来越多,文件的体积也会越来越大,如果不加以控制的话,体积过大AOF文件很可能会对Redis、甚至整个计算造成影响,并且AOF体积越大,数据库还原的时间也越多。而AOF重写就是为了解决体积膨胀的问题。
AOF重写:redis可以创建一个新的AOF文件来替代现有的AOF文件,两个文件数据库状态一致,但新的AOF不会浪费任何空间命令,所有新的文件比旧的文件小很多。
AOF重写原理:
比如:第一条命令push list ‘a’
第二条命令push list ‘b’
第三条命令push list ‘c’
这样,AOF旧文件上面就会有三条命令,但重写之后就变成了:push list ‘a’ ’b’ ’c’一条,大大的减少了很多浪费的空间。
- AOF缓冲区AOF后台重写有关
因为在AOF重写的时候有大量的写操作,所有会堵塞,因为redis是单线程的,如果直接使用服务器来执行的话就会阻塞其他的操作。而AOF又是一种维护数据的辅佐性功能,也就是说redis不是主要来进行AOF重写的,所有redis决定把AOF重写程序放在子进程里面执行。这样也会造成一个问题:主进行如果对数据库进行了状态修改怎么办?为了解决主进程与子进程的问题。Redis设计设置了一个AOF重写缓冲区。主进行的所有写命令都写入这个缓冲区。AOF重写的时候,所有的命令都在缓冲区,把内容写到新AOF文件中,然后创建旧文件一样的名字,覆盖旧的文件。
总结:
1.RDB文件为压缩的二进制文件,保存数据库所有的键值对数据
2.SAVE和BGSAVE前者会阻塞服务器,后者不会阻塞服务器
3.AOF文件通过保存所有修改数据库的写命令请求记录服务器数据状态
4.AOF文件中的所有命令都是以Redis命令请求格式保存的
5.命令请求先保存到AOF缓冲区,然后在定期写入并同步到AOF文件
6.AOF文件可能会膨胀,AOF重写可以解决整个问题
7.AOF重写会生产一个新的AOF文件覆盖旧的AOF文件,新的AOF文件很比旧的文件小很多
8.在AOF重写期间可能会出现主进程与子进程数据不同步的问题,用了一个AOF重写缓冲区解决了这个问题。
RDB和AOF不同点
1.RDB和AOF存储的数据格式不一样
2.RDB特定时间持久化,如果宕机了,载入RDB文件的话,宕机期间的数据可能会丢失。而AOF采用每秒,和缓冲区的设计一般不会有数据丢失的问题
3.RDB载入会堵塞服务器,AOF载入不会阻塞,因为AOF载入的时候回创建一个伪客户端去载入AOF里面的命令
·
RDB和AOF到底如何选择
1.不要仅仅使用RDB这样会丢失很多数据。
2.也不要仅仅使用AOF,因为这一会有两个问题,第一通过AOF做冷备没有RDB做冷备恢复的速度快;第二RDB每次简单粗暴生成数据快照,更加健壮。
3.综合AOF和RDB两种持久化方式,用AOF来保证数据不丢失,作为恢复数据的第一选择;用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,可以使用RDB进行快速的数据恢复。
有更多的技术可以一起分享,一起成长。