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

如何正确处理大批量数据的业务

  •  
  •   ak1ak · 2023-02-09 09:13:26 +08:00 · 1915 次点击
    这是一个创建于 639 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Hello, all!

    数据库中有一大批待处理的数据,可能有百万量级,还会增长。希望定义一个接口,请求之后查询并处理好这些数据。 处理的逻辑可能涉及 RPC 之类耗时较长的代码。因此,我使用异步代码处理。伪代码如下:

    // 1.查询数据库
    List<Biz> bizs = queryDB();
    // 2.分批次
    List<List<Biz>> bizLists = Lists.partition(bizs, 1000);
    // 3.异步处理 list
    bizLists.forEach(list -> listAsyncService.handle(list));
    // 4.listAsyncService#handle 也是异步处理
    list.forEach(biz -> asyncService.handle(biz));
    

    请教一下,上述代码是否合理。在数据量很大的情况下,如何避免步骤 1 出现 OOM 。

    11 条回复    2023-02-09 11:09:02 +08:00
    tairan2006
        1
    tairan2006  
       2023-02-09 09:21:52 +08:00
    你这个应该用 rabbitmq 之类的做异步,长时间运行的流程靠开线程异步不靠谱,除非调用方能容忍失败。

    如果害怕第一步 OOM ,那你直接在第一步分页查数据库不就完了…
    ak1ak
        2
    ak1ak  
    OP
       2023-02-09 09:25:09 +08:00
    在主键为 id 的情况下,每次查询记录 min(id),并针对 min(id) 分页只处理部份数据,如 10000 条。SQL 这样写:

    ```sql
    select * from tb_biz where id > (select min(id) from tb_biz where 查询条件) and 查询条件 limit 10000
    ```

    这样的话,就需要多请求几次接口。
    ak1ak
        3
    ak1ak  
    OP
       2023-02-09 09:29:16 +08:00
    @tairan2006 这个业务的场景是处理一些历史数据,接口是提供给内部人员调用的。希望尽可能一次性处理比较多的数据,调用者不乐意传分页参数,只希望分页逻辑在后台做掉。
    NoString
        4
    NoString  
       2023-02-09 09:45:58 +08:00
    调用者不传你自己加分页,写个方法
    queryMinLimitData(Long minId,int limitCount)
    嫌慢多线程调这个方法
    imokkkk
        5
    imokkkk  
       2023-02-09 09:59:46 +08:00
    1 查完之后推给 MQ ,2 从 MQ 拉取到数据后再分成小批次交给线程池多线程去处理
    5boy
        6
    5boy  
       2023-02-09 10:10:08 +08:00
    楼上回复分页查的一看就是菜鸟。分页查完汇总不还是这么多数据吗?数据又不会少,还是会 oom
    wangxin3
        7
    wangxin3  
       2023-02-09 10:18:26 +08:00
    就是分页查询 然后发送到 MQ ,查一批发一批,内存占用转移到 MQ 中去,然后多开消费者按需消费 MQ 的数据。
    zzzzz001
        8
    zzzzz001  
       2023-02-09 10:55:05 +08:00
    简单点,在表里面加个同步字段,每次同步了就更新这条数据,你每次用 limit 1000 取 1000 条未同步的,无限循环下去,当没有返回就终止循环
    zzzzz001
        9
    zzzzz001  
       2023-02-09 11:01:37 +08:00
    @zzzzz001 这种方式我玩了很多次了
    beneo
        10
    beneo  
       2023-02-09 11:05:04 +08:00
    spring batch
    Juszoe
        11
    Juszoe  
       2023-02-09 11:09:02 +08:00
    使用数据流中间件
    我没用过,不负责任推荐 https://github.com/mage-ai/mage-ai
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1037 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 23:01 · PVG 07:01 · LAX 15:01 · JFK 18:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.