冰河技术
导读
♻学习路线
  • 面试必问系列

    • 面试必问
  • 架构与模式

    • Java极简设计模式
    • 实战高并发设计模式
  • Java核心技术

    • Java8新特性
    • IOC核心技术
    • JVM调优技术
  • 容器化核心技术

    • Dockek核心技术
  • 分布式存储

    • Mycat核心技术
  • 数据库核心技术

    • MySQL基础篇
  • 服务器核心技术

    • Nginx核心技术
  • 渗透核心技术

    • 渗透实战技术
  • 底层技术
  • 源码分析
  • 基础案例
  • 实战案例
  • 面试
  • 系统架构
  • Spring6核心技术
  • 分布式事务

    • 分布式事务系列视频
  • SpringBoot
  • SpringCloudAlibaba
  • 🔥AI大模型项目

    • 一站式AI智能平台
    • AI智能客服系统
    • AI智能问答系统
    • 实战AI大模型
  • 中间件项目

    • 手写高性能Redis组件
    • 手写高性能脱敏组件
    • 手写线程池项目
    • 手写高性能SQL引擎
    • 手写高性能Polaris网关
    • 手写高性能RPC项目
  • 高并发项目

    • 分布式IM即时通讯系统(新)
    • 分布式Seckill秒杀系统
    • 实战高并发设计模式
  • 微服务项目

    • 简易电商脚手架项目
  • 手撕源码

    • 手撕Spring6源码
🌍知识星球
  • 总览

    • 《书籍汇总》
  • 出版图书

    • 《深入理解高并发编程:核心原理与案例实战》
    • 《深入理解高并发编程:JDK核心技术》
    • 《深入高平行開發:深度原理&專案實戰》
    • 《深入理解分布式事务:原理与实战》
    • 《MySQL技术大全:开发、优化与运维实战》
    • 《海量数据处理与大数据技术实战》
  • 电子书籍

    • 《实战高并发设计模式》
    • 《深入理解高并发编程(第2版)》
    • 《深入理解高并发编程(第1版)》
    • 《从零开始手写RPC框架(基础篇)》
    • 《SpringCloud Alibaba实战》
    • 《冰河的渗透实战笔记》
    • 《MySQL核心知识手册》
    • 《Spring IOC核心技术》
  • 关于自己
  • 关于学习
  • 关于职场
B站
Github
导读
♻学习路线
  • 面试必问系列

    • 面试必问
  • 架构与模式

    • Java极简设计模式
    • 实战高并发设计模式
  • Java核心技术

    • Java8新特性
    • IOC核心技术
    • JVM调优技术
  • 容器化核心技术

    • Dockek核心技术
  • 分布式存储

    • Mycat核心技术
  • 数据库核心技术

    • MySQL基础篇
  • 服务器核心技术

    • Nginx核心技术
  • 渗透核心技术

    • 渗透实战技术
  • 底层技术
  • 源码分析
  • 基础案例
  • 实战案例
  • 面试
  • 系统架构
  • Spring6核心技术
  • 分布式事务

    • 分布式事务系列视频
  • SpringBoot
  • SpringCloudAlibaba
  • 🔥AI大模型项目

    • 一站式AI智能平台
    • AI智能客服系统
    • AI智能问答系统
    • 实战AI大模型
  • 中间件项目

    • 手写高性能Redis组件
    • 手写高性能脱敏组件
    • 手写线程池项目
    • 手写高性能SQL引擎
    • 手写高性能Polaris网关
    • 手写高性能RPC项目
  • 高并发项目

    • 分布式IM即时通讯系统(新)
    • 分布式Seckill秒杀系统
    • 实战高并发设计模式
  • 微服务项目

    • 简易电商脚手架项目
  • 手撕源码

    • 手撕Spring6源码
🌍知识星球
  • 总览

    • 《书籍汇总》
  • 出版图书

    • 《深入理解高并发编程:核心原理与案例实战》
    • 《深入理解高并发编程:JDK核心技术》
    • 《深入高平行開發:深度原理&專案實戰》
    • 《深入理解分布式事务:原理与实战》
    • 《MySQL技术大全:开发、优化与运维实战》
    • 《海量数据处理与大数据技术实战》
  • 电子书籍

    • 《实战高并发设计模式》
    • 《深入理解高并发编程(第2版)》
    • 《深入理解高并发编程(第1版)》
    • 《从零开始手写RPC框架(基础篇)》
    • 《SpringCloud Alibaba实战》
    • 《冰河的渗透实战笔记》
    • 《MySQL核心知识手册》
    • 《Spring IOC核心技术》
  • 关于自己
  • 关于学习
  • 关于职场
