缓存相关问题总结-1

一. 缓存,更多的解决db的压力2个点
a, 时间窗口内重复请求
b, 绝对的并发数据访问场景

缓存旁路 cache-aside
面对的 cache-misses,就是在并发下解决方案:

  1. 分布式锁,
  2. 布隆过滤器,
  3. 必须附加过期,
  4. 热点识别
二. 双写方案:
1. 先写缓存,再写数据库
  1. 写缓存成功,数据库写入失败,缓存一致性问题;
  2. 有点违背了cache的意义,数据的就近原则。* ,不把redis作为cache, 作为store来使用。 1. 缓存数据量太大造成缓存拥挤,2. 如:商品未审核或者sort上架顺序的商品有放到缓存最前面buff
2. 先写数据库,再写缓存
  1. 数据库存储成功,但写缓存顺序容易错乱,并发场景下容易造成数据不一致的情况;
  2. 有点违背了cache的意义,数据的就近原则。
3. 先写数据库,删除缓存,带着过期时间然后写完之后然后结果

问题:

  1. 用的删除,类似于MESI的I状态,系统缓存未更新。
  2. 第二步会删除失败,redis作为cache使用, 没有这个数据,所以,删除是否失败无所谓
  3. cache 与 db,不是强制性的,看容忍度,其实也符合CAP,P是必然存在的,cache-aside属于AP。

解决方案: 因为cache-aside模型中,以上问题,由read模式补救(因为数据有过期时间),注:一定要加过期时间 -> 触发cache-messed(缓存数据找不到必然触发,缓存穿透,缓存刺破,缓存雪崩,预热等情况下也会触发)。

4. 先写数据库,canal同步(同步工具异构同步,监听数据库binlog)

概念:cache存储的一定是热点数据,read请求数据量直接体现热点数据,需要数据系统埋点统计热点数据。
问题:无法判断数据是否是热点数据,造成全量
方案1:canal -> mq(顺序消费,不做批处理) -> redis

java_cache_and_cpu_mesi (知识补充)

volatile 可见性 (无缓存性) 不经由缓存,直接写入主内存; 所以可以直接去内存。
cpu的MESI(缓存一致性)调优点:
image.png
参考文献:cache-aside
系统默认是不开启的EMSI, 缓存会存储一大批量的数据cache_line到达一定量,再给到主内存。
1.1 volatile 没有 MESI 的时候,全读场景,都会触发主内存读取。
1.2 volatile 有 MESI 的时候, 全读场景, 先去cache缓存区取没有再去主内存读取,主内存会在一定时间内去同步缓存区数据,查询将会速度大大提升。

三. redis数据安全与一致性的问题
redis建立实体模型model,可以使用db做备份,即使redis挂了也可以及时恢复备份。
> 方案1: 分布式数据库,即时存储redis内容。存在问题数据库压力大,数据相对较多碎片。

redis -> (N) DB

> 方案2: rides使用MQ,不同的task使用不同的send方,以Queue顺序的方式consumer去消费可以直接计算完结果的数据入库。减少了数据库的量,有顺序,减少碎片化数据,数据安全。

redis -> (N) mq -> (N) DB

四. reids存什么,基于cache
1. 静态的字典类,纬度类数据
> a 不要设置过期时间
> b 淘汰策略设置成基于过期策略设置成基于过期类数据的LRU/LFU(AKF原则:需要做隔离)
2. 预热,存热数据,热数据的识别思路很重要。
> a 读写扩散,选型
>> 写扩散,写完数据库,就要写redis,场景:未来一定有并发,以及修改的是静态类字典数据。(平台租户存在级别)
>> 读扩散,在cache-aside模型中,read过程出现cache-misses,注意:也要识别, redis存热数据,而热数据就是read请求访频次。
延展:如果单一的去使用某一个缓存的话:
read->def->LocalCache 存在oom问题
read->def- > Redis 虽然有LRU(淘汰机制),但是会造成redis性能下降

猜你喜欢

转载自blog.csdn.net/weixin_43869435/article/details/126563430