批量订单(大概是每个用户1W订单)处理的最优方案或思路是什么?

系统的订单是从excel表导入的。每个用户可以提交1、2万的订单,订单提交后,还要根据订单金额扣除用户相应的金额。

还要及时反馈1、2万订单成功多少,失败多少,从用户扣除订单金额,这个过程怎么处理才是最优解呢?

我现在的做法是,提交后。

1、从redis取出所有产品的库存信息。
2、循环处理订单,把0库存的剔除,把有库存产品累计金额。
3、队列把有库存的订单,用队列写mysql(批量插入)
4、扣除用户余额。

实践中发现以上做法不严谨,有时mysql插入失败。还是会扣除累计成功的用户余额。

PS:
整个过程耗时大概是PHP2秒左右,但是有同类型的系统(ASP.NET写的,不是PHP),几乎能做到5、600毫秒能反馈。
请问这个是PHP的问题?做不到这么短时间的响应速度,还是我自己优化不足呢?

我测试过流程时间, 以上流程,1、耗时0.7s 2、耗时1.2s

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 15
sanders

我分析一下,先从表设计开始:

  1. 准备一张导入批次和导入批次订单表,这两张表用来存储导入的数据,不做校验或尽量少的进行校验,直接批量入库,这可以让入库过程效率最大化;
  2. 异步生成订单,生成的过程中校验商品库存等信息,并将生成的结果写入导入批次订单表的状态字段和返回信息字段,并同步扣减用户余额;
  3. 处理完整个批次再标识当前批次处理完成状态。

如果是“及时”而非“实时”以上操作可以最大限度的满足效率需求,如果要保证写入速度采用的是多主库尽量避免使用自增ID主键。 最终的扣减结果和生成订单结果根据批次、批次订单和订单表结合查询获取。

8个月前 评论
Xiaoxiaoww (楼主) 8个月前
sanders (作者) 8个月前

一两万一个的订单还是订单总额一两万, 还是一两万个订单?

8个月前 评论
Xiaoxiaoww (楼主) 8个月前

没怎么听懂

8个月前 评论

去了解用户真正的需求是什么?真的需要当下就放回所有订单的结果吗?

如果不是,其实可以把每个 Excel 上传的操作视为一次导入任务,而这个任务是异步来处理的,下面每个订单是一个子任务,在子任务的处理过程中用事物保证一致性!并实时反馈处理进度,用户能实时看到正在处理那个订单,已经订单是导入成功了还是失败了,失败的原因是什么,而且这种方式对于失败的订单处理可操作空间更大!

8个月前 评论
Xiaoxiaoww (楼主) 8个月前

excel扩展建议换成xlswriter,速度能提升很多

8个月前 评论
沈小明 8个月前

相比excel订单导入,建议订单数据实时同步,订单状态扭转,支付数据联动更新

8个月前 评论
Xiaoxiaoww (楼主) 8个月前
巴啦啦
  1. 排查问题。耗时是花在了解析excel文件上,还是数据库操作上。
  2. 排查一下从redis中取出所有商品所需时间。如果可以建议一次性查出有库存的商品。大量从redis中存取大数据量,会引发阻塞,也有可能是其他进程对redis的操作,引起了本次操作。对比一下从数据库直接取数据,只取有用的信息。
  3. 一次性查出有余额的用户。
  4. 根据表结构设计不同,批量插入,不同数量有不同的效果,可以测试一下,每次插入多少,耗时最少。刚开始,直接测2万。
  5. 排查下有没有操作,对订单表和用户表进行锁表操作,这也有可能会导致等待,变慢。
8个月前 评论
  1. ASP.NET 500ms,php 2s 这个结果会不会语言性能带来的差异呢? php 解释性语言,ASP.NET 可是编译强类型语言。
  2. 插入失败原因是什么呢? 插入失败,余额更新完成,你是否开启事务操作?
  3. 一个用户提交都是几万记录,多个用户提交过来岂不是很大数据量,这怎么可能做到系统及时性。
  4. 文件上传完成,丢入队列多开几个worker进程去处理任务,但是要做好并发安全,这样看看性能会不会提升一些。
  5. 由于你已经把任务丢队列中处理,失败的任务同步一下到数据库就行了。
8个月前 评论

拿到数据后, 先按照商品汇总, 然后按照商品ID分发到多个(线程 协程 or 异步任务)内, 每个任务处理100个商品, 最后汇总结果返给前端即可.

这种任务看起来主要耗时在表格解析以及数据库写入, 速度差那么多, 大概率竞品是多线程进行了异步处理

8个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!