04-三高项目-缓存设计

04-三高项目-缓存设计
 
 

三高项目-缓存设计

分流、并发

导流:将原本复杂操作的请求,引导到简单的操作上。以后再来查,不需要经过复杂的计算。

成本:空间,收益:节省了时间。

不要以为仅仅是 redis,map等。

对应。kv值。

1计算k,2 查询k,3 得到值,做转换。

如果能做好对应,最好,做不好对应呢? 命中率。没有命中的缓存,查原数据。

数据的查询时间:时间(123)+(1-命中率p)*查原数据的时间。

命中率=缓存中能查到的数据/数据库总数据

如何 提升缓存的收益:

减少 123时间。

提高命中率(*)。

应用场景:

读多写少用缓存。

查询原数据时间特别长的场景。

Key

键K有关

生成时间

不同功能业务的,key值要不一样,否则会被覆盖。

要唯一,避免碰撞。

单向函数:hash。给定输入的情况下,很容易计算出结果,而给定结果的情况下,几乎不可能计算出输入值。

一般不存在。正向快速,逆向困难,输入敏感,冲突避免。


md4 , md5,sha-0,sha-1,sha-2(用)


查询时间

缓存的位置。内存,硬盘,本地。

数据结构。

1234567890

234567890-

equals,hashcode。

键总结

无碰撞(唯一),高效生成(不需要,约定好),高效比较。

系统标识+功能标识+业务标识+前后缀。

13910712345+vcode: 123456

公司统一标准。

序列化值(二进制),对象值。

数据污染:

0-0.5-1 1-2 存的不是最终值


缓存只是 在 调用方和 数据提供方之间的一个 暂存方。

统一:缓存中数据怎么来的,查询的时候,如果没有,就从数据提供方获取,然后放到缓存中。

缓存的更新机制

时效性更新机制

固定时间过期,被动更新

:缓存中的数据设置一个过期时间。如果缓存数据过期,那么,我会去提供方查询,这样就相当于将 提供方 的数据 更新到缓存中了。

放弃了:实时一致性。(商品关注人数,评论数,浏览量,评论点赞收藏)

读,

写:只写数据提供方。不理会缓存。

主动更新机制

清风:cap。

cache aside

写:先更新,更新数据提供方,删除缓存。

概率很低:

1。 读的时候,缓存里 没有数据。

2。 读的时候,有写在同时进行。

3。读的时长大于 写操作。(不那么容易发生 1%)。

4。 读写操作 同时发生时,读到的是旧值。50%。

可以用。鸵鸟算法。

计算机科学中,鸵鸟算法 是一个忽略潜在问题的一种算法策略,这种策略对计算机程序可能出现的问题采取无视态度(类似于鸵鸟在遇到危险时将头埋在地里,装作看不见)。鸵鸟算法的使用前提是,问题出现的概率很低。

三高项目-缓存

双写一致性

先删除缓存,再更新数据提供方。 延迟双删。

1。更新缓存,更新数据库。更容易造成数据的不一致,缓存成功,数据提供方失败。更糟糕。

2。更新数据库,更新缓存。有缺点,一点点稍微可取。

缺点:A 更新了数据库。B更新了数据库,B更新了缓存,A更新了缓存。

空干活,经过复杂的计算,给缓存设置值,但是用的少,浪费了资源。

3。删除缓存,更新数据库。延迟双删

4。更新数据库,删掉缓存。上节课所说的额cache aside。

延迟双删:删除缓存,更新数据提供方,睡眠一段时间(根据实际业务),再删除缓存。

如果第二次 删除失败了,怎么办? 重试一下。

自己写重试代码,没问题。自己挂了呢?

转移风险。重试的组件? 消息队列。

上面所说的,不管方案多么复杂,完善,总不能保证一致性。

Read/Write Through

直接 将 结果写入缓存。再从缓存 同步到数据提供方。调用方只需要和缓存交互。

写成功标识:缓存成功,数据提供方成功。TCC。

初始化:1。 启动缓存,从数据提供方,初始化。2。读取缓存 ,初始化。

缓存预热。命中率低,慢慢的命中率才高。

保障:缓存 非常 可靠。

Write Behind

在上面 做了升级,异步写入到数据提供方。加入消息队列,保证最终一致性。


缓存空间足够大,能缓存所有的数据,命中率 100%。

清理机制

以提高缓存命中率为目标。

过去访问多的,未来访问也多。

最近被更新的,未来访问的多。

时效性清理

过期全部清理。要求缓存中的数据都有一个生存期,有效期。

1条数据:data,ttl。2min。

轮询时效清理:额外开启一个程序,定期扫描所有数据的有效期,到期了,干掉。

自动时效清理:cookie。本质:上面的 轮询。

数目阈值清理

1 条数,2 每条的大小。

