Redis面试题(不完整)

75 阅读5分钟

1、Redis的五种数据类型及应用场景?

	值的五种数据类型
		string
			key:value
		hash
			大key
				k1【field】   v1
				k2   v2
		list
			key:集合  有序
		set
			key:集合   无序、不重复
		zset【sorted set

应用场景

		string
			验证码
				存入到Redis中的key应该怎么写?
					标识性的前缀:统一标记
					模块名:功能名:code:手机号
				有效期怎么确定?
					5分钟:放在Redis
					5分钟:短信内容
				如何防止频繁发送验证码?
					setnx
				如何防止同一个机器不断获取验证码?
					一个机器,在半小时之内,只能获取5次验证码?超过,我就不允许发送了
			分布式session
				登录
			计数器
				incr
					文章阅读数
			 缓存热点数据
		hash
			购物车
				
				用户登录之后的购物车
					cart:uid
						商品id
							数量
				未登录的购物车【面试时不要讲】
					cart:uuid
						商品id
							数量
				合并购物车【不要讲】
					合并时机
						登录合并
							合并购物车,要做异步
								要清空未登录的购物车
					怎么合并
						判断有没有用户登录的购物车
							没有
								创建车
									把未登录的车中的数据拿过来
							有
								判断未登录的车有数据在用户车中有没有
									没有
										增加
									有
										加数量
			学习计划
		list
			队列
				消息队列,保证顺序消费
		set
			抽奖
				
		zset
			排行榜

2、Redis持久化机制?

	1、Redis数据存储在内存
		一般不是重要的数据,可能会丢失
	2、持久化机制
		持久化
			把数据保存磁盘上
		分类
			不持久化
			RDB
				会根据配置的规则进行定时快照备份
					
				优点
					快照数据以二进制存储,文件小,恢复速度快
				缺点
					因为有时间间隔,会丢失一定的数据
				原理
					手动执行 bgsave 命令,来触发RDB
					主进程会fork一个子进程在后台完成RDB【读取内存的数据,形成一个dump.rdb,更换旧的rdb文件】
						
			AOF
				以日志的形式记录key发生变化的指令
					默认是关闭的
					记录到一个文件中:appendonly.aof
					触发时机
						
				优点
					数据以命令的形式存储,数据不容易丢失
					文件会重写
						去重无用指令
						优化数据最终得到的结果是多少即可
						手动重写
							bgrewriteaof
				缺点
					文件大、恢复速度慢
					AOF文件可能会被篡改
			RDB + AOF
				AOF + RDB文件在压缩以RDB二进制的方式去存储
					配置文件可以配置

3、Redis淘汰策略?

	Redis数据存储在内存,如果内存被打满了?就会触发淘汰策略
	淘汰
		定期淘汰【主动】
			
			一般会选择 volatile-lru
				取样基数:5
				Redis会把内存所有的key分为5个一组,在5个中淘汰一个满足条件的key
		隋性淘汰
			redis中的key如果过期了,是不是会立即被删除?
				不会
			客户端来查询一个key,redis会先判断该key是否过期,不过期直接返回。过期就删除,再返回一个null

4、高可用

	0、单点故障
		单台服务器运行的项目,如果服务器宕机了,项目就挂了
	1、主从
		职责
			主节点负责写
			从节点负责读
		数据同步
			从节点去同步主节点数据
				全量复制
				增量复制
					通过 offset 来定位需要复制的后续数据的位置
	2、哨兵
		职责
			是为了提升主从架构的可用性
			用来监控主从架构的是否可用
		选举
			哨兵监控主从节点宕机,当主节点宕机后,通过其他哨兵,确认主节点宕机了,通知从节点进行选举
			主节点选举
				谁的数据多,谁当主节点
				谁的数据新,谁当主节点
	3Cluster(集群)
		图
			
		主从
			主节点负责读写
			从节点只负责同步数据
		如何存储数据
			会根据key进行hash运算,得到对应的槽位,把数据放进去

5、分布式锁

	1、分布式锁
		传统锁
			Synchronized
				jvm
				关键字
				没办法手动释放锁
			Lock
				api
				类库
				手动释放锁
			
		分布式锁
			
	2、热点数据【key】重建问题
		没锁
			
		分布式锁
			
			死锁
				异常没释放锁
				解决方案
					设置过期时间
					把释放锁的代码放到finally中
			误删锁
				线程一删除其他线程的锁
				因为锁的过期时间,可能会造成误删锁
					锁已经过期,但是代码还没执行到删锁的代码
			完善版
				
	3、redisson
		
		执行流程
			1. 线程一尝试去获取锁,拿到锁之后【锁的有效是30S2. 在后台开启一个子线程【定时(每过10秒)去查询当前线程是否还持有锁,如果有,则给锁续命(延长锁到30S)】,直到主线程执行结束,手动释放锁。同时可以指定给锁续命的次数,如果超过了,则可以主动删除锁
			3. 线程二尝试去获取锁,拿锁失败,会进行自旋【每隔一定时间去拿锁】,直到拿锁成功后去执行2
		

6、Redis使用问题

	1、穿透
		概念
			访问缓存中没有,数据库中也没有的数据,感觉像穿透了缓存层,直达数据库,可能会造成数据库宕机。这个其实是一种恶意手段
		解决
			1、查一个不存在的数据时,设置一个具备过期间的假数据,存入缓存
				简单粗暴
			2、布隆过滤器
				查询缓存前,先判断当前key在布隆过滤器中是否存在
					一定不存在
						直接返回
					有可能存在
						再查询缓存,没有,再查询数据库
				Redisson直接有实现方案
	2、击穿
		概念
			某一个热点数据的key突然过期,造成大量请求直达数据库
		解决
			1、分布式锁
			2、热点数据永不过期
			3、接口限流
	3、雪崩
		概念
			缓存中在同一个时间点有大量的key同时过期,请求查询缓存中没有,直达数据库
		解决方案
			1、随机过期时间
			2、热点数据永不过期
	4、多个命令如何保证原子性?
		使用LUA脚本
		Redis的事务