02-秒杀系统-商品详细页多级缓存实战(上)

秒杀系统-商品详细页多级缓存实战一

秒杀系统-商品详细页多级缓存实战二

秒杀系统-商品详细页多级缓存实战三

商品数据表模块技术难点

问题:此时有什么问题?: 目前这个方案有什么问题了?我们慢慢发现一个问题,只有分类并不能适应所有的需求,比如 nike鞋和nikeT恤,用户可能希望先看nike的所有商品,这个模型就不能满足。我们想在这个关 系中,加入"品牌"概念

第二个版本:商品+分类+品牌

这样基本用户可以在首页上通过分类或者品牌找到自己想要的商品,也可以直接查看热门的商

品和新上架的商品。

但是问题也来了,用户在进入分类后,展示在用户面前的是很多很多商品,用户希望再通过筛选查询出更接近

他目标的商品?

于是优秀的产品设计师,设计出了类似这样的UI:

怎么设计

分类管有哪些属性

属性管有哪些可选值

商品直接勾选对应的可选值

前端筛选就是:按分类带出对应属性,再按属性选项过滤商品。

  • 作用:筛选用的公共属性,决定了商品属于哪个分类、能被用户怎么过滤。

  • 例子:

    • 手机的「CPU 型号:骁龙 865」「运行内存:12GB」「屏幕尺寸:6.6 英寸」
    • 牛仔裤的「裤型:直筒」「版型:修身」「腰型:中腰」
  • 特点:

    • 同分类下的商品共用这些属性(比如所有手机都有 CPU、内存、屏幕尺寸)
    • 一个商品绑定固定的属性值,不会因为用户选了不同颜色 / 尺寸而改变
    • 只影响「能不能被搜出来」,不影响价格、库存、图片这些东西
  • 一件商品的不同颜色不同尺寸
    是算一个商品还是多个商品。

第四个版本:商品+分类+品牌+属性+规格

货品 = SPU 商品 = SKU

关系:1 个货品(SPU)对应 N 个商品(SKU) 一对多关系

搜索引擎elasticsearch

商品模块展示技术难点

前端展示可以分为这么几个维度:商品维度(标题、图片、属性等)、主商品维度(商品介

绍、规格参数)、分类维度、商家维度、店铺维度等;

另外还有一些实时性要求比较高

的如实时价格、实时促销、广告词、配送至、预售等是通过异步加载

SPU: Standard Product Unit (标准化产品单元),SPU是商品信息聚合的最小单位,是一组

可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。

SKU: Stock keeping unit(库存量单位) SKU即库存进出计量的单位(买家购买、商家进货、

供应商备货、工厂生产都是依据SKU进行的),在服装、鞋类商品中使用最多最普遍。 例如纺

织品中一个SKU通常表示:规格、颜色、款式。SKU是物理上不可分割的最小存货单元。

  • SPU:iPhone 15 (就这一款机型,不分颜色、内存)
  • SKU
    1. iPhone 15 黑色 128G
    2. iPhone 15 粉色 256G
    3. iPhone 15 蓝色 512G

每一条都是独立 SKU,单独算库存、单独定价、单独下单

单品页流量特点
  • 热点少 大部分商品没人看,只有少数爆款、热门商品是流量热点;流量极度不均匀,冷门商品流量极低,少数商品扛住大部分访问。

  • 爬虫、比价软件疯狂抓取 商品详情页是爬虫、比价工具、第三方导购站重点爬的页面,请求量大、频率高、无间断,真实用户流量之外,还掺杂大量机器流量,很容易把系统打垮。

静态化处理

FreeMarker 是一款模板引擎:即基于模板和数据源生成输出文本(html网页,配置文件,电

子邮件,源代码)的通用工具。它是一个 java 类库,最初被设计用来在MVC模式的Web开发框架中生成HTML页面,它没有被绑定到Servlet或HTML或任意Web相关的东西上。也可以用

于非Web应用环境中。

模板编写使用FreeMarker Template Language(FTL)。使用方式类似JSP的EL表达式。模板中

专注于如何展示数据,模板之外可以专注于要展示什么数据

优缺点