B站
Github
  • 专栏介绍

    • 我要手把手教你搭建并研发一套抗瞬时百万流量的秒杀系统
  • 研发背景

    • 第01章:从多个角度聊聊为何要学习秒杀系统
  • 目标与挑战

    • 第02章:秒杀系统的目标与挑战
    • 第03章:秒杀系统高并发大流量的应对之道
  • 用户故事

    • 第04章:秒杀系统需求与流程梳理
    • 第05章:秒杀系统技术流程梳理
  • 架构设计

    • 第06章:秒杀系统总体方案目标与架构设计
    • 第09章:秒杀系统数据模型设计
  • 环境搭建

    • 第07章:秒杀系统基础环境搭建
    • 第08章:秒杀系统研发环境搭建
    • 第10章:基于DDD快速搭建秒杀系统项目并测试
  • 用户服务设计与实现

    • 第11章:用户登录授权认证流程的设计与实现
    • 第12章:访问登录授权限制接口的流程设计与实现
  • 秒杀活动设计与实现

    • 第13章:秒杀活动业务流程与接口设计
    • 第14章:秒杀活动后端业务与接口开发
    • 第15章:秒杀活动运营端业务开发
    • 第16章:秒杀活动用户端业务开发
  • 秒杀商品设计与实现

    • 第17章:秒杀商品业务流程与接口设计
    • 第18章:秒杀商品后端业务与接口开发
    • 第19章:秒杀商品运营端业务开发
    • 第20章:秒杀商品用户端业务开发
  • 秒杀订单设计与实现

    • 第21章:秒杀订单业务流程与接口设计
    • 第22章:秒杀订单后端业务与接口开发
    • 第23章:秒杀订单用户端业务开发
    • 第24章:秒杀订单运营端业务开发
  • 经典问题重现

    • 第25章:重现刷单流量问题
    • 第26章:重现库存超卖问题
  • 极致缓存设计

    • 第27章:混合型缓存设计场景与原则
    • 第28章:混合型缓存架构设计与技术选型
    • 第29章:混合型缓存通用代码设计与实现
    • 第30章:分布式锁通用代码设计与实现
    • 第31章:混合型缓存通用模型设计与实现
  • 整合极致缓存

    • 第32章:秒杀活动列表混合型缓存设计与实现
    • 第33章:秒杀活动详情混合型缓存设计与实现
    • 第34章:秒杀商品列表混合型缓存设计与实现
    • 第35章:秒杀商品详情混合型缓存设计与实现
  • 缓存领域事件

    • 第36章:领域事件通用缓存模型设计
    • 第37章:秒杀活动监听缓存领域事件的设计与实现
    • 第38章:秒杀活动发送缓存领域事件的设计与实现
    • 第39章:秒杀商品监听缓存领域事件的设计与实现
    • 第40章:秒杀商品发送缓存领域事件的设计与实现
  • 订单领域事件

    • 第41章:秒杀订单监听领域事件的设计与实现
    • 第42章:秒杀订单发送领域事件的设计与实现
  • 库存扣减防超卖设计

    • 第43章:秒杀扣减库存设计
    • 第44章:基于数据库设计并实现库存防超卖
    • 第45章:基于分布式锁设计并实现库存防超卖
    • 第46章:基于Lua脚本设计并实现库存防超卖
  • 单体到微服务

    • 第47章:从单体到微服务重构项目
    • 第48章:重现分布式事务问题
    • 第49章:基于TCC模型解决分布式事务问题
    • 第50章:基于AT模型解决分布式事务问题
    • 第51章:基于可靠消息最终一致性模型解决分布式事务问题
  • 缓存数据一致性

    • 第52章:零侵入重构秒杀活动异步事件后置处理器
    • 第53章:零侵入重构秒杀商品异步事件后置处理器
    • 第54章:零侵入重构秒杀订单异步事件后置处理器
  • 异步化设计

    • 第55章:异步化下单流程设计
    • 第56章:异步化下单编码实现
    • 第57章:异步化扣减商品库存流程设计
    • 第58章:异步化扣减商品库存编码实现
  • 库存分库分表与分桶设计

    • 第59章:商品库存分库分表与分桶设计
    • 第60章:商品库存分库分表与分桶编码实现
    • 第61章:下单流程整合商品库存分桶
  • 订单分库分表设计

    • 第62章:订单分库分表设计
    • 第63章:订单分库分表编码实现
    • 第64章:下单流程整合订单分库分表
  • 隔离与限制策略

    • 第65章:秒杀系统流量隔离策略
    • 第66章:秒杀系统规模限制策略
  • 预约系统设计与实现(含缓存)

    • 第67章:预约系统需求梳理与架构设计
    • 第68章:预约系统数据模型设计
    • 第69章:预约系统业务流程与接口设计
    • 第70章:预约系统运营端业务与接口开发
    • 第71章:预约系统用户端业务与接口开发
    • 第72章:下单流程整合预约系统
  • 预约系统优化

    • 第73章:预约系统分库分表设计
    • 第74章:预约系统分库分表编码实现
    • 第75章:预约系统整合分库分表
  • 秒杀系统削峰策略

    • 第76章:秒杀系统削峰总体概述
    • 第77章:打散客户端流量削峰
    • 第78章:消息队列削峰
    • 第79章:限流削峰
  • 分布式流控

    • 第80章:Sentinel概述与本地搭建环境
    • 第81章:秒杀系统整合Sentinel实现流控
    • 第82章:Sentinel核心技术与配置规则(加餐)
  • 单机限流

    • 第83章:基于QPS实现单机API限流
    • 第84章:基于线程池实现单机并发数限流
  • 业务网关

    • 第85章:业务网关概述与核心架构
    • 第86章:秒杀系统整合业务网关
    • 第87章:业务网关整合Nacos配置
    • 第88章:业务网关整合Sentinel流控
    • 第89章:业务网关整合Guava流控
    • 第90章:业务网关使用自带流控
  • 流量网关

    • 第91章:流量网关环境初步搭建
    • 第92章:流量网关项目搭建
    • 第93章:流量网关实现限流
  • 服务容错

    • 第94章:服务雪崩与容错方案
    • 第95章:服务降级核心原理与落地方案
    • 第96章:热点数据问题与解决方案
    • 第97章:秒杀系统实现服务容错
  • 服务配置

    • 第98章:凌乱的服务配置与解决方案
    • 第99章:秒杀系统整合Nacos配置中心
    • 第100章:实现配置动态刷新
    • 第101章:实现配置动态共享
  • 链路追踪

    • 第102章:链路追踪核心原理与解决方案
    • 第103章:秒杀系统实现链路追踪
    • 第104章:扩展Dubbo源码实现链路追踪
    • 第105章:秒杀系统链路追踪可视化
  • 日志治理

    • 第106章:日志治理概述、原则与架构
    • 第107章:快速搭建ELK环境并导入配置
    • 第108章:秒杀系统整合日志治理
  • 防刷方案

    • 第109章:实现基于条件限流机制防刷
    • 第110章:实现基于Token编排机制防刷
    • 第111章:实现基于黑名单机制防刷
  • 风控模型

    • 第112章:黑灰产与风控基础知识介绍
    • 第113章:风控模型架构与落地方案
    • 第114章:秒杀系统风控模型设计
    • 第115章:秒杀系统风控模型实现
  • 容器化集群部署

    • 第116章:容器化集群部署架构设计
    • 第117章:容器化集群部署落地实现
    • 第118章:容灾架构设计与落地方案
  • 全链路压测

    • 第119章:全链路压测场景与核心流程
    • 第120章:全链路压测核心原则与策略
    • 第121章:全链路压测落地方案实施
  • 极致优化

    • 第122章:服务器物理机极致优化
    • 第123章:单机服务性能极致优化
    • 第124章:秒杀系统流程极致优化
  • 专栏总结

    • 结尾:秒杀系统整体专栏总结
  • 番外篇

    • 第01章:互联网大厂是如何设计和使用缓存的

