redis相关面试题

1、Redis的高并发和快速原因?你为什么选择redis?Redis跟其他缓存相比,优势在哪里?

1.redis是基于内存的,内存的读写速度非常快;
2.redis是单线程的,省去了很多上下文切换线程的时间;
3.redis使用I/O多路复用技术,可以处理并发的连接。(客户端的连接不占用线程资源,只有当命令成功发送的时候,才会进入单线程,然后依次执行)
解释:多路——多个scoket、多个客户端、多个黑窗口
复用:复用那一个线程

在这里插入图片描述

2、为什么Redis是单线程的

1.官方答案
因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络宽带。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。
2单线程避免了上下文切换,节约时间

3、 Redis单线程的优劣势

1)单进程单线程优势:
代码更清晰,处理逻辑更简单
2)单进程单线程弊端:
无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善。

4、redis中的数据类型有哪些?

1 String:字符串类型,一个key对应一个值,可以存储任何内容,图片、视频都行,但是大小限制在512m以内
2 List:单键多值,值可以重复
3 set:单键多值,值不可以重复
4 Hash:key后面跟field属性,从而确定一个值
5 zSet:单键多值,有序不重复集合,可以自动排序

5、跳表的原理是什么?

跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。跳表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找。跳表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能。 redis的zset类型的底层就是用了这种数据结构

6.redis关键命令

Redis key
1.exists key判断某个key是否存在
2.expire key 10 10秒钟:为给定的key设置过期时间

String
1.setnx key value :只有在key不存在的时候设置key的值
常用来做分布式锁
2.incrby / decrby <步长>将 key 中储存的数字值增减。自定义步长

Incr和decr是原子操作,java的i++是原子操作吗?不是
i=0;两个线程分别对i进行++100次,值是多少?2-200

List
1.lpop/rpop 从左边/右边吐出一个值。值在键在,值光键亡。
2.lrange 根据范围取值
3.lpush/rpush存值

Set
1.sadd …
将一个或多个 member 元素加入到集合 key 中,已经存在的 member 元素将被忽略
2.smembers 根据范围取值
3.set类型数据的扩展操作
sinter 返回两个集合的交集元素。
sunion 返回两个集合的并集元素。
sdiff 返回两个集合的差集元素(key1中的,不包含key2中的)

Hash
1.hset 给集合中的 键赋值
2.hget 从集合取出 value
3.hexists 查看哈希表 key 中,给定域 field 是否存在。

Zset
1.zrangebyscore key minmax [withscores] [limit offset count]返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。
2…zrevrangebyscore key maxmin [withscores] [limit offset count] 同上,改为从大到小排列。
3.zincrby 为元素的score加上增量
4.zcount 统计该集合,分数区间内的元素个数

7.持久化方式有哪些?有什么区别?

redis持久化方案分为RDB和AOF两种。
RDB:
RDB持久化可以手动执行也可以根据配置定期执行,它的作用是将某个时间点上的内存中的数据保存到RDB文件中,RDB文件是一个压缩的二进制文件,通过它可以还原数据。由于RDB文件是保存在硬盘上的,所以即使redis崩溃或者退出,只要RDB文件存在,就可以用它来恢复数据。

可以通过save或者bgsave来生成RDB文件。
SAVE命令会阻塞redis进程,直到RDB文件生成完毕,在进程阻塞期间,redis不能处理任何命令请求,这显然是不合适的。
BGSAVE则是会创建一个子进程,然后由子进程去负责生成RDB文件,父进程还可以继续处理命令请求,不会阻塞进程。
AOF:
AOF和RDB不同,AOF保存的是命令,将写的命令保存起来。
AOF通过追加、写入、同步三个步骤来实现持久化机制。

1.当AOF持久化处于激活状态,服务器执行完写命令之后,写命令将会被追加aof缓冲区的末尾
2.在服务器结束一个事件之前,将会调用flushAppendOnlyFile函数决定是否要将aof缓冲区的内容保存到AOF文件中,可以通过配置appendfsync来决定。
配置如下:

always实时同步
everysec每秒同步
no同步时间由操作系统决定

默认选项将会是everysec,每秒同步

8.了解Redis事务机制吗?

redis通过MULTI、EXEC、WATCH等命令来实现事务机制,事务执行过程将多个命令按照顺序一次性执行,并且在执行期间,事务不会被中断,也不会去执行客户端的其他请求,直到所有命令执行完毕。事务的执行过程如下:

1事务以MULTI开始
2.如果客户端正处于事务状态,则会把执行命令放入队列,并且返回给客户端QUEUED,反之则直接执行这个命令
3.当服务器收到客户端的EXEC命令时,WATCH命令监视整个事务中的key是否有被修改,如果有则返回空,表示失败,否则redis会遍历整个事务队列,执行队列中的所有命令,最后返回结果给客户端

9.什么是悲观锁?什么是乐观锁?

(redis、mysql、oracle、mybatis-plus)

悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会等待,直到拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set机制实现事务的。

10.主从复制的原理:

