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

API 的设计问题

  •  
  •   hujianxin · 2016-11-28 09:19:43 +08:00 · 2921 次点击
    这是一个创建于 2711 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大家好,我需要在数据库获取十几万条数据,然后通过得到的这些数据,计算得到十几个参数(统计计算:方差、极差等)。

    现在的任务是,需要从前端得到这所有的十几万条数据,以及另外计算得到的十几个参数。其宗问题是,在数据库中获取数据的过程非常慢,大约的两分钟。

    现在我有几种解决方案:

    1. 后端得到这十几万条数据,后端提供一个 api ,用来处理前端的 get 请求,将这些数据发送到前端,然后在前端计算另外的十几个参数。这里有可能占用内存较大,而且需要客户端来完成计算。
    2. 后端得到这十几万条数据,然后将这些数据存储为一个类的类变量。后端提供多个 api ,首先要有得到十几万条结果数据的 api ,还要有另外的十几个 api 用来分别得到另外十几个参数,也就是说例如需要得到方差的时候,使用类里面存储的十几万条结果实时计算得到。这个设计的问题,可能是这十几万条数据比较占用内存,在后端长期驻留。
    3. 后端同样提供多个 api ,像上面一样。但是,那十几条参数的 api 都不涉及计算,而是在获取十几万条结果数据的 api 里面计算得到,然后存储到类的私有变量里面。十几条参数的 api 仅仅是这些似有成员的 getter 就可以。这个设计的问题可能是不统一,因为前端必须先调用获取十几万条结果的 api ,才能调用其他的 api ,否则得到的结果是假的结果。但是这个设计对内存友好,因为只是在一个函数里面存储了十几万条数据,等出了这个函数就垃圾回收了。
    4. 最后一种方案是只提供一个 api ,这个 api 返回一个 json 。 json 里面除了提供十几万条结果数据之外,还提供另外的十几个参数。

    描述的可能比较麻烦,非常感谢大家能为我指点迷津!感谢

    26 条回复    2016-11-29 02:54:45 +08:00
    sagaxu
        1
    sagaxu  
       2016-11-28 09:29:21 +08:00 via Android
    4 最好
    sarices
        2
    sarices  
       2016-11-28 09:31:38 +08:00
    大量数据还是服务端运算吧,毕竟浏览器效率提不上去
    lslqtz
        3
    lslqtz  
       2016-11-28 09:32:19 +08:00
    只提供一个 api ,这个 api 返回一个 json 。只提供另外的十几个参数。
    返回几十万条太费资源,浏览器也容易卡死。
    这属于在服务端计算,那么大的数量,建议不要传给客户端耗费带宽。
    kimchan
        4
    kimchan  
       2016-11-28 09:35:27 +08:00
    同三楼...json 把十几万条数据返回......真的大丈夫?
    jimzhong
        5
    jimzhong  
       2016-11-28 09:50:38 +08:00
    用任务队列吧,前端先把数据上传给后端,后端开始计算。前端定期 poll 计算状态,直到取得结果。
    十几万条数据交给前端浏览器算会消耗很多内存的。
    lrh3321
        6
    lrh3321  
       2016-11-28 10:24:34 +08:00
    对实时性要求不高的话就提前算好,存另一个表里,然后定时更新
    sagaxu
        7
    sagaxu  
       2016-11-28 10:33:09 +08:00
    @lslqtz 需求里客户端需要那十几万条数据的,不然也不会傻到发送给客户端了。除了分页慢慢传,还能有什么办法?
    just4test
        8
    just4test  
       2016-11-28 10:39:39 +08:00
    能描述下是什么业务场景需要把这些数据放在客户端吗?我觉得这个设计从根本上就有问题。
    hujianxin
        9
    hujianxin  
    OP
       2016-11-28 10:49:11 +08:00
    @lslqtz @kimchan 谢谢回复,我打算压缩之后在传送,这个应该可以接受吧
    hujianxin
        10
    hujianxin  
    OP
       2016-11-28 10:49:35 +08:00
    @jimzhong 谢谢,任务队列这个我了解一下去
    hujianxin
        11
    hujianxin  
    OP
       2016-11-28 10:50:35 +08:00
    @sagaxu @just4test 客户要求我们做数据可视化,将数据的分布情况显示到网页上,请教一下,有好的方法,不需要将数据传到前端吗?感谢
    just4test
        12
    just4test  
       2016-11-28 10:53:35 +08:00
    另外,考虑到这十几万条数据数据的更新频率(业务上不可能,也做不到要求完全实时的最新数据。毕竟从查数据库到返回结果也要十多分钟),可以把楼主说的第 4 项的返回值存成一个静态文件,还可以 zip 一下。然后提供一个接口返回该 zip 的下载地址即可。按业务需求,每隔一段时间生成一个新文件(不马上把旧的删除,因为可能还有客户端正在下载该旧文件),然后那个接口指向新文件的下载地址。



    @sarices
    @sagaxu
    @lslqtz
    我还是觉得楼主的设计从根本上就有问题。
    kimchan
        13
    kimchan  
       2016-11-28 10:53:47 +08:00
    @hujianxin 具体是怎么个压缩法? 如果压缩后还是很大. 浏览器渲染会很慢. 任务队列是个方法. 另外. 计算结果是否可以放缓存? 还是说计算结果会经常变?
    tomczhen
        14
    tomczhen  
       2016-11-28 10:53:54 +08:00
    x-y problem
    shibingsw
        15
    shibingsw  
       2016-11-28 10:59:00 +08:00
    x-y problem
    just4test
        16
    just4test  
       2016-11-28 10:59:57 +08:00
    @hujianxin 你觉得可视化需要在一个页面里描绘十几万个点吗?
    听说过抽样和统计吗?
    如果觉得抽样统计还不能满足需求,就在服务器上把图画好了再发过去。
    windyboy
        17
    windyboy  
       2016-11-28 11:00:30 +08:00
    从前端获得十几万条数据是什么意思?
    Bryan0Z
        18
    Bryan0Z  
       2016-11-28 11:09:12 +08:00 via Android
    几十万条数据压缩一下,也就几兆啊,为啥不能传…
    scys
        19
    scys  
       2016-11-28 11:52:24 +08:00
    不要小看前端处理能力 -_-
    ---

    感觉是不复杂的数据结构:大数据性能测试
    http://www.supcan.cn/solution/server17.htm
    scys
        20
    scys  
       2016-11-28 11:58:05 +08:00
    感觉楼主要考虑的是后端缓存,前端考虑的是绘制的程度,你确定要绘制那么精细的图表?
    没讲过那么精细的图表就是,如果有了缓存,你就可以抽样,比如 1/2 这样返回。
    你的 IO 压力减少了,同时各个函数间如果同意用一分缓存,连内存压力也减少了。
    前端也能减少数据获取量,你的 CDN 也能减少传输量了。

    ---
    你究竟遇到啥问题,好像和你数量级没啥关系就是。
    nicevar
        21
    nicevar  
       2016-11-28 12:06:00 +08:00
    不是专业做服务器开发的,有个建议,可以考虑中间用 mongodb 过度,有公司是这样做的
    hujianxin
        22
    hujianxin  
    OP
       2016-11-28 12:06:05 +08:00
    @just4test 抽样的方法是个好办法,我回去仔细想想。
    @kimchan 我的数据不是实时的,是点一下按钮,然后开始计算,然后现实。
    hujianxin
        23
    hujianxin  
    OP
       2016-11-28 12:07:20 +08:00
    @scys 谢谢提供思路,我确实可以不用把全部的数据弄过来,谢了。
    Miy4mori
        24
    Miy4mori  
       2016-11-29 01:53:32 +08:00 via Android
    见过一个请求 6mb 的应用,用 ng2 做客户端排序和搜索,除了加载慢点也没啥毛病。客户端崩溃是不太可能的,浏览器还没娇惯到存十几兆数据就崩溃。其实我有一次用 js 读了 1g 的视频文件到内存里都没有崩溃,就是多吃了点内存………
    Miy4mori
        25
    Miy4mori  
       2016-11-29 01:55:11 +08:00 via Android
    我觉得你要考虑考虑如果这个接口并发高了服务端会不会崩溃
    lslqtz
        26
    lslqtz  
       2016-11-29 02:54:45 +08:00
    @hujianxin 数据可视化的话,就分页+一些算好的数据传过去就好了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   819 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 22:32 · PVG 06:32 · LAX 15:32 · JFK 18:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.