互联网大厂是如何设计和使用缓存的?方案已开源!

作者:冰河
星球:http://m6z.cn/6aeFbs
博客:https://binghe.site
文章汇总:https://binghe.site/md/all/all.html

沉淀,成长,突破,帮助他人,成就自我。

大家好,我是冰河~~

最近,有小伙伴私信我:冰哥,我最近出去面试,面试官问我如何设计缓存能让系统在百万级别流量下仍能平稳运行,我当时没回答上来。接着,面试官问我之前的项目是怎么使用缓存的,我说只是缓存了一些数据。当时确实想不到缓存还有哪些用处,估计这次面试是挂了。冰哥,你可以给我讲讲互联网大厂项目是怎么设计和使用缓存的吗?

这可能是你职业生涯中最具含金量的一次点击,点击【查看详情】了解更多硬核技术与实战项目,提升技术能力与业务水平,助力跳槽面试、升职加薪和职场规划。

另外,本文缓存方案已经开源,开源地址如下,如果开源方案对你有点帮助或者启发,欢迎在代码仓库给个Star,让更过的小伙伴看到它,互相学习,一起进步。

  • GitHub:https://github.com/binghe001/spring-redis
  • Gitee:https://gitee.com/binghe001/spring-redis
  • GitCode:https://gitcode.net/binghe001/spring-redis

