Redis学习之:Redis的使用和优化

1.缓存的收益与成本

收益

  • 加速读写
  • 降低后端负载
    • 后端服务器通过前端缓存降低负载,业务端使用Redis降低后端MySql等数据库负载

成本

  • 数据不一致:缓存层和数据层有时间窗口不一致,和更新策略有关
  • 代码维护成本增大:多了一层缓存逻辑
  • 运维成本:例如Redis Cluster

2.缓存更新策略

  • LRU、LFU、FIFO算法剔除:例如maxmemory-policy
  • 设置过期时间:expire
  • 主动更新:开发控制生命周期

建议

  • 低一致性:最大内存和淘汰策略
  • 高一致性:超市剔除和主动更新结合,最大内存和淘汰策略兜底

3.缓存粒度控制

可以从以下三个维度考虑

  • 通用性:全量属性更好
  • 占用空间:部分属性更好
  • 代码维护:表面上全量属性更好

4.缓存穿透问题

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为0的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大

产生原因

  • 业务代码自身原因
  • 恶意攻击,爬虫等

如何发现

  • 业务的响应时间
  • 业务本身问题
  • 相关指标:总调用数、缓存层命中数、存储层命中数

解决方案

  • 缓存空对象:将查询到的null缓存到Redis中,并且设置过期时间。但这样会产生两个问题:1是需要更多的键,2是缓存层和存储层数据短期不一致(比如第一次查询数据库是null然后缓存了,第二次查询数据库已经有了但是缓存会返回null)
  • 使用布隆过滤器拦截:
    • 本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。
    • 当插入的元素越来越多时,当一个不在布隆过滤器中的元素,经过同样规则的哈希计算之后,得到的值在位数组中查询,有可能这些位置因为其他的元素先被置1了。所以布隆过滤器存在误判的情况,但是如果布隆过滤器判断某个元素不在布隆过滤器中,那么这个值就一定不在

5.缓存雪崩问题

缓存雪崩是指在某一个时间段,缓存集中过期失效,不能正常工作了。于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会挂掉的情况

产生原因及解决

  • 缓存大面积失效:避免缓存设置相近的有效期;为有效期增加随机值;统一规划有效期,失效时间均匀分布
  • 对热点数据持续高并发:使用互斥锁:jvm锁机制;分布式锁机制
  • 有效期本身的缺陷:缓存永不过期,异步更新
  • 缓存服务器宕机:使用Redis哨兵模式或者Redis集群部署方式,即便个别Redis 节点下线,整个缓存层依然可以使用

6.热点key重建

比如微博某个大v发布了一条微博,此时将会有很大量的线程进入缓存重建,给数据库或底层造成很大的压力

目标

  • 减少重新缓存的次数
  • 数据尽可能一致
  • 较少潜在的危险

解决方案

  • 互斥锁:第一个线程进入重建缓存时,加上一把锁,等工作完成后,再把锁释放。锁定期间其他线程只能等待,等缓存重建成功后,从缓存中获取
  • 永不过期:不设置过期时间expire,需要我们在程序中进行缓存的重建,重建完成之前获取到的都是旧的值
方案 优点 缺点
互斥锁 思路简单、保证一致性 代码复杂度增加、存在死锁风险
永不过期 基本杜绝热点key重建问题 不保证一致性、逻辑过期时间增加维护成本和内存成本
原文地址:https://www.cnblogs.com/xiaoqingtian/p/13669509.html