常用操作
缓存使用问题
缓存雪崩
缓存失效时间接近,同时有大并发量的请求,直接把db打挂了
解决办法:1. 每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效;2. 如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题;3. 设置热点数据永远不过期,有更新操作就更新缓存就好了
缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户(攻击者)不断发起请求,
**解决办法:**1. 参数校验;2. 布隆滤波;3. 布谷鸟滤波;4. 从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应Key的Value对写为null、位置错误、稍后重试这样的值
缓存击穿
某个热点数据失效了,大量请求打到DB上
**解决办法:**1. 设置热点数据永远不过期;2. 加上互斥锁,使得访问变成串行,有可能会使效率变慢
高可用问题
主从模式
一主N从,主节点负责写入,从节点可以读取,从节点从主节点负责和同步信息。相关问题:同步策略
sentinel
见往期文章
集群模式
待补充
持久化
见往期文章
分布式锁
当高并发访问某个接口的时候,如果这个接口访问的数据库中的资源,并且你的数据库事务级别是可重复读(Repeatable read)的话,确实是没有线程问题的,因为数据库锁的级别就够了;但是如果这个接口需要访问一个静态变量、静态代码块、全局缓存的中的资源或者redis中的资源的时候,就会出现线程安全的问题。
加锁机制
线程去获取锁,获取成功: 执行lua脚本,保存数据到redis数据库。
线程去获取锁,获取失败: 一直通过while循环尝试获取锁,获取成功后,执行lua脚本,保存数据到redis数据库。
监视器看门狗
它的作用就是一个线程获得锁后,突然服务器宕机了,那么这个时候在一定时间后这个锁会自动释放,你也可以设置锁的有效时间(不设置默认30秒),这样的目的主要是防止死锁的发生。
可重入加锁机制
Redisson可以实现可重入加锁机制的原因,跟两点有关:
1、Redis存储锁的数据类型是 Hash类型
2、利用Hash结构作为储存单元,将业务指定的名称作为key,将随机UUID和线程ID作为field,最后将加锁的次数作为value来储存。同时UUID作为锁的实例变量保存在客户端。将UUID和线程ID作为标签在运行多个线程同时使用同一个锁的实例时,仍然保证了操作的独立性,满足了线程安全的要求
基本的KV、DB读写模式
最经典的缓存+数据库读写的模式,就是 Cache Aside Pattern
- 读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
- 更新的时候,先更新数据库,然后再删除缓存。
为什么是删除缓存:可能更新了某个表的一个字段,然后其对应的缓存,是需要查询另外两个表的数据并进行运算,才能计算出缓存最新的值的。
布隆滤波器
布隆过滤器的原理是,当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。
**问题:**查询性能弱、空间利用效率低、不支持反向操作(删除)以及不支持计数。
布谷鸟过滤器
以后面试问道再补充吧