一、前言

通过这位小伙伴的自述,我们明显感受到这位小伙伴对缓存的认识还是停留在简单的存储数据上,没有对使用缓存背后的场景和实现逻辑进行深层次的思考。在互联网大厂项目中,缓存也是一种必不可少的组件,那使用缓存仅仅是为了缓存热点数据,提升读性能吗?如果你对缓存的认识只是停留在这里,那就未免太浅显了。

今天,我们就以高并发、大流量业务场景中最具代表性的 秒杀系统 为例,采用市面上大家都比较熟悉的技术,一起探究下 秒杀系统 背后是如何设计和使用缓存的。

二、秒杀系统缓存核心诉求

秒杀系统在承接瞬时高并发流量时,如果将流量直接打到数据库,那数据库很有可能因为扛不住瞬间的高并发流量而导致崩溃和宕机。所以,需要对秒杀系统进行极致的缓存设计,让大部分流量走缓存。同时,在设计缓存架构方案时,为了进一步提升性能,将采用 本地缓存+分布式缓存的混合型缓存 设计方案,让本地缓存抗大部分流量,分布式缓存次之,数据库再次之,如图1所示


并且针对秒杀系统这种瞬时并发量高的场景,在设计缓存时,需要注意的技巧:优先读取本地缓存数据,如果本地缓存失效,则读取分布式缓存数据,并且在同一时刻,只能有一个线程更新本地缓存,防止缓存击穿。没有获取到本地缓存更新机会的其他线程,需要立即返回而不是原地等待。如果分布式缓存失效时,在同一时刻,也只能有一个线程更新分布式缓存,防止缓存击穿。没有获取到分布式缓存更新机会的线程,也需要立即返回而不是原地等待。

另外,需要注意的是:我们提出了采用 本地缓存+分布式缓存的混合型缓存设计方案,后文会着重对这种设计进行说明。

三、秒杀系统缓存使用场景

秒杀系统属于典型的读多写少的高并发系统,应对这种场景的一个有效措施就是使用缓存,不管是单机JVM缓存还是以Redis为例的分布式缓存,其读写性能都会比数据库高得多。所以,在秒杀系统中,为了应对高并发、大流量的业务场景,缓存自然也就成为建设秒杀系统过程中必不可少的环节。

3.1 秒杀系统接口分析

在秒杀系统中,主要是对一些读数据的接口设计缓存策略,而在这些读数据的接口中,获取秒杀活动列表、获取秒杀活动详情、获取秒杀商品列表和获取秒杀商品详情的接口流量比其他接口高。尤其是获取秒杀商品列表和获取秒杀商品详情的接口QPS一般会高于获取秒杀活动列表和秒杀活动详情的接口,毕竟大部分用户在秒杀开始前就已经进入到秒杀详情页,当然这也不是绝对的,还是要看秒杀系统对于这些接口的设计。

3.2 秒杀系统缓存场景

尽管获取秒杀商品列表和获取秒杀商品详情的接口QPS一般会高于获取秒杀活动列表和秒杀活动详情的接口,但是我们在设计缓存时,需要对这些接口一视同仁,都要以严格的高标准来设计这些接口,不然稍有不慎,一个接口出现问题,就可能导致整场秒杀活动以失败告终。秒杀系统缓存的使用场景如图2所示。


所以,在秒杀系统中,会对获取秒杀活动列表、获取秒杀活动详情、获取秒杀商品列表和获取秒杀商品详情的接口设计缓存策略。

