电商系列第三课:商品中心——亿级商品搜索与SKU管理
作者:小蒋
邮箱:wei_wei10@163.com
微信:wei_wei10
音频:https://xima.tv/1_ZazZ6u?_sonic=0
【小蒋聊技术】关注技术成长,深挖业务价值。大家好,我是小蒋。
上节课我们深入讲解了用户中心,这是电商的根基。这节课,我们讲商品中心,电商的货。用户来了,你得让他有东西可逛、有东西可买。
大家有没有想过一个问题:淘宝京东有几亿件商品,搜索"手机"为什么能瞬间返回结果?这背后是什么技术在支撑?
今天我们就来揭开商品中心的神秘面纱。记住我们一直在强调的:技术是手段,业务是目的。
亿级商品搜索
先问大家:用户60%的访问来自搜索。如果搜索体验不好,会有什么损失?用户搜不到想要的东西,直接去竞品平台。搜索加载超过3秒,用户流失50%。
传统方案为什么不行?用MySQL的B+树索引,亿级数据全表扫描,查询要几十秒。解决方案是ElasticSearch加倒排索引。分词之后,把每个词对应的商品列表存起来。搜索"手机"时,直接拿出"手机"这个词对应的商品列表,比逐条扫描快成千上万倍。

真正的复杂度来了。首先,中文分词怎么做?苹果可能是水果,也可能是手机品牌,得用分词器处理。同义词怎么处理?手机和移动电话是不是一个意思?这需要维护同义词词库。搜索排序怎么设计?综合相关度、销量、评分、时效性、价格等多个因子。权重怎么调?A/B测试怎么跑?
还有实时性问题。商家上架了新商品,搜索结果什么时候能体现?ES是近实时写入,秒级可见。最后,聚合统计怎么做?用户搜手机,侧面要展示品牌、价格区间等筛选项。这里我们重点展开讲讲。
聚合统计是搜索体验的关键。 ES的Aggregation功能天然支持。搜索请求中加上aggs参数,指定按品牌、价格区间等维度聚合。真正的复杂度在于:筛选项是动态的,用户选完品牌,剩下的可选价格区间可能变了。这需要前后端联动,筛选交互要做好。亿级数据聚合很耗资源,用filter聚合代替query聚合,能利用ES的缓存。
SKU多规格管理
说完搜索,我们说说SKU多规格管理。

两个概念:SPU和SKU。SPU是标准产品单位,比如iPhone 15。SKU是库存量单位,比如iPhone 15 256G蓝色。SPU是抽象模板,SKU是具体销售实体。
真正的复杂度:首先是笛卡尔积爆炸。假设手机有三种颜色、三种内存、两种套餐,那就是18个SKU。品类多了以后,SKU数量爆炸式增长。解决方案是规格组合管理:用户选完颜色,再选内存,剩下的可选规格动态计算。
其次是SKU属性冗余。每个SKU需要冗余存储关键属性:价格、库存、图片。为什么要冗余?查询时不用跨表JOIN,性能好。但更新时要同步更新多个地方。
还有库存一致性。库存分散在多个SKU,下单扣库存时,如何保证不超卖?Redis分布式锁?数据库乐观锁?
复杂价格计算
价格计算是电商最核心的逻辑之一,直接涉及钱,容不得半点差错。

价格计算出了问题,有什么损失?用户付了100块,实际应该收80,损失20块。用户付了80块,实际应该收100,少收20块。促销活动价格叠加错误,被薅羊毛。
优惠叠加规则:促销和优惠券能不能叠加?常见规则是促销和优惠券互斥,只能选一个。优惠券之间也不一定能叠加。会员价通常可以与优惠券叠加。这些规则要抽象成配置,不能写死在代码里。
真正的复杂度:第一,价格一致性。商品详情页显示的价格、购物车显示的价格、下单时的价格、最终支付的价格,必须一致。价格计算必须原子化,下单时重新计算价格。第二,浮点数精度问题。Java的double类型计算有精度问题,电商用BigDecimal。但BigDecimal性能比double差很多,高并发下怎么办?第三,价格风控。如果有人利用价格漏洞,下单价和实际支付价不一致,怎么办?
商品数据同步
商品数据存在MySQL,但搜索要用ES。数据如何同步?

常见方案有三种。定时任务同步:每分钟跑一次任务,把MySQL数据同步到ES。问题:延迟高,数据不一致。Canal监听Binlog:用Canal监听MySQL的Binlog变化,实时同步到ES。MQ异步同步:商品变更时,先写 MySQL,再发MQ,下游消费MQ去更新ES。
真正的复杂度:数据一致性怎么保证?MySQL和ES的数据必须一致。同步延迟怎么控制?商家上架商品,希望立刻能搜到。但MQ消费有延迟,高峰期积压更多。
图片存储
商品详情页有大量图片,几亿张图片怎么存?
解决方案是对象存储加CDN。图片存OSS或S3,通过CDN加速分发。
真正的复杂度:图片如何裁剪?不同终端需要不同尺寸的图片。图片水印怎么加?防盗要加水印。图片压缩怎么做?WebP格式比JPEG小30%,但兼容性有问题。
实战解析:下单扣库存,如何保证不超卖?
接下来我们挑一个点深入讲讲。以SKU库存一致性为例,这是面试高频问题。
双十一凌晨0点,iPhone 15 Pro Max准时开抢。库存只有100台,但同时有5000人下单。如果技术没做好,会发生什么?5000人都下单成功,实际库存只有100台,超卖4900台。4900人付了钱却没货。这就是典型的库存超卖问题。
方案一:数据库乐观锁。SQL这样写:UPDATE sku_stock SET stock = stock - 1 WHERE sku_id = 100 AND stock > 0。核心是WHERE条件加stock大于0。优点是简单,缺点是,高并发下5000人抢100台,4900人会失败。
方案二:Redis预扣减。流程是:请求进来,先扣Redis库存,用Lua脚本保证原子性。Redis扣成功,再异步落库到MySQL。优点是Redis性能高,能扛住峰值流量。缺点是Redis和MySQL数据一致性问题,需要补偿机制。
方案三:消息队列削峰。流程是:请求进入MQ,按顺序处理。消费者逐个扣库存。优点是把突发流量削平,保护后端数据库。缺点是实现复杂。
库存超卖本质是并发扣减的原子性问题。技术方案从简到繁:数据库乐观锁、Redis预扣减、MQ削峰。业务量级决定技术选型,不是越复杂越好。
总结
今天我们深入拆解了商品中心,五个核心技术点:亿级商品搜索、SKU多规格管理、复杂价格计算、商品数据同步、图片存储。
记住我们的核心理念:技术本身没有价值,能解决业务问题、帮企业降本增效创造收益,技术才有价值。
下期预告
第四课我们讲订单中心:高并发下单与分布式事务。下单时扣库存、减优惠券、调支付,怎么保证一致性?咱们下期揭晓。
思考题
你在项目中,遇到过哪些复杂的商品价格计算场景?
关注技术成长,深挖业务价值。有问题评论区留言,我是小蒋,咱们下期见!
更多推荐




所有评论(0)