Redis - 在电商购物车场景下的实战分析

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis - 在电商购物车场景下的实战分析

1. 购物车需求背景与业务整体设计

1.1 写在前面

1.1.1 需求背景

商城购物车模拟了传统的现实世界中真实存在的购物车的功能,便于用户挑选心仪商品统一结算等。同时还能在这个点上加以创新,加一些其他的功能。比如:比价,推荐(可作为商家的竞价广告位)等,甚至还可以统计数据告诉卖家,有多少人添加了购物车(代表有购物意向),结果没有付款(尝试分析原因)。

1.1.2 购物车的妙用

购物车在实际使用中对用户来说,兼具凑单、促销、收藏的功能。


  1. 凑单

在用户浏览商品详情页的时候,有两种选项:一种是“立即购买”, 另一种是“加入购物车”。当用户本身需求较多,想一次购买多种商品, 或者参与到优惠活动中(如满减、满赠等),这时候会将商品加入购物车进行凑单。

  1. 促销

购物车还有促销方面的功能,用于提高客单价。当有促销活动(满减、满赠)时,用户将商品加入购物车之后,可以查看是否满足优惠条件和优惠之后的金额(不包含优惠券)。

  1. 收藏

对于大部分用户来说,购物车发挥更多的是收藏的作用:“这东西看着不错,等以后再下单。”另外还有筛选的作用。比如笔者网购时, 会先加入购物车收藏,后面有时间再在购物车中筛选之后购买。

1.2 业务设计

1.2.1 通用显示

  1. 商品信息
  2. 促销信息
  3. 选中状态

默认全选、默认全不选、继承上次选中

  1. 结算

1.2.2 离线购物车

离线购物车指的是用户在未登录状态下把商品加入购物车,一般通过创建虚拟用户实现。为了更好的用户体验,需要让用户在下单之前,允许未登录先将商品加入购物车。

用户登录之后,涉及离线购物车和在线购物车合并。首先判断当前是否有离线购物车,然后将离线购物车的数据和在线购物车的数据进行合并。

1.2.3 商品监控

  1. 库存监控

设置库存提醒值,判断当前商品的数量,当库存数大于0并 小于提醒值时,提醒用户库存不足,请尽快下单;当库存数等于0时, 提醒无货。

  1. 状态监控

当商品下架后,提示商品无效;

无效商品进入无效商品列表中,可批量清除。

  1. 价格监控

购物车的商品价格变动时给用户提示,比如降价20元,会对用户的消费决策产生影响。

1.2.4 分类排序

  1. 商家店铺,将不同店铺的商品分开;
  2. 优惠不同,在购物车中将优惠活动相同的商品聚合在一起;
  3. 加入时间,按照加入购物车的时间倒序排列,最近添加的商品排列在 前。

1.2.5 促销信息

购物车中显示促销相关信息,类似满减、满赠、赠品等信息。例如在购物车中显示“满500减100”、“全场满减”、“商品的赠品有哪些”。还可以引导客户去店铺领取优惠券。在购物车中展示促销信息对提高客单价有良好效果,笔者认为目前最好用的购物车非京东莫属。

1.2.6 商品推荐

在购物车底部,是最好的商品宣传位,可以添加为商品推荐区域。 至于商品推荐的内容,会根据用户数据做定向推荐,这里不做扩展。

1.2.7 编辑

编辑购物车时主要可以进行的操作:删除商品、加减商品数量、更改选中状态、更改商品规格等。

1.2.8 结算

在购物车选中商品时,会实时算出订单金额。在购物车中计算时,需要将优惠金额算进去。

计算优惠金额还需要考虑满减促销、多种优惠券同时满足订单时用户自主选择还是推荐最优券等等。

2. 购物车核心链路和技术方案设计

2.1 核心链路

2.2 技术方案设计

部分电商公司对于购物车数据会选择不落库处理,只做Redis缓存;本次案例以Redis为主,同时通过RocketMQ将购物车数据异步更新到MySQL,不需要去保证Redis缓存和MySQL持久化的数据一致性,数据库只是作为数据备份。

业务上来说,购物车其实是临时性的数据。仅仅是把一些商品再购物车里进行暂存,迟早会购买(从购物车里删除),或者长时间没有购买,已经遗忘了加购过什么商品。就算在极端情况下丢失数据,也影响不大,这时用户重新加入就好了。

2.2.1 Redis

  • 缓存穿透
    当请求穿透缓存时,通过写入空缓存、分布式锁限制MySQL的负载。

2.2.2 表结构

-- auto-generated definition
create table cart
(
    id              bigint auto_increment comment '主键ID'
        primary key,
    user_id         bigint         default 0                 not null comment '用户ID',
    product_sku_id  bigint         default 0                 not null comment '商品SKU ID',
    product_sku_num int            default 0                 not null comment '商品SKU数量',
    add_amount      decimal(10, 2) default 0.00              not null comment '加购价格',
    selected_status tinyint        default 1                 not null comment '选中状态 0:未选中 1:已选中',
    is_deleted      tinyint        default 0                 not null comment '是否删除 0:未删除 1:已删除',
    create_time     datetime       default CURRENT_TIMESTAMP not null comment '创建时间',
    update_time     datetime       default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '修改时间'
)
    comment '购物车表';
create index idx_product_sku_id
    on cart (product_sku_id);