FIFO: 队列大小是10,

LRU:左神算法。数据访问次数,头部,删尾部。

LinkedHashMap 都可以实现 fifo,lru。

如果空间充足,则缓存多多的,提高命中率。如果空间不够,再回收空间,把空间给其他人让出来。

垃圾回收。

强引用:只要被强引用,就不会被回收。内存不足时,哪怕自己挂掉,也不回收。

软引用:空间不足时,才会被回收。

弱引用,虚引用。

SoftReference。 java实现它。

用java实现一个 根据内存空间大小的使用情况,做一个缓存组件。

Map <k,SoftReference<>>。

实战:

时效性清理+数据阈值式= 1。过期就干掉。2,密集查询,导致空间急剧增大。

LRU+软引用:保证最近用的数据在,然后最近不用的,放到软引用里,用软引用包装一下。

不建议:只用软引用。缓存的存活与否,从业务逃脱。业务控制不了。


三高项目

缓存风险点

每增加一个环节,就多一个风险。

缓存穿透

缓存没有数据,数据提供方也没有数据,穿透了。

无效的调用,增加数据提供方的压力,缓存基本无效。

解决方案:在缓存中,缓存一份 空数据。key有值,value为空。

缓存雪崩

大量缓存突然失效,引发的数据提供方压力 骤增。

数据阈值式清理:(缓存是逐个失效的)阈值比较低的时候会。10个缓存。阈值高,可以缓解。

时效式清理:会造成雪崩。避免缓存在同一时刻失效。过期时间=固定值+随机值。错峰失效。

软引用清理:当空间紧张的时候,缓存占据的空间会被回收。单纯的软引用无法解决。lru:对经常访问的数据建立强引用。

缓存击穿

有数据提供方 兜底,不叫穿透。

lru:高频访问的数据,大概率在前面 fifo。

read/write through, write behind。更新机制。缓存里有没有?因为数据的写、更新,先操作的是缓存。

cache aside: 有一个节点,缓存被删除。可能有击穿。

实际工作:

清理机制+更新机制,针对缓存,共同考虑。

缓存预热

启动系统的时候,提前加载一些数据。预加载。

缓存服务启动后,脚步直接灌入。init

时效式清理机制:缓存重复预热。

缓存的位置

需要缓存的数据,一定要靠前。。要想系统性能好,缓存一定要趁早。

前置模块:减少和后端通信的成本。

后置模块:公共模块,尽量用这个方式。

客户端缓存

客户端:浏览器,c软件,安卓,ios,h5,小程序。

浏览器:cookie,过期时间。轻量级的缓存。

F12 application。h5支持 & 浏览器的支持。

sqlite :安卓端的一个数据库。规则类。开机图片,引导页。

cdn 静态缓存

静态资源:页面,图片。

数据:重点:地名,字典,行业分类,统计局 那些标准化的数据。三级联动。算。广义:与用户个体无关的具有通用性的数据,都可以作为静态数据。

数据:用户不同,参数不同,时间不同,----结果不同。 对系统性能造成负面影响。

服务端缓存

redis。localcache,guava。

数据库缓存

冗余字段,中间表

操作完业务,需要做统计,非实时的数据,让它后置。

新增订单:

insert order (xxxxxx), 统计表 (订单数据 + 1) 10s。

5s, 定时任务扫描(48h-24h) +10。

冗余字段:

订单表(商品的数据)快照。

三高项目

写缓存

读缓存。调用方 数据提供方。

写缓存:调用方和 数据 处理方之间。目的:减少巨量调用操作对数据处理方的冲击。库存。削峰。

消息队列。

写缓存收益:原始时间 <(写缓存时间+缓存中数据向后传递的时间+原始时间)

收益在于用户的角度:目标用户的响应时间 降低了。

读缓存:是以缓存命中的数据 替代 数据提供方的操作。

写缓存:通过增加额外花费的时间,来延迟数据处理方的工作。

写缓存实践:redis(发布订阅),消息队列(发布订阅),数据库(先生成数据,后期再进行统计,耗时的&对实时性要求不高的,后置)

适合场景:请求峰谷值变化明显&对实时性要求不高的系统中。

抢购系统,竞品系统,秒杀系统,抢红包系统。

消息推送系统:极光,百度。

实时性不高。

大厂:

需求:平峰(请求量在某个阈值之下):正常处理。峰值超过阈值的时候,触发写缓存。

降级:微服务降级组件处理可以。

灰度发布。配置灰度规则(规则中 请求的阈值,根据阈值的不同,调用不同的系统)。

限流。要对流量进行 评估。

面试:写的访问量增大,怎么处理。

下单:订阅消息,不重要的系统订阅关键 业务的数据。

posted @ 2022-03-18 08:57  0x9e5Y2J  阅读(131)  评论(0编辑  收藏  举报