这是静态化的一个痛点:如果页面的公共模板(比如页头、页脚、样式、布局)改了,需要把所有商品的 HTML 文件重新生成一遍。比如京东上亿个页面,改一次模板就要全量重生成,成本极高,所以后面才会有动态模板、局部静态化的优化方案。

  • 京东的量级:千万级商品,部署在 50 台服务器 / 节点,最终是上亿个静态 HTML 文件,全靠静态化扛住超大流量。

  • 「1 个模板改了,所有的静态化页面跟着改」这是静态化的一个痛点:如果页面的公共模板(比如页头、页脚、样式、布局)改了,需要把所有商品的 HTML 文件重新生成一遍。比如京东上亿个页面,改一次模板就要全量重生成,成本极高,所以后面才会有动态模板、局部静态化的优化方案。

架构方案的问题

复制代码
商品详情页静态化架构
├─ 核心问题
│  ├─ 新增商品如何同步?
│  │  ├─ 方案1:scp/rsync推送(低效,不推荐)
│  │  ├─ 方案2:定时任务+分布式锁(简单但延迟高)
│  │  └─ 方案3:MQ消息通知+各节点本地生成(推荐)
│  ├─ 数据变更如何同步?
│  │  ├─ 全量重生成静态文件
│  │  └─ 动静分离,动态数据用JS异步拉取
│  ├─ 模板修改如何生效?
│  │  ├─ 全量重生成(成本极高)
│  │  ├─ 局部静态化,公共部分动态引入
│  │  └─ 前后端分离,放弃静态化
│  └─ 用户如何找到静态页面?
│     ├─ 约定URL规则(如 /product/{id}.html)
│     └─ Nginx URL重写
└─ 演进方向
   ├─ 纯静态化(早期)
   ├─ 动静分离(主流)
   └─ 前后端分离+SSR(现代)
方案 核心思路 优点 缺点
1. 文件推送(scp/rsync) 一台服务器生成静态文件,然后推送到所有节点 实现简单,直接粗暴 节点越多,同步成本越高(商品数 × 节点数);带宽压力大;容易出现延迟和一致性问题
2. 定时任务(各节点本地生成) 每台服务器定时从数据库拉取未静态化的商品,本地生成 HTML 无需文件同步,节点间无依赖 必须解决重复执行问题,需要分布式锁(如 Redis 锁、ZooKeeper);定时任务有延迟,实时性差
3. 消息中间件(MQ) 商品新增 / 变更时,发送消息到 MQ;所有节点订阅 topic,收到消息后本地生成 HTML 实时性高;天然支持多节点分发;避免重复同步文件 架构复杂度提升;需要维护 MQ 集群;需保证消息可靠性(防丢、防重)

后台优化

缓存

提高请求的吞吐量,除了减少磁盘IO,还有网络IO,我们可以发现,请求redis其实也会涉及到

网络IO,我们所有的请求都要走xxx端口号。那有没有更好的优化思路了,来同学们你们鲜花在

哪儿?

优化方式 解决什么问题 优化的 IO 类型 作用效果
Redis 缓存 替代查 MySQL 减少磁盘 IO 避开数据库磁盘读写,大幅降低 DB 压力
连接池(Redis/DB) 频繁创建销毁网络连接 优化网络 IO 复用连接,省去三次握手 / 断开的网络开销
线程池 请求串行阻塞、并发低 优化网络 IO 并发处理 多线程异步处理网络等待,提升整体吞吐量
JVM 本地缓存 还要走 Redis 内网网络 消除网络 IO 本机内存直接读,不用连 Redis,零网络 IO
CDN/Nginx 静态缓存 后端还要处理请求 彻底绕过应用 + Redis 直接返回静态页,无网络、无磁盘 IO
相关推荐
薪火铺子15 小时前
Redis 缓存三大问题与解决方案
redis·spring·缓存
努力努力再努力wz1 天前
【Qt 入门系列】从应用场景到开发环境:建立对 Qt 的第一层认知
c语言·开发语言·数据库·c++·b树·qt·缓存
河阿里1 天前
深入理解LRU缓存机制:从原理到应用(C++实现
开发语言·c++·缓存
郝学胜-神的一滴1 天前
高并发秒杀系统设计全解:从需求拆解到Redis库存实战
java·数据库·redis·python·程序人生·缓存·php
nj01281 天前
Spring 循环依赖详解:三级缓存、早期引用、AOP 代理与懒加载
java·spring·缓存
期待のcode2 天前
Redis的数据清理机制
数据库·redis·缓存
阿维的博客日记2 天前
Redis 和 Caffeine 构建的多级缓存,如何保持数据一致性?
数据库·redis·缓存
田梓燊2 天前
LRU 缓存
缓存
旷世奇才李先生2 天前
Redis 7\.0实战:分布式缓存与高可用集群搭建全指南
redis·分布式·缓存