1)当从服务器连接上主服务器之后,从服务器就会向主服务器发送一个sync命令进行数据同步操作
2)主服务器接到从服务器发过来的同步命令,先将主服务器数据进行持久化,生成rdb文件,然后把rdb文件发送给从服务器,从服务器拿到rdb进行读取,完成复制
3)每次主服务器进行写操作之后,和从服务器进行数据同步
4)全量复制:从机第一次连接主机,主机所有的数据将会同步给从机。
5)增量复制:主机继续将新的数据依次传给从机
6)但是只要是重新连接主机(从机发出slaveof命令),全量复制都会自动执行
在这里插入图片描述

11. 主从复制的三种方式:

方式一:一主多从(N个从机直接跟随主机)
方式二:薪火相传 (从机可以作为其他机器的主机)
方式三:反客为主 (主机宕机 ,从机可以通过slaveof no one 变成主机)

12 什么是哨兵机制?哨兵机制的工作原理是什么?

主从架构中,主机宕机,从机无法自动上位,需要手动上位,而哨兵机制就是自动上位
在这里插入图片描述
1.基于主从方案的缺点还是很明显的,假设主机宕机,那么就不能写入数据,那么从机也就失去了作用,整个架构就不可用了,除非你手动切换,主要原因就是没有自动故障转移机制。而哨兵具备自动故障转移、集群监控、消息通知等功能。
2.哨兵可以同时监视多个主从服务器,并且在被监视的主机下线时,自动将某个从机提升为主机,然后由新的主机继续接收命令。
3.哨兵会每隔1秒向所有实例(包括主从服务器和其他哨兵)发送ping命令,并且根据回复判断是否已经下线,这种方式叫做主观下线。当判断为主观下线时,就会向其他监视的哨兵询问,如果超过半数的投票认为已经是下线状态,则会标记为客观下线状态,同时触发故障转移。

13.知道什么是热key吗?热key问题怎么解决?

所谓热key问题就是,突然有几十万的请求去访问redis上的某个特定key,那么这样会造成流量过于集中,达到物理网卡上限,从而导致服务器宕机。
在这里插入图片描述

针对热key的解决方案:

1.提前把热key打散到不同的服务器,降低压力
2.加入二级缓存,提前把热key加载到二级缓存中,如果redis宕机,走二级缓存查询

14.什么是缓存击穿、缓存穿透、缓存雪崩?

(1)缓存穿透:

缓存穿透是指查询内存和数据库都不存在的数据,每次请求都会打到数据库上,从而压垮数据库。
解决方案:
1、 缓存null:根据id=30000去数据可查找user,user=null,也将user=null放到redis中
2、 使用布隆过滤器:是一种数据结构,判断值肯定不存在或者可能存在
准备一个足够长的数组,将值存入数据库的时候,同时将key存入布隆过滤器
查找key的时候,先去布隆过滤器中获取这个key的三个hash值,在根据hash值去布隆过滤器中获取值,三个值中有一个0,代表数据肯定不存在,如果三个值都是1,代表可能存在,再去数据库查找数据,针对这个问题,加一层布隆过滤器。布隆过滤器的原理是在你存入数据的时候,会通过散列函数将它映射为一个位数组中的K个点,同时把他们置为1。
这样当用户再次来查询A,而A在布隆过滤器值为0,直接返回,就不会产生击穿请求打到DB了。显然,使用布隆过滤器之后会有一个问题就是误判,因为它本身是一个数组,可能会有多个值落到同一个位置,那么理论上来说只要我们的数组长度够长,误判的概率就会越低,这种问题就可以在一定程度上得到解决。

(2)缓存击穿:

redis中不存在这个key,数据库中存在,key在redis中过期了,当大量请 求过来的时候,请求会直接打到数据库上,引起数据库崩溃
解决方案:a.加锁:操作数据库的时候加锁
B.当某一个请求去数据库查询的时候,同时在redis中将值设为null,待他 从数据库查到数据返回后,设置具体的值

(3)缓存雪崩:

(3)redis中不存在这些key,数据库中存在,这些key在某一时间集中过期了, 当大量请求过来的时候,请求会直接打到数据库上,引起数据库崩溃
解决方案:a.加锁
C.多级缓存
D.设置key 的不同的过期时间,比如固定的过期时间上在随机1-10分钟

15.Redis的过期策略有哪些?

redis主要有2种过期删除策略
惰性删除
惰性删除指的是当我们查询key的时候才对key进行检测,如果已经达到过期时间,则删除。显然,他有一个缺点就是如果这些过期的key没有被访问,那么他就一直无法被删除,而且一直占用内存。
在这里插入图片描述
定期删除
定期删除指的是redis每隔一段时间对数据库做一次检查,删除里面的过期key。由于不可能对所有key去做轮询来删除,所以redis会每次随机取一些key去做检查和删除。

16.那么定期+惰性都没有删除过期的key怎么办?

假设redis每次定期随机查询key的时候没有删掉,这些key也没有做查询的话,就会导致这些key一直保存在redis里面无法被删除,这时候就会走到redis的内存淘汰机制。
1.volatile-lru:从已设置过期时间的key中,移出最近最少使用的key进行淘汰
2.volatile-ttl:从已设置过期时间的key中,移出将要过期的key
3.volatile-random:从已设置过期时间的key中随机选择key淘汰
4.allkeys-lru:从key中选择最近最少使用的进行淘汰
5.allkeys-random:从key中随机选择key进行淘汰
6.noeviction:当内存达到阈值的时候,新写入操作报错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值