四、混合型缓存设计

总体来说,在设计秒杀系统的缓存过程中,会采用 本地缓存+分布式缓存的混合型缓存 设计方案。其中,本地缓存指的就是单机缓存,比如JVM内存缓存,单机Cache缓存。分布式缓存指的是以分布式的方式集中管理的缓存,比如Memcached、Redis等,如图3所示。


4.1 抗流量洪峰

良好的缓存设计不仅仅能够提升系统的总体性能,还能作为抗瞬时流量洪峰的有效防线。可以这么说,如果整个秒杀系统前置的流量管控、流量清洗和限流等是秒杀系统流量洪峰的第一道防线,则本地缓存就是抗流量洪峰的第二道防线,而分布式缓存就是第三道防线,如图4所示。


使用缓存能够抗一定的流量洪峰,经过前置的流量管控、流量清洗和限流等措施的第一道防线、本地缓存的第二道防线、分布式缓存的第三道防线,真正进入数据库的流量就会比较小了。

4.2 缓存集群方案

从缓存集群模式的角度去分析,每台服务器甚至JVM实例都会拥有自己独立的本地缓存,在承载大并发流量时,,以本地缓存为主,分布式缓存次之,如图5所示。


可以看到,从缓存的集群模式角度来看,每台服务器都会自己独立本地缓存,除了前置的流程管控、流量清洗和限流等措施构筑的流量洪峰第一道防线外。本地缓存会承接剩余的大部分流量,构筑成流量洪峰的第二道防线,而分布式缓存则是流量洪峰的第三道防线。并且在缓存的设计上,分布式缓存的作用主要是协调和同步最新数据到本地缓存。

也就是说,只有本地缓存失效时,才会访问分布式缓存,将分布式缓存中的数据更新到本地缓存中,并且同一时刻只能有一个线程对本地缓存进行更新操作,以避免多个线程并发更新本地缓存。同样的,如果分布式缓存失效,则同一时刻只能有一个线程访问数据库来获取对应的数据,并将其更新到分布式缓存。

在集群模式下,我们应该尽最大努力将流量拦截在本地缓存,避免过多的请求访问分布式缓存,提高秒杀系统的性能,并且降低秒杀系统由于大量的远程IO导致的各种风险。

4.3 缓存交互流程

采用本地缓存+分布式缓存的混合型缓存架构设计方案时,在读取缓存数据时,会优先读取本地缓存的数据,如果本地缓存未开启,或者已经失效,此时就会使用分布式缓存,也就是说,优先读取本地缓存中的数据,如果本地缓存未开启或者缓存数据失效,则读取分布式缓存中的数据,如图6所示。


可以看到,只有在本地缓存未开启或者缓存失效的情况下,才会去访问分布式缓存,读取分布式缓存中的数据,并且在同一个时刻只能有一个线程更新本地缓存中的数据,这种方式可以最大限度减少远程IO为秒杀系统带来的风险。具体的流程如下所示。

(1)判断本地缓存是否开启,如果开启则进行第2步,否则进行第4步。

(2)判断本地缓存是否失效,如果未失效,则进行第3步,否则进行第4步。

(3)读取本地缓存数据,读取缓存流程结束。

(4)判断分布式缓存是否开启,如果开启则进行第5步,否则进行第7步。

(5)判断分布式缓存是否失效,如果未失效,则进行第6步,否则进行第7步。

(6)读取分布式缓存数据,同一时刻只有一个线程更新本地缓存数据,读取缓存流程结束。

(7)读取数据库数据,同一时刻只有一个线程更新分布式缓存数据,读取缓存流程结束。

这里,有一个设计技巧需要大家注意:如果本地缓存失效,并且某个线程没有获取到更新本地缓存的机会,这个线程需要立即返回而不是在原地阻塞等待,这种方式可以最大限度的节省服务器资源和线程切换的成本,尤其是像在秒杀系统这种承接瞬时高并发流量的系统中,这种设计能够节省不少服务器资源。这种线程未获取到更新数据的机会而快速返回的机制,需要客户端配合在适配处理,也就是说,客户端对这种情况需要进行静默处理,不要提示错误信息,也不做其他处理,稍后重新调用接口进行重试即可。

4.4 混合型缓存设计的优点

