记一次缓存填坑省市区级联获取的操作

先说缓存是什么?

缓存主要是解决高并发,大数据场景下,热点数据快速访问。缓存的原则首先保证数据的准确和最终数据一致,其次是距离用户越近越好,同步越及时越好。

再说我们遇到的场景:

接手项目后,发现省市区前端调用,后台整合了全国数据进行返回。文件超过了1MB。喊着前端同事进行整改,更改成选择哪个获取下级的级联方式,前端的大爷们不配合。哎!催不动啊!你知道不合理但是优化不了。只能在不合理的基础上进行优化。

指导思想:借鉴nacos的配置中心,通过版本号识别是否产生更改,进行数据同步。

这个方案改动比较小,仅额外增加了一个版本号字段,无特殊逻辑,前端接受了。

数据都存储在哪儿了

第1层:客户端缓存

app缓存了全量的数据。

检测是否需要更新时,根据版本号查询后台数据,响应了具体数据就进行本地数据更新,否则保持原状。

缓存的构建和更改: 根据版本号调用后台服务,返回了非空的数据,进行缓存数据的更新。

第2层:nginx缓存

我们通过nginx配置,控制nginx自动缓存了这个版本号对应的数据,有效期是24小时。nginx缓存我们并没有进行手动清理,因为改动不频繁,并且能容忍24小时的时间差。真的想要立刻生效,就手动去进行nginx的缓存删除。

缓存的构建:数据查询完成,缓存对应的请求网址和响应结果。

缓存内容:

初始化后缓存内容: 老版本号/新版本号=空数据,空版本号=全量数据+新版本号

数据更改后缓存内容:空版本号/老版本号=全量数据+新版本号,新版本号=空数据。(缓存未清理则有延时)

第3层:本地服务的缓存

本地服务采用Ehcache,未配置失效时间。

缓存内容:最新版本号/最新数据。

查询操作:比对传入版本号是否和最新版本号相同,相同则返回空对象,否则返回全量数据

缓存的构建:当前缓存无数据,根据redis查询的结果,进行本地缓存的重建。

缓存的清理:redis数据构建完毕,通过loadBalance读取eureka服务名称对应的所有节点信息,轮询调用所有服务的数据清理接口。

第4层:分布式缓存redis

本地服务采用redis缓存,未配置失效时间。

缓存内容:最新版本号/最新数据。

业务操作:比对传入版本号是否和最新版本号相同,相同则返回空对象,否则返回全量数据。

缓存的构建:当查询redis无数据时,双重检查锁防击穿,查询数据库,进行redis缓存的构建。

缓存的清理:产生数据库更新操作时,进行redis缓存的清理动作。

第5层:真实的数据库

更新操作:进行数据库的数据更新,调用redis的重新构建方法,集群轮询调用本地缓存清理方法。

查询操作:查询数据库,组装前端期望的对象。

这样搭建的效果:

当客户端进行请求时, 调用nginx, nginx检测自己的缓存, 根据缓存返回数据。

nginx缓存失效(1天失效一次),服务器本地缓存查询并返回。

服务器本地缓存失效(服务重启),通过redis查询并返回。

redis数据失效(redis被清理),根据数据库进行缓存的构建,并返回。

数据没有产生变更,用户持有的是最新的版本号,大部分场景下返回的都是空对象,减少了海量的io和网络资源的消耗。

同时这个模型像是一个倒置的漏斗, 无论nginx接受了多少请求,相同的请求地址,一天最多放行了1个,撑住了绝大部分的请求流量,nginx每天放行的一个,也被本地缓存命中,减少了redis的查询。

相关推荐
YOU OU4 小时前
Redis基础常识与命令
数据库·redis·缓存
吳所畏惧9 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
Y38153266214 小时前
SERP API + Redis 缓存层:4 种方案对比与选型
数据库·redis·缓存
海兰16 小时前
【高速缓存】RedisVL 高级查询(全文搜索、混合搜索和 多向量搜索)
数据库·人工智能·redis·缓存
流星白龙1 天前
【Redis】4.基本全局命令
数据库·redis·缓存
流星白龙1 天前
【Redis】3.Redis安装与命令行客户端
数据库·redis·缓存
我不想名字重复2 天前
redis缓存和数据库数据保持一致
数据库·redis·缓存
时空无限2 天前
vllm 大模型启动缓存相关环境变量 export
linux·缓存·vllm
流星白龙2 天前
【Redis】6.计数其他命令
数据库·redis·缓存
正儿八经的少年2 天前
redis 的大 key 和热 key 详解
数据库·redis·缓存