Redis学习笔记(8、缓存设计)

目录:

  • 缓存更新策略
  • 缓存粒度
  • 缓存穿透
  • 缓存雪崩
  • 缓存击穿

缓存更新策略:

一、内存溢出淘汰策略redis

当redis的使用内存超过maxmemory时会触发相应的策略,具体策略由maxmemory-policy参数控制算法

淘汰策略分为六种:缓存

)noeviction:默认策略,此策略不会删除任何数据;当客户端还进行写操做时将返回OOM(内存溢出)网络

)volatile-lru:根据LRU算法删除设置了过时时间的key,若是没有可删除的key,回退到noevication策略并发

)volatile-random:随机删除过时的keydom

)allkeys-lru:根据LRU算法从全部的key里删除分布式

)allkeys-random:随机算出全部的key函数

)volatile-ttl:根据对象ttl属性删除最近将要过时的key,若没有回退到noevication策略spa

不推荐使用noevication、allkeys-lru线程

二、过时删除

)惰性删除:redis有一个专门存储设置了过时时间的过时字典,每当客户端要访问一个key时,先回去这个过时字典里查,若已过时则返回空;但仅只有这一个删除策略的话就会致使一些长期未使用的key也占用这内存,故有了一个定时删除的策略

)定时删除:redis内部维护了一个job,默认每10秒运行一次;它会根据key的过时比例,使用快慢两种模式回收key

三、应用方删除

)先从缓存读取,获取不到读DB,而后再将DB读到的数据写入缓存

)先删缓存,再更新DB(不推荐),怕并发写操做致使脏数据

)先更新DB,再删缓存(推荐

缓存粒度:

究竟是缓存整个对象呢,仍是缓存须要的数据呢,咱们从两个方面来分析:

一、缓存整个对象

优势:通用性更好

缺点:浪费内存;网络流量大,极端状况可能会阻塞网络;序列化和反序列化的CPU开销更大

二、仅缓存须要使用的数据

优缺点与缓存整个对象偏偏相反,可是新增缓存属性时须要修改代码,并且修改后还须要刷新缓存

缓存穿透:

缓存穿透是指去访问一个根本不可能不存在的key,缓存层和持久层都不会命中,从而致使请求直接打向持久层,增长持久层的压力。

出现缓存击穿的缘由:

一、自身业务实现的问题

二、恶意攻击、爬虫等

解决方案:

一、缓存空对象

缓存空对象会有两个问题:

)占用更多的内存;缓存层会有更多的键,须要更多的内存;能够经过设置过时时间解决问题

)数据不一致;若在缓存有效期时,持久层又新增了这一条数据,便会有这一问题;能够经过MQ或其它方式清除缓存中的空对象

二、布隆过滤器

布隆过滤器其实是一个很长的二进制向量和一系列随机映射函数。布隆过滤器能够用于检索一个元素是否在一个集合中。它的优势是空间效率和查询时间都远远超过通常的算法,缺点是有必定的误识别率和删除困难。它收到一个对key请求时先用布隆过滤器验证是key否存在,若是存在在进入缓存层、存储层。

可使用bitmap作布隆过滤器;但这种方式仅适用于数据命中不高、数据相对固定、实时性低的应用场景,代码维护较为复杂;优势是缓存空间占用少。

缓存雪崩:

咱们都知道缓存层承载了大量的请求,它有效的保护了咱们的DB,但缓存层也可能由于某些状况宕机了或大量缓存在同一时间失效,这样便会致使大量请求直接到达DB,致使系统雪崩。

解决方案:

一、使用高可用的sentinel、cluster方案

二、采用多级缓存,如系统进程为一级缓存,redis做为二级缓存等等

三、缓存的过时时间随机,不要让大量缓存在同一时间失效

缓存击穿:

当一个热点key过时时,刚好有大量的并发请求到这个key,此时这些并发请求就会大量的打入DB层。

出现缓存击穿的缘由:

一、缓存中有热点key

二、重建缓存不能再短时间内完成,如复杂计算或复杂SQL

解决方案:

一、分布式互斥锁

只容许线程重建一个缓存,其余线程须要等待重建缓存的线程执行完后才能从新从缓存获取数据。

二、永不过时

从缓存层面上看:不设置热点key的过时时间

从功能层面上看:为热点key设置一个逻辑过时时间,当超过这个逻辑过时时间后,用一个单独的线程将其缓存更新

相关文章
相关标签/搜索