采用本地缓存+分布式缓存的混合型缓存架构设计方案存在诸多的优点。其中,本地缓存一个很大的优势就在于不会发生远程IO操作,性能更高,有利于服务的横向伸缩,大部分请求会命中本地单机缓存。这里,我们可以从整体的请求链路上进行分析。

例如,当前请求链路上需要读取5次分布式缓存中的数据,这样,如果秒杀系统承接了100万的请求,则会产生500万读取分布式缓存的IO操作。这成倍的IO风险对于秒杀系统来说,是绝对不能忽视的风险因素,如图7所示。


可以看到,一次请求会访问5次分布式缓存,这在无形当中就增加了分布式缓存的IO成本,这对秒杀系统来说,是不容忽视的风险项,稍有不慎,则系统可能会由于IO瓶颈引发各种事故,最终造成系统崩溃或者宕机。所以,在设计秒杀系统时,一定要注意这种放大效应带来的风险。所以,在高并发大流量的场景下,很有必要精心的设计本地缓存。

五、缓存刷新机制

数据存放到缓存中,并不是一成不变的,也不会永久存放到缓存中。也就是说,存放到缓存中的数据终归是要失效或者过期的,也就是存放到缓存中的数据会有相应的生命周期,为此需要以一定的策略对缓存中的数据进行刷新操作,以防止缓存中的数据长时间过期而导致大部分流量直接打入数据库。本节,就从本地缓存和分布式缓存两个角度简单聊聊缓存的生命周期。

5.1 本地缓存刷新机制

假设本地缓存基于Guava Cache实现,在设计本地缓存时,本地缓存的容量不宜过大,有效时长不宜过大,并且在设计本地缓存时,可以基于版本号机制来实现缓存的失效策略。

对于本地缓存会实现两种刷新机制:

(1)主动刷新

请求接口传入的版本号如果大于本地缓存中的版本号,说明本地缓存已经失效,此时,就需要从分布式缓存中重新获取数据进行刷新。

(2)被动刷新

本地缓存自动过期,被动从缓存中移除,此时,需要从分布式缓存中重新获取数据进行刷新。

5.2 分布式缓存刷新机制

假设分布式缓存基于Redis实现,对于分布式缓存来说,也需要设置缓存的过期时间,不能让缓存数据永久性驻留到Redis中。相比于本地缓存来说,分布式缓存的过期时间要稍微长一些,并且分布式缓存在刷新机制上与本地缓存略有不同。

(1)主动刷新

业务数据变更驱动刷新分布式缓存数据。当业务数据发生变更时,会主动刷新分布式缓存中的数据。

(2)被动刷新

可以基于Redis提供的缓存过期策略,比如基于LRU、TTL等策略淘汰缓存中的数据。后续在访问分布式缓存中的数据时,如果检测到分布式缓存中的数据已经过期,则会使用一个线程来刷新分布式缓存中的数据。

六、数据一致性

可以这么说,只要系统中使用了缓存,就或多或少会涉及到数据一致性的问题,在秒杀系统中,数据一致性的问题主要包括:本地缓存与分布式缓存数据一致性问题,缓存与数据库数据一致性问题。同时,在数据一致性保证方面,就包括强一致性保证和弱一致性保证。

6.1 强一致性保证

CAP理论为数据的强一致性奠定了理论基础,但是CAP理论下的数据强一致性,很难做到既保证系统高性能的同时,又要保证数据的绝对一致。在秒杀系统的设计中,我们会将数据的强一致性保证交给数据库和业务规则来实现,在业务规则层面结合数据库来实现强一致。

例如,假设用户在抢购秒杀商品中,缓存中存在商品库存,通过了缓存中的校验逻辑。在真正下单时,还要校验数据库中的商品库存,如果此时数据库中已经没有商品剩余库存了,则终止下单逻辑,提示用户商品已售罄。

6.2 弱一致性保证

强一致性保证交由业务规则和数据库共同约束实现,缓存层面的数据就可以实现为弱一致性。也就是说,在很小的一段时间内,允许缓存中的数据存在延迟,允许缓存中的数据与数据库中的数据在短时间内的不一致,只要在可接受的时间范围内最终达到一致即可。充分发挥缓存的实际作用,即:缓存数据,提供系统的读写性能和抗系统流量。

七、缓存落地实现

