`
gao_xianglong
  • 浏览: 470614 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

大促场景下热点数据写(库存扣减)技术难题解决方案

阅读更多

《大促场景下热点数据写(库存扣减)技术难题解决方案》

 

已经很久没有足够的时间让自己安静下来撰写一篇技术文章,确实近年来,大部分都花在了工作和2017年的新作品上。今天难得自己给自己打了瓶100ML的鸡血,出一篇前段时间针对交易系统大促场景下热点数据写优化的相关案例。当然,不同的企业有不同的解决方案和实现,但是万变不离其宗,还是那句话,对于大型网站而言,其架构一定是简单和清晰的,而不是炫技般的复杂化,毕竟解决问题采用最直接的方式直击要害才是最见效的,否则事情只会变得越来越糟

 

在大部分情况下,商品库存都是直接在关系型数据库中进行扣减,那么在限时抢购活动正式开始后,那些单价比平时更给力、更具吸引力的热卖商品大家肯定都会积极踊跃的参与抢购,这必然会产生大量针对数据库同一行记录的并发更新操作。因此数据库为了保证原子性,InnoDB引擎缺省会对同一行数据记录进行加锁,把前端的并发请求变成串行操作来确保数据更新时的一致性。

 

一、在RDBMS中扣减商品库存

先来看看如果是直接在数据库中扣减库存,应该如何避免商品超卖呢?在生产环境中我们可以通过乐观锁机制来避免这个问题,所谓乐观锁,简单来说,就是在item表中建立一个version字段。假设某一个热卖商品的实际库存为n,处于性能考虑对于查询库存操作是不建议加for update的,那么在并发场景下,必然会导致多个用户拿到的stock和version都一样。因此当第1个用户成功扣减商品库存后,则需要将item表中的version加1,这样一来,当第2个用户扣减库存时,由于version不匹配,那么为了提升库存扣减的成功率,可以适当进行重试,如果库存不足,则说明商品已经售罄,反之扣减库存后version继续加1。关于在数据库中使用乐观锁扣减库存的伪代码,如下所示:

 

public void testStock(int num) {
if (version不一致时的重试次数阈值) {
    SELECT stock,version FROM item WHERE item_id=1;
if (如果查询的指定商品存在) {
if (判断stock是否够扣减) {
             UPDATE item SET version=version+1,stock=stock-1 WHERE 
                          item_id=1 AND version="+ version +";
if (扣减库存失败) {
/* version不一致时开始尝试重试 */
testStock(--num);
} else {
logger.info("扣减库存成功");
}
} else {
logger.warn("指定商品已售罄");
}
}
}
}

 

如果系统前端不配合做限流消峰等处理,随意放任大量的并发更新请求直接在数据库中扣减同一热卖商品的库存数据,这将会导致线程之间相互竞争InnoDB的行锁,由于数据库中针对同一行数据的更新操作是串行执行的,那么某一个线程在未释放锁之前,其余的线程将会全部阻塞在队列中等待拿锁,并发越高时,等待的线程也就会越多,这会严重影响数据库的TPS,从而导致RT线性上升,最终可能引发系统出现雪崩。

 

二、在Redis中扣减库存
InnoDB的行锁特性其实是一把利与弊都同样明显的双刃剑,在保证一致性的同时却降低了可用性,那么究竟应该如何保证大并发更新热点数据不会导致数据库沦为瓶颈这其实是秒杀、抢购场景下最核心的技术难题之一。可以尝试将热卖商品的库存扣减操作转移至数据库外,由于Redis的读/写能力要远胜过任何类型的关系型数据库,因此在Redis中实现库存扣减将会是一个不错的替代方案,这样一来,数据库中存储的商品库存可以理解为实际库存,而Redis中存储的商品库存则为实时库存。

 

在Redis中扣减热卖商品的库存,或许有同学会有疑问,Redis如何保证一致性呢?如何才能做到不超卖和少买呢?答案就是Redis提供的Watch命令来实现乐观锁,和基于MySQL的乐观锁机制一样,并发环境下,通过Watch命令对目标Key进行标记后,当事务提交时,如果监控到目标Key对应的值已经发生了改变,那么也就则意味着版本号发生了改变,因此这一次的事务提交操作就失败,如图1所示:

图1 利用Redis乐观锁扣减商品库存 

 

Redis中扣减热卖商品的库存主要是出于以下2个目的:

1、首先是为了避免在RDBMS中,多线程之间相互竞争InnoDB引擎的行锁导致RT上升,TPS下降,最终引发雪崩的问题;

2、其次是能够利用Redis与生俱来的高效读/写能力来提升系统的整体吞吐量。

 

三、利用“分裂”技巧巧妙地提升库存扣减成功率

这里跟大家分享一个笔者公司的业务场景,由于特务特点,我们整点的限时抢购往往是爆款+大库存(几万至十几万不等的库存数),我们都知道限时抢购的峰值其实就是秒杀,并且还伴随的大库存。相对于普通的秒杀场景而言,由于库存并不多,如果上游系统配合交易系统做好扩容、限流保护、隔离(业务隔离、数据隔离,以及系统隔离)、动静分离、localCache等措施,秒杀场景下就能够将绝大多数流量挡在系统上游,让用户流量像漏斗模型一样逐层减少,让流量始终保持在系统可处理的容量范围之内。

 

由于“变态”的业务特点,业务系统除了要承受亿级流量的冲击,交易系统还要想办法提升下单时的库存扣减成功率,这对于我们来说确实是一次挑战,因为在生产环境中,一次的不小心,将会带来灾难性的后果。我们都知道架构的意义是有序的对系统进行重构,不断减少系统的“熵”,让其不断进步,但架构调整的失误,将会是不可逆的,尤其是那些成熟且用户规模较大的网站。

 

我们都知道,秒杀活动开始后,能够抢购到心仪的产品,是非常不容的一件事情,因为在同一个单位时间内,除了你之外,还有别的用户也在下单,那么针对同一个爆款的WATCH碰撞概率将会被无情放大,成功率自然降低。如果是小库存,直接返回商品已经售罄即可,但是多大十几万的库存,让用户看得到,买不到,心里痒痒的似乎不太友好,并且运营策略上也希望能够快速消完这些库存好制造噱头。

 

你不用指望能够利用某一种数据库就能够即提升吞吐量又提升成功率,首先你需要搞明白的是,这是一个实打实的单点问题,要保证一致性,就必然会牺牲成功率,这个矛盾点,该怎么解决呢?我们目前采用的做法是在Redis中,将某一个SKU的Key,拆分成N个对应的subKeys,库存服务在扣减库存的时候,通过轮询路由策略路由到不同的subKey上来降低WATCH碰撞概率,达到大幅度提升下单成功率的目的,如图2所示:

图2 将parentKey分裂为n个subKeys

 

分裂的概念相信大家都已经清楚了,接下来笔者再跟大家分享关于分裂操作的具体细节和一些注意事项。支撑分裂操作的主要由2部分构成,首先是嵌入在库存服务中的路由组件,其次是分裂管理服务,路由组件的任务很简单,订阅配置中心的分裂规则,然后轮询路由到不同的subKeys上做扣减即可。而分裂管理服务则相对复杂,parentKey的分裂操作就由它负责,并且它还需要处理一些相关的库存聚合(subKeys库存聚合)和下拉(重新划分库存给subKeys)任务。

 

分裂了,必然需要对分裂信息进行管理,比如:运营后台对某一个parentKey进行大库存扣减、调整某一个parentKey的分裂数量,以及删除某一个parentKey的分裂规则。这些操作全都包含着以下2个动作:
1、库存聚合(subKeys库存聚合),并将subKey库存设置为0;
2、然后将聚合后的库存归还给目标parentKey;

 

由于聚合和归还并不在同一个事物中,如果因为某些原因导致执行异常,那就悲剧了。比如聚合库存的时候成功了,这时subKeys的库存已经被设置为0,用户是无法正常下单的,但还库存给parentKey这个动作失败了,将会导致商品少卖,所以需要依靠以下2点来尽量保证商品不少卖:
1、业务上增大Redis的重试次数;
2、如果Redis故障,告警后人工介入归还库存;

 

为什么要区分普通用户扣减库存和运营后台扣减库存?因为这是2个截然不同的概念,因为用户扣减库存,往往会受限于业务(比如限制1个用户1次能够购买的商品数量),但运营后台则不同,有时候可能因为人为原因导致库存设超,因此需要扣减大量的库存,但是如果扣减的库存数量大于每一个subKey持有的有效库存数,则无法完成扣减操作,所以针对运营后台的扣减我们提供有单独的扣减方法,首先会聚合subKeys的库存并将subKey持有的库存数设置为0,将扣减后的库存还给parentKey,再等待重新下拉分配库存给subKeys。在此大家需要注意,如果一个商品特别爆,用户并发越大,聚合再分配的时间窗口期就会越长。

 

有时候,subKeys之间的库存数可能存在不均匀的情况,那么当某一个subKey持有的库存被扣减完,且无回流库存以便下拉重新分配时,只要路由到这个subKey的库存扣减动作都会是失败的,用户就会存在看得到,买不到的不友好体验,因此可以在路由组件上做动作,当某一个subKey的库存已经消完后,本地需要做剔除动作,下次不路由到这个subKey上。

 

最后给大家一点建议,如果parentKey的分裂数量越多,库存扣减的成功率就会越大,当然分裂数量也不是越多越好,一般来说一个parentKey分裂为10-20个subKey就够了,相对以前已经拥有了10-20倍的下单扣减成功率提升。

转发前,请询问我,3Q!

分享到:
评论

相关推荐

    20年IT老民工苦心编撰成超大流量分布式系统架构解决方案文档.docx

    针对大促期间热点数据的处理问题,文章第四章提出了多级缓存+RedisCluster模式下的读/写分离方案,以及基于Redis乐观锁的库存扣减方案。这些方案不仅能够有效提高系统的读写性能,还能保证数据的一致性。 **2. 高...

    全球变风量(VAV)系统市场研究:年复合增长率(CAGR)为 5.8%

    在全球建筑行业不断追求节能与智能化发展的浪潮中,变风量(VAV)系统市场正展现出蓬勃的发展潜力。根据 QYResearch 报告出版商的深入调研统计,预计到 2031 年,全球变风量(VAV)系统市场销售额将飙升至 1241.3 亿元,在 2025 年至 2031 年期间,年复合增长率(CAGR)为 5.8%。这一令人瞩目的数据,不仅彰显了 VAV 系统在当今建筑领域的重要地位,更预示着其未来广阔的市场前景。​ 变风量系统的起源可追溯到 20 世纪 60 年代的美国。它犹如建筑空调系统中的 “智能管家”,能够敏锐地感知室内负荷或室内所需参数的变化,通过维持恒定的送风温度,自动、精准地调节空调系统的送风量,从而确保室内各项参数始终满足空调系统的严格要求。从系统构成来看,变风量系统主要由四个基本部分协同运作。变风量末端设备,包括 VAV 箱和室温控制器,如同系统的 “神经末梢”,负责接收室内环境变化的信号并做出初步响应;空气处理及输送设备则承担着对空气进行净化、加热、冷却等处理以及高效输送的重任;风管系统,涵盖新风、排风、送风、回风等管道,构建起了空气流通的 “高速公路”;而自动控制系统宛

    《基于YOLOv8的跆拳道训练系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    探究ChatGPT情感化交互对其用户情绪健康的多方法研究

    内容概要:本文探讨了ChatGPT这种高级语音模式的人工智能聊天机器人与用户的互动对其情绪健康的影响。研究采用了两种互补的方法:大规模平台数据分析和随机对照试验(RCT)。平台数据部分通过对超过400万次对话进行隐私保护的大规模自动化分析以及对4000多名用户的调查,揭示了高频率使用者表现出更多的情感依赖和较低的社会交往意愿。RCT部分则通过近1000名参与者为期28天的研究,发现语音模型相较于文本模型能带来更好的情绪健康效果,但长时间使用可能导致负面后果。此外,初始情绪状态较差的用户在使用更具吸引力的语音模型时,情绪有所改善。 适合人群:对人机交互、情感计算和社会心理学感兴趣的科研人员和技术开发者。 使用场景及目标:本研究旨在为AI聊天机器人的设计提供指导,确保它们不仅能满足任务需求,还能促进用户的心理健康。同时,也为政策制定者提供了关于AI伦理使用的思考。 其他说明:研究强调了长期使用AI聊天机器人可能带来的复杂心理效应,特别是对于那些已经感到孤独或社交孤立的人来说,过度依赖可能会加剧这些问题。未来的研究应该更加关注这些极端情况下的用户体验。

    Java反射性能优化:深入探讨setAccessible与MethodHandle的技术差异及应用场景

    Java 反射(Reflection)是一种强大的机制,允许程序在运行时检查和操作类的成员变量和方法。然而,传统的 `setAccessible(true)` 方式虽然便捷,但存在安全性问题,并且性能相对较低。在 Java 7 引入 `MethodHandle` 后,我们可以通过 `MethodHandles.Lookup.findVirtual()` 提供更优雅、高效的方式来访问对象属性。本文将对比这两种反射方式,并分析它们的优缺点。

    loongdomShop.tar.gz

    loongdomShop.tar.gz

    人工智能与人类行为对聊天机器人社会心理效应的纵向随机对照研究

    内容概要:本文探讨了不同交互模式(文本、中性语音、吸引人语音)和对话类型(开放式、非个人化、个人化)对聊天机器人使用者的心理社会效果(如孤独感、社交互动、情感依赖、不当使用)的影响。研究表明,在初期阶段,语音型聊天机器人比文本型更能缓解孤独感并减少情感依赖,但随着每日使用时间增加,这种优势逐渐消失,尤其是对于中性语音聊天机器人。此外,个人话题对话略微增加了孤独感,而非个人话题则导致更高的情感依赖。总体而言,高频率使用聊天机器人的用户表现出更多的孤独感、情感依赖和不当使用,同时减少了真实人际交往。研究还发现,某些个体特征(如依恋倾向、情绪回避)使用户更容易受到负面影响。 适合人群:心理学家、社会学家、人工智能研究人员以及关注心理健康和人机交互的专业人士。 使用场景及目标:①帮助理解不同类型聊天机器人对用户心理健康的潜在影响;②为设计更健康的人工智能系统提供指导;③制定政策和规范,确保聊天机器人的安全和有效使用。 其他说明:研究强调了进一步探索聊天机器人管理情感内容而不引发依赖或替代人际关系的重要性,呼吁更多跨学科的研究来评估长期影响。

    MP4575GF-Z 产品规格书

    MP4575GF-Z MP4575 TSSOP-20 降压型可调DC-DC电源芯片

    界面设计_SwiftUI_习惯养成_项目管理_1742850611.zip

    界面设计_SwiftUI_习惯养成_项目管理_1742850611.zip

    免安装版的logic软件包 支持波形实时查看 内含驱动文件

    免安装版的logic软件包。支持波形实时查看。内含驱动文件。

    基于Springboot+Mysql的学生毕业离校系统(含LW+PPT+源码+系统演示视频+安装说明).zip

    1. **系统名称**:学生毕业离校系统 2. **技术栈**:Java技术、MySQL数据库、Spring Boot框架、B/S架构、Tomcat服务器、Eclipse开发环境 3. **系统功能**: - **管理员功能**:首页、个人中心、学生管理、教师管理、离校信息管理、费用结算管理、论文审核管理、管理员管理、留言板管理、系统管理。 - **学生功能**:首页、个人中心、费用结算管理、论文审核管理、我的收藏管理。 - **教师功能**:首页、个人中心、学生管理、离校信息管理、费用结算管理、论文审核管理。

    WebSocket测试Demo程序

    配套文章:https://blog.csdn.net/gust2013/article/details/139608432

    蓝凌OA系统V15.0管理员手册

    蓝凌OA系统V15.0管理员手册

    《基于YOLOv8的生物样本识别系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    mips-gcc520-glibc222编译工具链.zip

    mips-gcc520-glibc222编译工具链.zip

    社交网络_React_Native_开发教程_学习资源_1742847416.zip

    app开发

    Swift编程语言的基础特性与应用开发入门教程

    内容概要:本文档详细介绍了Swift编程语言的基础知识,涵盖语言特点、基础语法、集合类型、控制流、函数定义、面向对象编程、可选类型、错误处理、协议与扩展以及内存管理等方面的内容。此外还简要提及了Swift与UIKit/SwiftUI的关系,并提供了进一步学习的资源推荐。通过这份文档,读者可以全面了解Swift的基本概念及其在iOS/macOS/watchOS/tvOS平台的应用开发中的使用方法。 适合人群:初学者或者希望从其他编程语言转向Swift的开发者。 使用场景及目标:帮助读者快速上手Swift编程,掌握其基本语法和特性,能够独立完成简单的程序编写任务,为进一步学习高级主题如并发编程、图形界面设计打下坚实的基础。 阅读建议:由于Swift是一门现代化的语言,拥有许多独特的特性和最佳实践方式,在学习过程中应当多加练习并尝试理解背后的原理。同时利用提供的官方文档和其他辅助材料加深印象。

    《基于YOLOv8的泰拳训练辅助系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    《基于YOLOv8的室内装修质量检测系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

    《基于YOLOv8的雕塑识别系统》(包含源码、完整数据集、可视化界面、部署教程)简单部署即可运行。功能完善、操作简单,适合毕设或课程设计.zip

    资源内项目源码是来自个人的毕业设计,代码都测试ok,包含源码、数据集、可视化页面和部署说明,可产生核心指标曲线图、混淆矩阵、F1分数曲线、精确率-召回率曲线、验证集预测结果、标签分布图。都是运行成功后才上传资源,毕设答辩评审绝对信服的保底85分以上,放心下载使用,拿来就能用。包含源码、数据集、可视化页面和部署说明一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.txt文件,仅供学习参考, 切勿用于商业用途。

Global site tag (gtag.js) - Google Analytics