缓存使用建议

缓存问题

  • 缓存穿透

高并发访问数据库不存在的值,导致缓存失效
解决: 给无结果的key缓存 标志位表示无值(0,1 之类的),并添加短期失效时间

  • 缓存雪崩

高并发访问时,正好大批量的key失效
解决:添加失效时间间隔值

– 缓存击穿

对于热点key突然失效时的高并发访问
解决:加锁

Redis 分布式锁

  • 使用redis setnx 实现的一种分布式锁, 必须保证加锁解锁的原子性

场景:

  • 使用redis 的 setnx 时候, 需要设置过期时间,但是过期时间设置时候闪断怎么办?
    • 让设置值的命令和设置过期时间的命令在同一次操作中实现, setnx key value ex xx
  • A线程删了B线程的锁怎么办?
    • 回查当前redis种占用锁的线程id(set时候当value传入了),与当线程对比后再删
  • 问题2中,如果代码执行到匹配正确然后要删锁时,锁过期了并且同时被其他线程抢到了,这时候又删到了别人的key
    • 使用redis 脚本来执行删key操作, 脚本实际时比对当前value和传入的value是否一直,是才值删锁。
    if redis.call("get",KEY[1]) == ARGV[1]
    then
    	return redis.call("del",KEY[1])
    else
    	return 0
    end
    
  • 如果业务执行时间长,锁先过期了,如何设计这个锁续期呢
    • 简单处理是将过期时间延长,必须执行手动删锁。
    • 详细可以看redisson中的自动续期 (如果设置了过期时间,看门狗失效)

redisson

  • 读写锁 (redis中有记录)

    • 写 + 读: 等写结束才能读
    • 写 + 写: 阻塞
    • 读 + 写: 有读锁,写锁需要等
    • 读 + 读: 无锁模式
  • countdown latch

    • 门闩锁: 用于某个特定业务必须多个业务必须都操作完才能执行
  • 信号量锁

    • 信号量锁:用于控制某个业务执行的次数,如停车场车位,入库则减1,但校验时候需要判断有无信号量了。
    • 也可用为限流工具

缓存一致性问题

  • 双写

    • 改完数据库,改缓存
    • 问题: ABA问题(A线程写完时,B线程把旧数据又放入缓存了))
    • 解决:加读写锁,或者业务允许 可以考虑过期时间 -> 最终一致性
  • 失效模式

    • 改完数据库,删除缓存
    • 问题: ABA问题(在A线程删除缓存时,B线程把旧数据又放入缓存了)
    • 解决:加读写锁,或者业务允许 可以考虑过期时间 -> 最终一致性
  • 最终解决方案

    • 常用并且一致性要求高的数据,可以直接使用数据库
    • 如果使用canal订阅binlog,canal会伪装成从库,然后把数据更新到redis,业务代码就可以不处理更新redis逻辑了。 (又引入了中间件)
    • 延时双删

spring-cache

  • 默认用本地map当成缓存
  • redis (CacheAutoConfiguration -> RedisCacheConfiguration -> RedisCacheManger -> 初始化所有缓存)
    • 使用redis时,需要在配置中申明使用redis做缓存
    • 开启缓存功能 @EnableCaching
    • @Cacheable // 缓存当前结果,下次执行会先找缓存
      • names: 存入的分区
      • key: redis中的key,使用"‘xxx’" -> 默认不加’'会去解析成SEPL语言
    • @CacheEvict // 删除缓存数据
      • value: 分区名称
      • key: redis的key
      • allEntries: true时 删除分区所有数据
    • @Caching // 多个缓存操作
      • evict: @CacheEvict 集合
    • ttl设置:只能配置文件中设置全局 (ms单位)
    • 自定义序列化:默认是jdk序列化,不友好
      • 注入一个自定义配置的 RedisCacheConfiguration
      • 使用了自定义的,配置文件的就失效了,不过可以从容器中获取再注入
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值