1 为什么要使用redis?
主要从“高性能”和“高并发”这两点来看待这个问题
- 并发能力强:mysql的并发能力是最多支持150个连接(默认),redis读支持10w-15w次/秒,写支持8w-10w次/秒
- 速度快,因为redis直接内存作为存储媒介,速度快
2 redis为什么这么快?
-
完全基于内存,绝大部分操作也都是纯粹的内存操作,非常快速 -
采用单线程+多路IO复用技术,因为单线程,避免了上下文切换的时间,同时也避免了多线程的资源争抢,避免了死锁的发生,所以快 多路:多个socket、多个客户端、多个黑窗口 ? 复用:复用那一个线程 -
数据结构简单,对数据的操作也非常简单(与关系型数据库对比)
3 Reids中有哪些数据类型?各自的特点是啥?
? 1 String:字符串类型,一个key对应一个值,可以存储任何内容,图片、视频都行,但是大小限制在512m以内
? 2 List:单键多值,值可以重
? 3 set:单键多值,值不可以重复
? 4 Hash:key后面跟field属性,从而确定一个值
? 5 zSet:单键多值,有序不重复集合,可以自动排序
4 Redis的使用场景?你在项目的哪些地方使用过redis?
-
计数器:可以对 String 进行自增自减运算,从而实现计数器功能。Redis 这种内存型数据库的读写性能非常高,很适合存储频繁读写的计数量。 -
缓存:将热点数据放到内存中,设置内存的最大使用量以及淘汰策略来保证缓存的命中率。 -
消息队列(发布/订阅功能):List 是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息。不过最好使用 Kafka、RabbitMQ 等消息中间件。 -
分布式锁实现:在分布式场景下,无法使用单机环境下的锁来对多个节点上的进程进行同步。可以使用 Redis 自带的 SETNX 命令实现分布式锁。 -
计数器:探花交友,给mongoDB的表生成自动增长的数字 -
缓存:探花交友,推荐好友列表、推荐动态列表、推荐视频列表,权限认证的验证码等等 -
消息队列:集信达项目,将发送短信的任务丢进redis的队列中,消费者从redis的队列中取出任务,发送短信 -
分布式锁:秒杀项目,防止超卖
5 什么是redis的持久化?
? 持久化就是把内存中的数据写到磁盘上,防止服务宕机了内存数据丢失。
6 redis的持久化机制是什么?各自的优缺点是啥?
? redis提供两种持久化机制:RDB(默认)和AOF
always | 实时同步 |
---|
everysec | 每秒同步 | no | 同步时间由操作系统决定 |
默认选项将会是everysec,每秒同步
? AOF的缺点:因为恢复需要重新执行命令,可能会执行很多冗余的命令,造成效率低下
- RDB和AOF比较
- RDB持久化的是数据,而AOF持久化的是命令
- AOF文件的更新频率高于RDB的更新频率
- AOF的数据安全性更好,不容易丢失数据
- RDB的性能比AOF好
- 如果两个都配置了,优先加载AOF
?
?
7 Redis的过期键的删除策略是啥?
redis主要有2种过期删除策略
惰性删除指的是当我们查询key的时候才对key进行检测,如果已经达到过期时间,则删除。显然,他有一个缺点就是如果这些过期的key没有被访问,那么他就一直无法被删除,而且一直占用内存。
定期删除指的是redis每隔一段时间对数据库做一次检查,删除里面的过期key。由于不可能对所有key去做轮询来删除,所以redis会每次随机取一些key去做检查和删除。
8 什么是哨兵模式?
主从架构中,主机宕机,从机无法自动上位,需要手动上位,而哨兵机制就是自动上位
1.基于主从方案的缺点还是很明显的,假设主机宕机,那么就不能写入数据,那么从机也就失去了作用,整个架构就不可用了,除非你手动切换,主要原因就是没有自动故障转移机制。而哨兵具备自动故障转移、集群监控、消息通知等功能。
2.哨兵可以同时监视多个主从服务器,并且在被监视的主机下线时,自动将某个从机提升为主机,然后由新的主机继续接收命令。
3.哨兵会每隔1秒向所有实例(包括主从服务器和其他哨兵)发送ping命令,并且根据回复判断是否已经下线,这种方式叫做主观下线。当判断为主观下线时,就会向其他监视的哨兵询问,如果超过半数的投票认为已经是下线状态,则会标记为客观下线状态,同时触发故障转移。
9 缓存雪崩是什么?解决方案?
10 缓存穿透?解决方案?
11 缓存击穿?解决方案?
- 缓存击穿:redis中不存在这个key,数据库中存在,key在redis中过期了,当大量请求过来的时候,请求会直接打到数据库上,引起数据库崩溃
- 解决方案:
- 加锁:操作数据库的时候加锁
- 当某一个请求去数据库查询的时候,同时在redis中将值设为null,待他从数据库查到数据返回后,设置具体的值
12 如何保证缓存与数据库双写是的数据一致性?双写不一致肯定会发生
? 你只要使用缓存,使用数据库,就会发生双写不一致的问题!如何解决呢?
? 采用延时双删策略
13 分布式锁Redission执行原理
-
原理 -
为什么要使用lua语言 因为一大堆复杂的业务逻辑,可以通过封装在lua脚本中发送给redis,保证这段复杂业务逻辑执行的原子性 -
为什么要设置锁的过期时间? Redis分布式锁,一旦客户端没有释放锁,服务端就会一直持有这个锁的,其他进程中的线程是获取不了锁的,从而出现死锁。 比如以下这两种情况: 1.网络抖动 进程A中的一个线程获取到了锁,然后执行finally中的释放锁的代码时,由程序到Redis的网络不好了,所以释放锁失败。此时对于redis服务端来说,它可不知道客户端曾经试图释放过锁,它会一直把锁给A,如此一来,其他进程的线程再也不能获取到这个锁了。 如果用设置过期时间的方式,即使客户端和服务端的网络不通了,服务端依然在进行时间的计算,时间到了直接把锁释放掉,等网络通了,不影响获取锁。 2.服务端宕机 进程A获取到了锁,Redis服务器宕机了,所以锁没有释放。等到Redis再次恢复的时候,Redis服务端还会保持这这个锁给到A,就会锁死。 如果是设置了过期时间的话,服务器恢复后就会继续倒计时,时间到了服务器自动把锁释放。 -
看门狗策略是啥? 1、客户端1加锁的默认生存时间是30秒,如果超过了30秒,客户端1还想一直持有这把锁,怎么办呢? Redisson中客户端1一旦加锁成功,就会启动一个watch dog看门狗,他是一个后台线程,会每隔10秒检查一下,如果客户端1还持有锁key,那么就会不断的延长锁key的生存时间。 2、如果负责存储这个分布式锁的Redission节点宕机后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态,为了避免这种情况的发生,Redisson提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的续期时间是30s,也可以通过修改Config.lockWatchdogTimeout来另行指定。
|