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

求教复杂规则简单计算的技术选型。

  •  
  •   evanlyu · 2018-12-17 10:59:58 +08:00 · 2327 次点击
    这是一个创建于 2152 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景: 需要在 5 分钟内计算完 5w 人的绩效工资,会有各种维护的计算公式和规则,规则复杂,但是都是简单的加减乘除运算,涉及计算的数据大约 50w,但是会重复计算,比如个人的要计算,多个人组成的团队的也要计算,几个团队组成的大团队也要计算。 数据库 mysql,后台开发语言 java。

    目前的思路: 1.mysql 存储过程去处理,压力全在数据库,老系统业务是用存储过程,但是是 oracle,且数据量没有这么大 2.java 去计算,效率和资源消耗问题,优点是目前开发人员都是 java 3.golang 计算,效率和并发比 java 快,缺点是需要从头开始学习 4.其他语言或工具

    大佬有无这种类似的业务场景,是如何实现的,谢谢!

    19 条回复    2018-12-17 14:36:13 +08:00
    leeg810312
        1
    leeg810312  
       2018-12-17 11:59:44 +08:00 via Android
    计算密集可以 Java 多线程处理。如果计算规则特别复杂,5 分钟可能无法完成,是不是可以做离线运算,在晚上空闲时间生成结果
    evanlyu
        2
    evanlyu  
    OP
       2018-12-17 12:03:38 +08:00
    @leeg810312 计算是在白天,且需要看到结果后在继续后续的操作。目前只把一些基础数据加工放到的晚上去跑,但是计算和规则还是要白天去跑
    XOXO360
        3
    XOXO360  
       2018-12-17 12:05:49 +08:00 via iPhone
    5w 人公司 oa 软件都省,难怪寒冬。
    zz052831
        4
    zz052831  
       2018-12-17 12:12:17 +08:00 via iPhone
    我觉得这种完没有必要实时计算出来啊,定时任务跑出来结果存储起来,需要的时候查一下不就好了。搞不懂哪里有实时算的必要
    memormou
        5
    memormou  
       2018-12-17 12:14:30 +08:00
    你这种场景,如果按照常规的逻辑来写,同一时间只计算一个人的,即使开了多线程(算你 24 线程)也没吊用,因为这不是解决计算密集型程序的正确打开方式,CPU 给你的 SSE、AVX 等指令集用不上,逻辑判断频繁插入在数值计算里打乱流水线,完全就是低能写法。要真想解决,你得专门写一个模块来搞计算,即一次性把整块的计算需求打包输入,设计好对编译器友好的数据结构,整块计算,整块提取结果,再用上多线程,这样才能快。
    evanlyu
        6
    evanlyu  
    OP
       2018-12-17 12:46:03 +08:00
    @XOXO360 不是 oa,这里的绩效是指的手续费,要根绝绩效算手续费。
    ziding
        7
    ziding  
       2018-12-17 12:46:50 +08:00
    这么简单的需求,最省心的就是 sql 到底。
    evanlyu
        8
    evanlyu  
    OP
       2018-12-17 12:48:17 +08:00
    @memormou 是的,重构的第一个思路就是用 golang 去做这块的计算,但是目前团队的人对这块不熟悉,所以前来请教一番。
    lihongjie0209
        9
    lihongjie0209  
       2018-12-17 12:59:11 +08:00
    但是会重复计算,比如个人的要计算,多个人组成的团队的也要计算,几个团队组成的大团队也要计算。


    缓存一份不就好了
    lihongjie0209
        10
    lihongjie0209  
       2018-12-17 13:01:09 +08:00
    而且 50w 的数据怎么加载到内存都是问题, 如果你是需要一直查询数据的话, 我觉得瓶颈在数据库.
    如果一次全部加载到内存, 才能进行计算上的优化
    ziding
        11
    ziding  
       2018-12-17 13:16:00 +08:00
    @lihongjie0209 你想的太多了,才 50 万数据,根本不用考虑那么多,一个批次 3000 条的处理就完全足够了。
    FallenTy
        12
    FallenTy  
       2018-12-17 13:56:02 +08:00
    使用场景呢,要即时获取还是非即时。
    非即时的话随便用什么方法,半夜跑个批就行了。即时获取的话也看你们对速度有多大需求以及准备投入的时间了,最简单的肯定还是用开发人员熟悉的语言。
    whileFalse
        13
    whileFalse  
       2018-12-17 14:08:11 +08:00
    select * from tablename
    内存里算完事~

    这个数据量这个时间要求真是随便搞就行。
    lihongjie0209
        14
    lihongjie0209  
       2018-12-17 14:16:45 +08:00
    @ziding 考虑过数据依赖的问题吗?
    ziding
        15
    ziding  
       2018-12-17 14:26:15 +08:00
    @lihongjie0209 依赖数据批量加载进去,按批次处理,3000 条数据依赖也不会太多。关键在于数据要批量加载、处理、保存。
    vincenttone
        16
    vincenttone  
       2018-12-17 14:31:10 +08:00
    明明只有 5w 的数据,5 分钟时间,不至于多复杂吧。。。这些数据存文件里写个 shell 都能在五分钟内搞定吧。。。
    反而楼主要注意的是浮点数的运算问题
    Zane0001
        17
    Zane0001  
       2018-12-17 14:32:46 +08:00
    我也觉得直接 sql 完事了。
    不管你 join 多少表,直接建立 view 视图,把依赖的数据字段、计算公式等映射成一张“表”。

    oracle 里面有物化视图,一点毛病都没有。
    evanlyu
        18
    evanlyu  
    OP
       2018-12-17 14:33:28 +08:00
    谢谢大佬,现在准备去用 2、3 分别搞个 demo 去验证下。
    qieqie
        19
    qieqie  
       2018-12-17 14:36:13 +08:00
    @evanlyu 为什么是 golang,go 编译器又不能-mavx, -ftree-vectorize。不过我觉得你这个量级基本没什么压力,要优化手动把一些批量计算写成矩阵的就行了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2348 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 16:10 · PVG 00:10 · LAX 08:10 · JFK 11:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.