面试题
Redis是什么
Redis是no sql 数据库,特性有什么?
- 单线程:Redis类型队列的有事,把并行改为串行访问,减少了并行访问的开销
- 基于内存数据库,性能非常出色
- 每秒可以访问10万多次,key-value可以存储1GB
- 支出多种数据类型
Redis与Memcached的区别
都是属于no sql 数据库
- Redis速度比memcached上快
- memcached只支持string类型
- 没有持久化功能
Redis数据类型
- String类型
- list类型
- set类型
- Sorted Set 类型
- hash类型
Redis是单线程为什么这么快
- 数据存储在内存中,时间复杂度o(1)-重要
- 单线程避免线程之间上下文切换
- 使用了IO多路复用模型,多个链接,只用一个线程
Redis持久化机制
Redis持久化机制,有两种方式,RDB和AOF
RDB可以理解为快照,例如我们VM中的快照,后者照相机是一个道理。下面是他的执行流程
AOF
aof是写的时候都会把命令复制到Aof文件中,在redis重启的时候会重新加载aof文件,这样可以保证数据不会丢失。下面是aof操作的流程,其实与rdb差不多原理,但是利用的思想却不一样,但是使用场景达到的效果就不同~
RDB和AOF的优缺点
1 RDB特性是快照存储,存储快,文件类型小,但是可能会丢失数据,持久化不好
2 AOF特性是存储写命令,文件大,在重启时重新加载aof文件,不会丢失数据
Redis淘汰策略
什么是会触发淘汰策略?
当客户端发起请求存储数据的时候,redis会检查内存情况,如果超出maxmemory的时候会触发淘汰策略。
Redis过期淘汰策略
- 定时过期,每个设置过期时间的key都需要设置一个定时器,这样到过期时间的时候清除,这样的好处就是可以及时的清除数据,但是可能会导致cpu利用率太高,会影响缓存的相应时间和吞吐量
- 惰性过期,只有当访问一个key的时候会去判断是否过期,如果过期则清除,缺点是内存中存在很多过期的key
- 定期过期:定期去访问一定量的key,筛选然后清除
Redis总共有6大淘汰策略分为两大类,第一类属于只从kv键中设置过期时间,第二大类从所有的kv对中筛选
第一类从所有kv键设置过期时间筛选:
- volatile-lru(less recently used) 当内存不足时从设置kv过期键中选择最近最少使用的键值对淘汰
- volatile-ttl(time to live) 当内存不足时设置kv过期键中选择剩余时间最短的kv键淘汰
- volatile-random 当内存不足时从设置kv过期键中随机选择键值对进行淘汰
第二大类从All键中筛选:
- allkeys-lru 当内存不足时 从所有键值对中选择最近最少使用的键值对淘汰
- allkeys-random 当内存不足时从所有键值对中随机选取淘汰
- noeviction 当内存不足时不淘汰策略,返回错误信息。
Redis主从复制
什么是主从复制
主从复制的作用其实可以类比于mysql的主从复制,首先有主和从,主向从复制数据,主可以有多个从,但是从只能有一个主
主从复制的原理
全量复制
- slave执行slaveo命令
- slave首先会保存master主节点信息
- 主从建立连接
- slave发送命令
- master回馈slave pong命令,表示已经收到连接
- master同步数据到slave。
这种方式使用的sync ,使用的是全量同步,当然任何事情不能只做片面,肯定是有增量同步,pync:他主要的方式是通过记录偏移量来实现主从复制
主从复制的作用
- 保存Redis数据的副本
- 读写分离,减少master压力
- 故障转移实现高可用性
Redis缓存雪崩
感觉这应该算是老生常谈的话题了吧。
首先我们应该思考的是为什么使用缓存,缓存的目的是为了减少数据库的压力,如果对于小数量的访问数据库是可以承受压力的,如果当大批量的数据访问,假如redis挂了或者可能缓存过期时间到了,访问不到数据,这个时候MySQL的压力会非常大,会出现什么问题呢?
-
1 针对于redis缓存生效问题
我们可以在code的时候,不要吧缓存过期时间写在同一时刻,怎么可以避免在同一时刻? 可以利用随机数的方式,这样减少了redis在同一时刻会缓存失效 -
针对于redis蹦了
这种事情一旦发生是无法补救的,所以我们只能 1做好预先准备利用主从复制机制实现高可用,2 redis蹦了也不完全依赖它,使用本地缓存或者spring提供的缓存再加上限流 3 事后,redis做持久化操作,利用rdb或者aof进行恢复数据。
这张图片来自Java3y公众号,写的非常不错,推荐大家去看哦~
什么是缓存穿透
首先穿透是什么意思?你可以理解为无论是在redis缓存中还是在MySQL中都是get不到数据,有的人就会想,既然没有数据就返回null不就行了吗? 按照道理来说是没有问题的, 但是总是预防突发情况,如果有人刷接口,后者黑客操作,那么这个时候会导致什么问题呢?
解决方案可以当数据库访问为null的时候设置一个空的对象到redis中,防止出现缓存穿透现象。
Redis分布式锁
首先第一个疑问应该是什么是分布式锁? 如果针对的是单机版的我们可以使用java自带的关键字,或者是java.util.condition包下AtomicInteger等类,但如果我们使用的分布式架构或者集群,这个时候应该如何处理?这就是我们常说的分布式锁。接下来我们看下Redis是如何表现为分布式锁
王雪芬-Judy领袖 发布了208 篇原创文章 · 获赞 91 · 访问量 14万+ 关注