推广公司属于什么公司,厦门网站快速排名优化,网站页面布局名称,设计wordpress主题文章目录1、什么是缓存击穿#xff1f;该如何解决2、什么是缓存穿透#xff1f;该如何解决3、什么是缓存雪崩#xff1f;该如何解决4、什么是BigKey#xff1f;该如何解决bigkey的危害发现bigkey解决bigkey5、redis过期策略都有哪些#xff1f;6、讲一讲Redis缓存的数据一…
文章目录1、什么是缓存击穿该如何解决2、什么是缓存穿透该如何解决3、什么是缓存雪崩该如何解决4、什么是BigKey该如何解决bigkey的危害发现bigkey解决bigkey5、redis过期策略都有哪些6、讲一讲Redis缓存的数据一致性问题和处理方案1、什么是缓存击穿该如何解决
缓存击穿是指一个热点的Key在某个瞬间过期失效了持续的并发请求在缓存获取不到数据后直接请求数据库的现象。
如何解决
使用互斥锁 在缓存失效的时候判断拿出来的值为空不是立即去load db而是先去设置一个互斥锁比如Redis的SETNX当获取到锁再进行load db的操作并回设缓存否则就重试获取缓存的方法。 伪代码如下图 永远不过期
不设置过期时间就保证了不会出现热点key过期问题也就是“物理”不过期。我们把过期时间存在key对应的value里如果发现要过期了通过一个后台的异步线程进行缓存的构建。
2、什么是缓存穿透该如何解决
缓存穿透是指查询一个根本不存在的数据缓存层和存储层都不会命中每次请求都要到存储层去查询失去了缓存保护后端存储的意义。
造成缓存穿透的基本原因有两个
自身业务代码或者数据出现问题。一些恶意攻击、爬虫等造成大量空命中。 如何解决
缓存空对象
当存储层不命中到数据库查发现也没有命中那么设置空值到缓存层中。不过空值做了缓存意味着缓存层中存了更多的键需要更多的内存空间比较有效的方法是针对这类数据设置一个较短的过期时间让其自动剔除。
布隆过滤器拦截
在访问缓存层和存储层之前将存在的key用布隆过滤器提前保存起来做第一层拦截。如果布隆过滤器认为该用户id不存在,那么就不会访问存储层,在一定程度保护了存储层。 这种方法适用于数据命中不高、数据相对固定、实时性低(通常是数据集较大)的应用场景代码维护较为复杂,但是缓存空间占用少。
3、什么是缓存雪崩该如何解决
缓存雪崩的英文原意是stampeding herd(奔逃的野牛)指的是缓存层宕掉后流量会像奔逃的野牛一样打向存储。 缓存层由于某些原因不能提供服务比如同一时间缓存数据大面积失效所有的请求都会达到存储层存储层的调用量会暴增造成级联宕机的情况。
如何解决
保证缓存层服务高可用性。依赖隔离组件为后端限流并降级。将缓存失效时间分散开降低缓存过期时间的重复率。
4、什么是BigKey该如何解决
bigkey是指key对应的value所占的内存空间比较大例如一个字符串类型的value可以最大存到512MB一个列表类型的value最多可以存储23-1个元素。
bigkey的危害
内存空间不均匀在Redis Cluster中bigkey 会造成节点的内存空间使用不均匀。超时阻塞由于Redis单线程的特性操作bigkey比较耗时也就意味着阻塞Redis可能性增大。网络拥塞每次获取bigkey产生的网络流量较大
假设一个bigkey为1MB每秒访问量为1000那么每秒产生1000MB 的流量,对于普通的千兆网卡(按照字节算是128MB/s)的服务器来说简直是灭顶之灾。
发现bigkey
redis-cli --bigkeys可以命令统计bigkey的分布。 但是在生产环境中开发和运维人员更希望自己可以定义bigkey的大小而且更希望找到真正的bigkey都有哪些这样才可以去定位、解决、优化问题。
判断一个key是否为bigkey只需要执行debug object key查看serializedlength属性即可它表示 key对应的value序列化之后的字节数。 解决bigkey
主要思路为拆分对 big key 存储的数据 big value进行拆分变成value1value2… valueN等等。
例如big value 是个大list可以拆成将list拆成。 list_1 list_2, list3, …listN
5、redis过期策略都有哪些
当 Redis 内存超出物理内存限制时内存的数据会开始和磁盘产生频繁的交换 (swap)。交换会让 Redis 的性能急剧下降对于访问量比较频繁的 Redis 来说这样龟速的存取效率基本上等于不可用。
在生产环境中我们是不允许 Redis 出现交换行为的为了限制最大使用内存Redis 提供了配置参数 maxmemory 来限制内存超出期望大小。
当实际内存超出 maxmemory 时Redis 提供了几种可选策略(maxmemory-policy) 来让用户自己决定该如何腾出新的空间以继续提供读写服务。 noeviction 不会继续服务写请求DEL请求可以继续服务读请求可以继续进行。这样可以保证不会丢失数据但是会让线上的业务不能持续进行。这是默认的淘汰策略。
volatile-lru 淘汰设置了过期时间的key最少使用的key优先被淘汰。
volatile-ttl 淘汰设置了过期时间的key过期时间最接近的key优先被淘汰。
volatile-random 淘汰设置了过期时间的key随机选择一个key。
allkeys-lru 所有的 key 中最少使用的key优先被淘汰。
allkeys-random 所有的 key 中淘汰随机的 key。
6、讲一讲Redis缓存的数据一致性问题和处理方案
只要使用到缓存无论是本地内存做缓存还是使用 redis 做缓存那么就会存在数据同步的问题。通常有以下几种同步方法 先更新缓存再更新数据库 这个方案我们一般不考虑。这种方案如果不处理好比如更新数据库失败之后没有回滚缓存就会拿到错误的值。 先更新数据库再更新缓存 这个方案也我们一般不考虑原因跟第一个一样数据库更新成功了缓存更新失败同样会出现数据不一致问题。同时还有以下问题 并发问题同时有请求A和请求B进行更新操作那么可能会出现 1线程A更新了数据库 2 线程B更新了数据库 3 线程B更新了缓存 4 线程A更新了缓存 这样会因为缓存更新顺序问题造成脏数据的产生。 业务场景问题如果是一个写数据库场景比较多而读数据场景比较少的业务需求采用这种方案就会导致数据压根还没读到缓存就被频繁的更新浪费性能。 先删除缓存后更新数据库 该方案也会出问题具体出现的原因如下。 1此时来了两个请求请求 A更新操作 和请求 B查询操作 2 请求 A 会先删除 Redis 中的数据然后去数据库进行更新操作 3此时请求 B 看到 Redis 中的数据时空的会去数据库中查询该值但是此时请求 A 并没有更新成功得到旧值补录到 Redis 中 利用延时双删策略解决这一问题是在更新数据库后睡眠一会将B写的脏数据再次删除伪代码如下 redis.delKey(X)db.update(X)Thread.sleep(N)redis.delKey(X)先更新数据库后删除缓存 这种方式被称为Cache Aside Pattern读的时候先读缓存缓存没有的话就读数据库然后取出数据后放入缓存同时返回响应。更新的时候先更新数据库然后再删除缓存。
一般情况下我们可能会先用先更新DB后删除缓存的操作。因为这种情况下缓存不一致性的情况只有可能是查询比删除慢的情况而这种情况相对来说会少很多。