在电商系统中,哪些数据需要放到缓存?哪些数据需要放到DB永存呢?

先给结论

有需要被"记住"而非仅仅被"看到"的信息。 用户在淘宝上的每一次点击可以被遗忘(缓存过期),但他的每一笔交易必须被铭记(DB永存)。这就是工业级系统设计中"性能"与"正确"之间的永恒权衡。

我们必须先建立一个认知:缓存是"便签纸",关系型数据库才是"法律账本"。

便签纸(缓存)写得快、看得快,但可能写错、可能丢失、可能被风吹走;而法律账本(DB)写得慢,但它是唯一具备法律效力、绝对准确、永久保存的依据。

下面我以 "用户在淘宝下单买一件衣服" 的全流程为例,详细拆解哪些数据必须落DB,哪些放缓存,以及为什么。

1. 核心原则:什么决定了数据存哪里?

判定维度 放关系型数据库 (PolarDB/OceanBase) 放缓存 (Tair/Redis)
一致性要求 强一致(绝对不能错) 最终一致(允许短暂不准)
数据生命周期 永久保存 临时/有TTL
业务后果 错了=资损/法律风险/客诉 错了=体验下降/可重试
操作类型 复杂事务、关联查询、聚合统计 简单KV读写、高频计数
数据价值 核心资产 加速副本

2. 购物全流程数据归属详解

场景一:浏览商品详情页
数据项 存储位置 原因
商品标题、描述、SKU属性 缓存 (主) + DB (备) 读多写少,缓存命中率高;修改时异步刷新缓存
商品主图/视频 CDN + OSS 大文件,不适合进KV缓存
实时价格 缓存 + DB 价格变更时通过消息队列秒级刷新缓存;DB是定价权威来源
实时库存 缓存 (扣减) + DB (校准) 高并发下用Redis原子扣减防超卖;订单创建成功后异步落DB持久化
评论列表 缓存 + Lindorm 评论内容存Lindorm(宽表),热门评论摘要进Redis
"猜你喜欢"推荐 缓存 推荐引擎预计算结果,纯读场景

关键点:库存的"双写"逻辑

用户点击"立即购买"时,先在Redis中执行 DECR 扣减库存(毫秒级响应,抗住秒杀流量)。但这只是"预扣",真正的库存变更必须在订单创建事务中写入PolarDB。如果订单取消或支付超时,Redis和DB都要回滚。Redis是"挡箭牌",DB是"真账本"。

场景二:提交订单
数据项 存储位置 原因
订单主表 PolarDB/OceanBase 核心交易数据,涉及资金、履约、售后,必须强一致+永久存储
订单明细(SKU/数量/单价) PolarDB/OceanBase 与主表在同一事务中写入,保证原子性
优惠快照(用了什么券/满减) PolarDB/OceanBase 退款/审计时必须精确还原当时优惠规则
收货地址快照 PolarDB/OceanBase 用户后续修改地址不影响历史订单
订单号生成 Tair(序列号) + DB Redis自增生成全局唯一ID,DB记录映射关系
购物车状态 缓存 (主) 购物车是"临时意图",非正式交易;DB仅做异步持久化防丢失

为什么订单必须落DB?

  • 事务性:扣库存、创建订单、扣优惠券、记积分,这4个操作要么全成功要么全失败,只有DB支持ACID事务。
  • 可追溯:3个月后用户投诉"我没收到货",客服需要从DB查出完整订单链路。缓存早就过期了。
  • 合规性:电商法要求交易记录保存至少3年,缓存无法承担此法律责任。
场景三:支付与履约
数据项 存储位置 原因
支付流水 OceanBase 资金数据,金融级强一致,RPO=0
支付状态回调 DB + 缓存 DB持久化;缓存更新订单状态供前端快速轮询
物流单号/轨迹 DB + 缓存 DB存权威记录;缓存存最新轨迹供高频查询
发票信息 PolarDB 税务合规,不可变
风控决策结果 缓存 实时拦截用,事后分析从日志/数仓取
场景四:用户相关数据
数据项 存储位置 原因
用户名/手机号/实名信息 PolarDB 核心身份数据,加密存储,强一致
Session/Token 缓存 登录态是临时的,过期即失效
用户标签(偏好/等级) 缓存 + DB 画像系统预计算写缓存;DB存原始行为数据
浏览/搜索历史 缓存(近期) + Lindorm(长期) 近期行为用于实时推荐;长期行为用于离线分析
收藏夹 缓存 + DB 高频读走缓存;DB保证换设备后数据不丢