create index idx_user_id
    on cart (user_id);

2.2.3 MQ

加入购物车/更新购物车通过RocketMQ异步入库

3. 购物车的阈值检查与重复加入逻辑

3.1 为什么淘宝购物车要设置上限?

3.1.1 回归原始 - 拟物

实体购物车因为有物理的空间限制,理论上可以购买的商品件数和空间是有限的,因此电商的购物车其实在拟物化上也沿袭了这一设计。

站在平台和商家的立场考虑,购物车上限的提示是在一定程度上引导用户去结算或者清理的,提升购物车商品的曝光量,同时也是希望用户把购物车和收藏夹的场景区分开来的,保留购物车的核心功能。

3.1.2 需求大小与价值衡量

  1. 需求大小

从我自身的使用上,我目前还未遇到过购物车超过上限的情况,但是基于淘宝天猫这么大超过8亿的用户群体,碰到购物车超过上限的比例如果只有1%,那绝对值也有庞大的800万用户。

  1. 价值衡量

电商购物最终一定是以交易成交为目的的,也就是解决这个问题能否提升用户下单率和成交件数。这个其实是不一定的,当购物车上限过多时,有可能用户的购买决策会更难,周期可能会更长,同时购物车过多商品用户也会表示很难找到自己想结算的商品,所以在需求的价值上来说是需要慎重衡量的。

  1. 解决方案

(1)引导用户结算或者清理;

(2)引导用户先添加收藏夹再添加购物车;

(3)类似花呗限时提额的操作;

(4)类似美团外卖多个购物车的场景;

(5)在大促是限时提高购物车的上限。

3.1.3 技术和性能

在大促时,系统本来已经面临千万级上亿级别的并发量,为了避免购物车商品图片、价格等信息加载不出来,出现卡顿等情况,设置上限是保证用户体验的一个手段,当用户不能添加购物车需要清理购物车,和进入购物车出现卡顿或加载不出来相比,影响相对较小。

购物车结算涉及到跨店铺满减、商品库存、优惠券、订单金额计算等多达几十个服务的调用

因此技术上为了避免宕机或者影响用户无法结算等糟糕的体验,设置购物车上限是一种产品上的妥协。

3.2 购物车需要设置哪些上限

  1. 购物车单个SKU上限
  2. 购物车加购SKU上限

3.3 重复加入

  1. 不校验重入逻辑
  2. 校验重入逻辑
@Slf4j
@Component
public class RedissonUtils {
    @Resource
    private RedissonClient redissonClient;
    public boolean lock(String key, long waitTime, long leaseTime) {
        RLock lock = redissonClient.getLock(key);
        try {
            return lock.tryLock(waitTime, leaseTime, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error("[RedissonUtils][lock] - tryLock异常", e);
        }
        return false;
    }
    public void unLock(String key) {
        RLock lock = redissonClient.getLock(key);
        if (ObjectUtils.isNotEmpty(lock)) {
            lock.unlock();
        }
    }
}

4. 购物车加入商品多线程并发问题解决

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
监控 NoSQL Java
场景题:百万数据插入Redis有哪些实现方案?
场景题:百万数据插入Redis有哪些实现方案?
42 1
场景题:百万数据插入Redis有哪些实现方案?
|
1月前
|
存储 NoSQL Redis
Redis 新版本引入多线程的利弊分析
【10月更文挑战第16天】Redis 新版本引入多线程是一个具有挑战性和机遇的改变。虽然多线程带来了一些潜在的问题和挑战,但也为 Redis 提供了进一步提升性能和扩展能力的可能性。在实际应用中,我们需要根据具体的需求和场景,综合评估多线程的利弊,谨慎地选择和使用 Redis 的新版本。同时,Redis 开发者也需要不断努力,优化和完善多线程机制,以提供更加稳定、高效和可靠的 Redis 服务。
37 1
|
1月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
77 6
|
24天前
|
缓存 监控 NoSQL
Redis 缓存穿透的检测方法与分析
【10月更文挑战第23天】通过以上对 Redis 缓存穿透检测方法的深入探讨,我们对如何及时发现和处理这一问题有了更全面的认识。在实际应用中,我们需要综合运用多种检测手段,并结合业务场景和实际情况进行分析,以确保能够准确、及时地检测到缓存穿透现象,并采取有效的措施加以解决。同时,要不断优化和改进检测方法,提高检测的准确性和效率,为系统的稳定运行提供有力保障。
48 5
|
26天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
56 5
|
1月前
|
缓存 NoSQL Java
Spring Boot与Redis:整合与实战
【10月更文挑战第15天】本文介绍了如何在Spring Boot项目中整合Redis,通过一个电商商品推荐系统的案例,详细展示了从添加依赖、配置连接信息到创建配置类的具体步骤。实战部分演示了如何利用Redis缓存提高系统响应速度,减少数据库访问压力,从而提升用户体验。
74 2
|
1月前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
63 4
|
1月前
|
存储 消息中间件 NoSQL
【redis】redis的特性和主要应用场景
【redis】redis的特性和主要应用场景
107 1
|
2月前
|
缓存 NoSQL 应用服务中间件
Redis实战篇
Redis实战篇
|
2月前
|
Oracle NoSQL 关系型数据库
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
主流数据库对比:MySQL、PostgreSQL、Oracle和Redis的优缺点分析
424 2
下一篇
无影云桌面