• java缓存


    用在:

    即时性、数据一致性要求不高

    访问量大,更新频率低的数据(读多写少)

    本地缓存只适合本地单服务处理

    分布式缓存—缓存中间件redis

    安装在Docker中

    查看工具Redis Desktop Manager

    RedisAutoConfiguration

    Redis Properties.class

    使用Template操作redis

    例如StringRedisTemplate.opsForValue set/get value timeout

    复杂对象的缓存可以使用json数据,跨平台兼容。其他语言兼容。

    堆外内存溢出

    Lettuce作为操作redis的客户端,使用netty进行网络通信

    排除lettuce

    加依赖jedis

    spring对lettuce/jedis封装为template

    缓存失效—缓存穿透

    利用不存在的数据进行攻击

    查询一次后,缓存空数据,下次查到空,空结果加入短暂的过期时间。

    缓存雪崩——多key

    大量Key采用了相同的过期时间,同一时间失效,压力到db

    过期时间加随机值(例如1-5分钟)

    缓存击穿—单key

    高并发访问某个失效的key,且数据是热点数据。

    大量请求进来时候,正好失效,都落到db上

    解决: 加锁 (判断缓存-查数据库-存缓存)

    单体服务,SpringBoot所有组件在容器中都是单例的

    方法内/方法声明加本地锁:synchrozied/lock。

    问题:分布式服务中,组件是多实例的,锁不住。

    解决:分布式锁

    使用redis set key NX。key不存在时候,才会设置。

    代码实现:setIfAbsent(“lock”,1)返回bool。

    true为加锁成功。执行后续业务、完成后删除锁

    Else 持续休眠尝试

    问题1:代码崩溃、断电等问题导致解锁失败、死锁。

    解决:增加自动过期(template.expire),自动删除失败的锁。

    问题2:占锁同时,要加过期时间。即保持原子。set lock 1 EX 300 NX

    代码实现:setIfAbsent(“lock”,1,expire)

    问题3:业务执行代码过久,大于expire,锁被误删除(并发时删掉其他人锁)。

    解决:增加UUID。删除锁时,使用脚本,不使用DEL

    框架实现:Redssion

    RedssionConfig {

    }

    操作RedissonClient redisson()

    内容:分布式对象,分布式集合,

    分布式锁RLock,同名同锁

    Lock.Lock()看门狗自动续期,默认30s过期时间

    Lock.lock(leastime:10)不会自动续期,其他人可占,不可删。会异常。

    自动解锁时间,一定要大于业务执行时间。

    分布式锁的缓存一致性

    1、双写模式——脏数据、加锁、允许临时不一致——最终一致

    2、失效模式—

    解决方案:

    缓存数据+过期时间,解决大部分缓存需求。

    加读写锁

    canal订阅binlog

    直接写逻辑复杂

    使用springCache,直接加注解

    CacheManager兼容各类缓存,Redis、ConcurrentHashMap

    实施:

    引入依赖

    写配置(自动配置好了RedisCacheManager)

    spring.cache开头,spring.cache.type=redis

    使用注解

    @Cacheable 触发将数据保存到缓存

    @CacheEvict 删除(失效模式)

    @CachePut不影响方法执行 更新缓存(双写模式)

    @Caching 组合多个缓存操作

    @CacheConfig 类级别共享缓存配置

    获取:

    @Cacheable() 注解到方法上,代表方法的结果需要缓存,如果缓存中有,方法不调用

    自定义key(SpEl表达式)、时间、数据保存json

    更新:

    @Caching(evict = { })

    @CacheEvict() //失效模式

    @CachePut //双写模式

    常规数据,读多写少,实时性一致性要求不高的数据,直接使用Spring-Cache

    问题解决:

    缓存穿透:cache-null-values=true

    缓存击穿:加锁? 读写加锁(默认无锁,syn=true,get方法加锁)、canal感知mysql更新数据库、读多写多的直接操作数据库

    缓存雪崩:因为开始缓存已经不一致,加上过期时间即可

    特殊数据:特殊设计

    各个微服务 properties中配置相同redis host port

  • 相关阅读:
    人生苦短,我用JRebel
    (vue)el-descriptions 描述列表无效
    mipi phy理解
    tcp_v4_connect函数的解析
    07.自定义指令传参小窍门
    大模型赛道如何实现华丽的弯道超车【赠书活动|第十期《分布式统一大数据虚拟文件系统 Alluxio原理、技术与实践》】
    day1-机器学习-回归问题
    【Java】泛型 之 什么是泛型
    数据量太大了,数据分批处理
    HTML中的语义化标签
  • 原文地址:https://blog.csdn.net/zhangbinHn/article/details/126583349