缓存的使用模式

缓存使用模式分为两大类: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(写时复制)。
有些进程内缓存很多是基于引用的,所以拿到缓存中的数据如果进行修改,可能发生不可预测的问题。
读时复制:读取到的缓存的值,复制内容封装一个新的对象。
写时复制:给缓存中写的值,复制一个新的对象写入

你可能感兴趣的:(redis)