V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nano91
V2EX  ›  程序员

关于订单数据统计的问题

  •  
  •   nano91 ·
    MaxZzyo · 2020-12-11 17:24:16 +08:00 · 1298 次点击
    这是一个创建于 1448 天前的主题,其中的信息可能已经有所发展或是发生改变。

    要求:实时获取当天订单的数据,比如今天 17:00 要获取的是 00:00-17:00 的数据

    当时的设计:用户下单的时候用异步队列处理数据统计部分,不要影响正常的订单流程,这样订单表和订单统计表就完全独立,但是具体的方案是 有一个日志表 log 去记录所有和订单有关的操作(下单-支付-退款等),并且每一步操作也有具体的金额相关字段, 但是问题就在于 前面提到的异步队列 是定时的从 log 表去读这些操作日志 然后把响应的金额、数量等数据 写入订单统计表 所以做不到实时拿到当前整个平台的订单数据

    问题: 1 、虽然 log 表确实必须得有,但是订单的统计为什么不能直接在订单操作的过程中直接把相关的数据写入统计表,而是要异步的定时任务去做?(比如支付后除了去继续进行订单流程外,还要把金额直接加到统计表中,而不是定时任务去统计) 2 、这样的设计有什么好处吗? 3 、更合适的方案是怎样的?

    这个是以前的公司参与过的项目,但是问设计的人也没说为什么这样做

    crclz
        1
    crclz  
       2020-12-11 20:44:18 +08:00
    > 问题 1 、虽然 log 表确实必须得有,但是订单的统计为什么不能直接在订单操作的过程中直接把相关的数据写入统计表,而是要异步的定时任务去做?

    因为统计数据的更新是订单操作事件的**副作用**。

    副作用是一定会成功的,因为并没有事务关系(如果你下单成功了,那么统计数据中的订单数量一定能够加 1,没有业务规则能够阻碍统计数据的改变)。

    如果你把订单操作和副作用放在同一个事务里面,那么就会降低响应时间和吞吐量。


    > 2 、这样的设计有什么好处吗?

    第一,解耦。订单处理只需要考虑怎么处理订单,以及订单的操作应当写哪些日志。至于日志怎么做统计信息,订单处理的程序不需要考虑。

    第二,batching 。如果日志处理和修改某些统计信息可以是批量的,那么这种 batching 可以提升速度( 10 次订单数量+1 操作,vs 1 次订单数量+10 操作)

    > 3 、更合适的方案是怎样的?

    首先,如果想要做到实时,可以考虑“推”方式的消息队列。

    其次,如果系统本身并发要求不高,那么应当采取把订单操作和副作用放在同一个事务里面进行提交,这可以**简化编程**。

    原来的方案虽然性能较好,但是把副作用从事务里拆出,需要保证两点:1. log 是 1 次或多次送达的。2. log 可以被重复消费。

    第一点可以使用 outbox pattern + ack 来保证;第二点可以让消费者建立去重表。 我所说的这两点是标准的解决方案。

    可以看出提升性能的代价就是开发复杂度的增加。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3225 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 12:56 · PVG 20:56 · LAX 04:56 · JFK 07:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.