3. "强一致"到底意味着什么?

以支付为例,对比两种一致性模型:

维度 强一致 (OceanBase/PolarDB) 最终一致 (Redis缓存)
写入后读取 立即读到最新值 可能读到旧值(延迟ms~s级)
故障恢复 RPO=0,数据零丢失 可能丢失未持久化的写入
跨行/跨表 支持分布式事务 不支持
适用场景 转账、下单、库存确权 展示、计数、会话、预扣
代价 延迟较高(ms级),吞吐受限 延迟极低(μs级),吞吐极高

一句话总结

"强一致" = 在任何时刻、任何节点、任何故障场景下,读到的数据都等于最后一次成功写入的值。 这是用性能和复杂度换来的"绝对正确",只用在"错了就出大事"的地方。

4. 架构全景图:一次购物的数据流转

复制代码
用户点击"购买"
       │
       ▼
┌──────────────┐    预扣库存     ┌─────────────┐
│   前端/App    │ ─────────────→ │ Tair(Redis) │ ← 毫秒级响应,抗并发
└──────────────┘                └─────────────┘
       │                              │
       │ 创建订单(同步)                 │ 异步同步
       ▼                              ▼
┌──────────────────────────────────────────────┐
│         PolarDB / OceanBase                  │
│  ┌─────────┐ ┌─────────┐ ┌────────────────┐  │
│  │订单表    │ │库存表    │ │优惠/支付流水表  │  │
│  │(强一致)  │ │(强一致)  │ │(强一致)        │  │
│  └─────────┘ └─────────┘ └────────────────┘  │
│         ↑ ACID事务保证原子性                   │
└──────────────────────────────────────────────┘
       │
       │ 订单创建成功 → 发消息
       ▼
┌──────────────┐
│  消息队列     │ → 通知缓存更新订单状态
│  (RocketMQ)  │ → 触发积分/通知等异步任务
└──────────────┘

终极总结

问题 答案
哪些必须落DB? 一切涉及钱、权、责、法的数据:订单、支付、库存确权、用户身份、合同、发票
哪些放缓存? 一切为了快、省、扛的数据:商品展示、Session、预扣库存、推荐结果、热点配置
两者关系? DB是"真相之源",缓存是"高性能投影"。缓存可以脏、可以丢、可以过期,但DB永远是对的
为什么不全放DB? DB扛不住百万QPS,延迟也满足不了用户体验
为什么不全放缓存? 缓存没有事务、不能持久、无法追责,用来管钱等于裸奔
相关推荐
其实防守也摸鱼3 小时前
运维--安全与数据库
网络·数据库·学习·安全·安全威胁分析·数据库架构·软件安全
TDengine (老段)5 小时前
TDengine DML SELECT — 完整查询语法参考
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
Database_Cool_1 天前
时序数据库选型:阿里云 Lindorm 时序引擎 vs InfluxDB 全维度对比
数据库·阿里云·时序数据库
石像鬼₧魂石1 天前
【Y2Ksoft】智慧农场管理平台 —— 航拍实景 · 物联网可视化 · 单文件HTML开箱即用
大数据·物联网·数据库架构
石像鬼₧魂石1 天前
【Y2Ksoft】贵阳枫叶控股ERP管理系统 —— 管业制造 · 全链路数字化 · 开箱即用
大数据·数据仓库·数据库开发·数据库架构
TDengine (老段)1 天前
TDengine 索引使用指南 — 何时建、怎么建、怎么用
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
TDengine (老段)1 天前
TDengine DDL 完整参考 — Database/STable/Table/Column/Tag
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
石像鬼₧魂石1 天前
【Y2Ksoft】贵阳陈桥饭店ERP管理系统
大数据·前端·物联网·html·数据库架构
数据库小学妹1 天前
分布式数据库架构怎么选?三种路线对比+迁移避坑指南
数据库·分布式·分布式数据库·数据库架构·数据迁移·数据库选型