-
java面试题及解答—Redis
一、Redis的数据结构及应用场景
- String:存储字符串类型数据,一般用来存储json格式的对象数据
- List:存储列表数据,应用场景可以用来做秒杀场景,提前将商品放到list中,因为redis的pop操作是原子性的,多个用户同时请求也是依次pop,list为空了则说明商品卖完了
- Hash:存储结构体数据,类似于java的HashMap,底层数据结构是数组+链表,应用场景同样是存储结构化的对象数据,不同于string类型的是,hash可以将每个字段单独存储,需要取的时候可以根据字段只取对应的数据,无需像string类型那样全部取出
- Set:存储不重复且无序的数据,类似于java的HashSet,底层用的是HashMap,其value为null,应用场景用于对数据去重
- Zset:存储有序的不重复的数据,是java的sortedSet和HashMap的结合体,一方面是set,保证了内部value的唯一性,另一方面对每个value设置了一个score权重值,根据score进行排序,应用场景是各类热门排序场景,比如音乐的榜单,歌曲ID是value,根据播放次数是score,这样就可以根据播放次数score进行排序
二、redis的持久化机制
-
RDB:
- 持久化原理:全称是Redis DataBase,将数据以快照的形式保存在磁盘上,是某个时间点上所有数据的备份,是redis默认的持久化方式。
- 触发条件:手动触发:通过命令save或者bgSave持久化,自动触发:在redis.conf文件中配置触发的条件,比如900秒内有一个key值变化
- 优点:因为RDB是保存的快照,特别适合容灾恢复,直接将快照导入到redis中即可恢复数据
- 缺点:因为RDB是进行全量备份,对于数据集比较大的场景,需要好几分钟才能备份完成,因此设置的触发条件时间也必须是几分钟,当节点故障时,就要丢失几分钟的数据
-
AOF:
- 描述:全称是Append-Only File,全量备份往往是比较耗时的,这时我们需要一种比较高效的备份方式。
- 持久化原理:AOF是将写入数据的命令通过write函数追加到文件中。
- 触发条件:每次修改触发、每秒触发、不触发,默认是每秒触发
- 优点:鉴于AOF的触发条件,当发生系统故障时,最多只会丢失一秒钟的数据
- 缺点:AOF存储的是写入的命令,因此文件会比RDB大很多,并且在进行故障恢复时,效率也低于RDB
- 参考RDB与AOF的区别、Redis持久化之RDB与AOF
三、redis雪崩、击穿和穿透
-
雪崩
- 描述:redis缓存大面积失效,导致请求直接落到数据库上,数据库承受不住压力,直接挂了
- 原因:造成雪崩的原因有两种,一:redis故障,无法接受请求;二:redis上的缓存有效期大面积到期
- 解决:对于第一种原因,可以提高redis的高可用,做缓存降级,在本地使用EhCache缓存,第二种原因,可以随机设置缓存的有效期,使其在不同的时间失效
-
击穿
- 描述及原因:redis热点缓存失效,热点key在承受着高并发,当这个热点key失效之后,所有请求会直接落在数据库上,导致数据库宕机
-
解决:
- 1、设置热点key永不过期
- 2、加互斥锁,请求A访问数据库时,其他请求需要等待,等请求A查询完成,添加到redis中,其他请求发现redis已经有数据了,就不会再请求数据库了
-
穿透
- 描述及原因:请求的数据在缓存和数据库中都不存在,请求就一直落到数据库中,导致数据库压力过大宕机
-
解决:
- 1、对不存在的数据,将key和value为null的数据缓存起来,并设置一个较短的过期时间,防止过期时间过长,影响其他用户使用
- 2、做接口参数校验,拦截掉非法的请求
- 3、对同一时间内请求次数过多的非法请求IP做封号处理
- 参考:redis缓存雪崩,击穿,穿透,到底是什么?
四、保证redis高可用
-
主从架构
-
主从复制:
- 1、一个slave节点第一次连接或者重新连接到master节点时,会发送一个SYNC命令给master
- 2、master收到这个命令之后,会干两件事,1)执行bgsave,即将缓存中的数据创建一个RDB快照文件,2)将新收到的写入和修改数据集命令保存到缓冲区
- 3、master节点将创建的RDB文件传输给slave节点,slave节点则清空自己的内存,加载RDB文件的内存中
- 4、master节点缓冲区的命令传送给slave节点,slave节点执行这些命令,达到主从数据的一致性
- 5、此后master/slave节点会通过异步请求方式同步master收到的命令
- 读写分离:master节点只处理写入和修改请求,并同时同步给slave节点,slave节点只处理查询请求
-
主从复制:
-
哨兵模式
- 描述:主从架构中,只有一个主节点,一旦主节点发生异常宕机,整个系统将瘫痪不可用,于是需要一个哨兵模式来检测主节点状态及主从切换
- 监测:哨兵周期性地向所有节点发送类似ping命令,看是否能正常应答,如果不能,则主观判定为下线,如果哨兵群的多数(n/2+1)判定主观下线,则认为客观下线
-
选主:一旦认定主节点下线,就要开始选择新的主节点。一般会将选择主节点的过程分为“筛选+打分”,就是从所有从节点中过滤掉经常掉线的和网络不好的,然后将剩下的节点按照
从库优先级
、从库复制进度
和从库ID
依次判定,即从库优先级最高的作为新的主节点,如果全都一样,则判定从库从主库上的复制进度,进度最高的当选主节点,如果进度全都一样,则判定从库ID,ID小的当选主节点,选定好新的主节点时,就可以开始进行主从切换了
-
拓展
- 1、哨兵模式中,哨兵宕机了,怎么保证主从切换?:哨兵模式中,哨兵也会采取集群模式,至少需要三个哨兵组成集群,当一个哨兵宕机,另外的哨兵依然可以正常工作
- 2、主从切换进行中,客户端能正常请求操作吗?:如果redis采用的是读写分离,那么读请求可以正常响应,写请求则会失败
- 参考redis高可用之哨兵模式
五、redis实现分布式锁
-
加锁
- 加锁其实就是在redis新增一个键值,为避免死锁,设置过期时间
- 发送命令set key value nx px time
- 命令解释:nx-设置成功返回1,失败返回0,px-过期时间,time-毫秒时间
- 加锁过程:使用上面命令尝试执行,如果返回1则说明加锁成功,返回0则说明加锁失败,遇到加锁失败,本地不断尝试加锁,直到成功,即可完成分布式锁的实现
-
解锁
- 使用del命令将key删除,达到解锁目的
- 原文:https://www.cnblogs.com/jorry-yun/p/14752313.html
最新更新
带有参数的装饰器
类装饰器
django中的auth模块与admin后台管理
python的日期处理
字符串常用方法
基本数据类型概述
python-map()函数基本用法
python带你实现任意下载AcFun视频数据~
bbs项目之注册功能
变量的定义和使用
三大常用数据库事务详解之三:事务运行
三大常用关系型数据库事务详解之二:基
三大关系型数据库事务详解之一:基本概
MongoDB常用命令(2)
MongoDB基本介绍与安装(1)
SQLServer触发器调用JavaWeb接口
SQL Server索引的原理深入解析
SqlServer2016模糊匹配的三种方式及效率问题
SQL中Truncate的用法
sqlserver 多表关联时在where语句中慎用tri
VB.NET中如何快速访问注册表
ASP.NET中图象处理过程详解
Vue(1)Vue安装与使用
JavaScript 语言入门
js将一段字符串的首字母转成大写
纯原生html编写的h5视频播放器
H5仿原生app短信验证码vue2.0组件附源码地
TypeScript(4)接口
TypeScript(3)基础类型
TypeScript(2)WebStorm自动编译TypeScript配置