缓存的使用模式

2022-10-25 15:47:51 浏览数 (2)

缓存使用模式分为两大类:Cache-Aside和Cache As SoR 专业名词:

  • SoR(system-of-record):记录系统,或者可以叫数据源,实际存储原始数据的系统
  • Cache:缓存,是SoR的快照数据,Cache的访问速度比SoR要快,放入Cache的目的是提升系统速度,减少回源到SoR的次数
  • 回源:回到数据源头检索数据,Cache没有命中需要回到SoR读取数据,这叫做回源

1)、Cache-Aside

Cache-Aside:即业务代码围绕Cache编写,由业务代码维护缓存; 如:

读场景

data = cache.getIfPresent(key); if(data == null){ data = loadFromSoR(key); cache.put(key,data) } 先从缓存中获取,没有查询SoR,再放入缓存

写场景(主动更新和删除时被动读取)
  1. 双写模式 //1、先将数据写入SoR writeToSoR(k,v); //2、执行成功后立即同步写入缓存 cache.put(k,v) 或者
  2. 失效模式 //1、先将数据写入SoR writeToSoR(k,v); //2、失效缓存,下次读取时从缓存中加载(进入读场景), cache.invalidate(k);

并发更新问题与解决(多个缓存实例,同时更新自己里面的同样数据) 1、考虑使用中间件如Canal订阅binlog,进行增量更新分布式缓存,不会存在缓存数据不一致问题。但是会有延迟,我们可以调整合理的过期时间来容忍这个延迟 2、读服务,可以考虑一致性哈希,相同的操作负载均衡到同一个实例,从而减少并发几率。

2)、Cache-As-SoR

即把Cache当做SoR,所有操作都是对Cache进行,然后Cache委托SoR进行数据的真实读写。即业务代码只看到Cache的操作,看不到关于SoR的代码;三种实现模式:read-through、 write-through、write-behind

  1. read-through 业务代码首先调用Cache,Cache不命中,由Cache回源到SoR(类似回调的方式或者Cache配置的方式),而不是业务代码。【Guava、Ehcache均支持这种模式】 优点:业务代码整洁
  2. write-through 称为穿透写模式/直写模式。业务代码调用Cache写数据,然后由Cache负责写缓存和写SoR,而不是业务代码。
  3. write-behind 也叫write-back;回写模式。不同于write-through的是,write-through是同步写,而write-back是异步写,异步成功后可以实现批量写、合并写、延时写等

3)、Copy-Pattern

应用级缓存:(数据一定不能是脏数据)【Map、Ehcache、Guava】 Mybatis:二级缓存Map if(map.get(1)){ return obj; }else{ queryFromDb } obj = cache; 缓存读取来的数据是否是改写安全; obj = cache; obj2 = new Obj(); BeanUtils.copyProperties(obj,obj2) obj2.compute(); //写时复制 obj = ObjHaha(); obj2 = new Obj(); BeanUtils.copyProperties(obj,obj2) map.put(k, obj2); obj.compute(); 分布式缓存:

缓存使用两种复制模式,注意。Copy-On-Read(读时复制)、Copy-On-Write(写时复制)。 有些进程内缓存很多是基于引用的,所以拿到缓存中的数据如果进行修改,可能发生不可预测的问题。 读时复制:读取到的缓存的值,复制内容封装一个新的对象。 写时复制:给缓存中写的值,复制一个新的对象写入

0 人点赞