在秒杀系统中本地缓存和分布式缓存相结合,能够抗住进入秒杀系统内部的大部分流量。并且在技术选型上,假设本地缓存默认基于Guava Cache实现,分布式缓存默认基于Redis实现。并且本地缓存不仅仅只是支持Guava Cache,分布式缓存不仅仅只是支持Redis,在代码层面,都是面向接口编程,而非面向具体实现类编程,不管是本地缓存还是分布式缓存,都可以根据简单的配置切换具体的实现方式。

7.1 扩展性描述

代码具备良好的扩展性,后续维护和升级的成本就比较低。相反,如果代码写的杂乱无章,犹如“屎山”,那后期维护起来是相当痛苦的,谁也不想天天面对着一堆“屎山”,哪来有问题改哪里。所以,从一开始写的代码就要有良好的扩展性,方便后期的维护和升级。

假设秒杀系统整体基于SpringBoot+SpringCloud Alibaba技术栈实现,那如何写代码具备良好的扩展性呢?总体的原则就是面向接口编程,而非面向具体的实现类编程,具体业务逻辑里依赖的是接口,而非实现类,在接口不变的前提下,可以随时切换具体的实现类,也可以随时新增接口的实现类。业务中可以根据配置加载接口的某个具体实现类。

7.2 本地缓存落地实现

本地缓存的落地实现示意图如图8所示。


可以看到,具体秒杀业务中会依赖本地缓存的接口,而非具体的实现类。本地缓存的接口可以有多个实现类,在秒杀业务中可以根据具体的配置项指定要加载并使用哪个实现类,也可以根据具体的需求和业务场景随时新增本地接口的实现类,大大提高了程序的扩展性。

7.3 分布式缓存落地实现

分布式缓存的落地实现示意图如图9所示。


可以看到,分布式缓存在扩展性方面的设计与本地缓存类似,同样是秒杀系统在具体业务中依赖分布式缓存的接口,而非分布式缓存的具体实现类。分布式缓存的接口可以有多个实现类,在秒杀业务中可以根据具体的配置项加载并实例化具体的实现类,也可以根据具体的需求和业务场景新增分布式缓存接口的实现类,提高了实现分布式缓存程序的扩展性。

八、总结

缓存不仅仅可以用来存储热点数据,提升热点数据的读性能,还是业务系统中抗高并发、大流量的利器。以秒杀系统为例,采用本地缓存+分布式缓存的混合型缓存方案时,如果整个秒杀系统前置的流量管控、流量清洗和限流等是秒杀系统流量洪峰的第一道防线,则本地缓存就是抗流量洪峰的第二道防线,而分布式缓存就是第三道防线,经过层层流量过滤,最终进入数据库的流量就比较可控了。

同时,引入本地缓存+分布式缓存的混合型缓存方案后,要考虑缓存的刷新机制,数据一致性问题,在代码落地的过程中,还要最大程度避免缓存穿透、击穿和雪崩问题,并实现代码的高度可扩展性。

在提供的开源方案中,已经解决了缓存穿透、击穿和雪崩问题,开源地址如下:

  • GitHub:https://github.com/binghe001/spring-redis
  • Gitee:https://gitee.com/binghe001/spring-redis
  • GitCode:https://gitcode.net/binghe001/spring-redis

如果开源方案对你有点帮助或者启发,欢迎在代码仓库给个Star,让更过的小伙伴看到它,互相学习,一起进步。

九、写在最后

这些真实场景的项目设计与落地实现,在冰河的知识星球除了Seckill秒杀系统外,还有其他5个项目,这些项目的需求、方案、架构、落地等均来自互联网真实业务场景,让你真正学到互联网大厂的业务与技术落地方案,并将其有效转化为自己的知识储备。

年底最大优惠力度,原价299,扫码立减200,加入星球学习。


加入星球后,记得查看置顶消息,申请代码权限等。并且课程汇总里面有往期项目、课程专栏、学习路线,还有1000+套精美简历模板和面试技巧等内容。

另外,点击 阅读原文 ,了解更多硬核技术与实战项目,提升技术能力与业务水平,助力跳槽面试、升职加薪和职场规划。

好了,今天就到这儿吧,我是冰河,我们下期见~~

在 GitHub 上编辑此页
上次更新: 2026/4/29 16:18
Contributors: binghe001
阅读全文
×

扫码或搜索:冰河技术
发送:290992
即可立即永久解锁本站全部文章

星球会员
跳转链接