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 。
1
tairan2006 2023-02-09 09:21:52 +08:00
你这个应该用 rabbitmq 之类的做异步,长时间运行的流程靠开线程异步不靠谱,除非调用方能容忍失败。
如果害怕第一步 OOM ,那你直接在第一步分页查数据库不就完了… |
2
ak1ak OP 在主键为 id 的情况下,每次查询记录 min(id),并针对 min(id) 分页只处理部份数据,如 10000 条。SQL 这样写:
```sql select * from tb_biz where id > (select min(id) from tb_biz where 查询条件) and 查询条件 limit 10000 ``` 这样的话,就需要多请求几次接口。 |
3
ak1ak OP @tairan2006 这个业务的场景是处理一些历史数据,接口是提供给内部人员调用的。希望尽可能一次性处理比较多的数据,调用者不乐意传分页参数,只希望分页逻辑在后台做掉。
|
4
NoString 2023-02-09 09:45:58 +08:00
调用者不传你自己加分页,写个方法
queryMinLimitData(Long minId,int limitCount) 嫌慢多线程调这个方法 |
5
imokkkk 2023-02-09 09:59:46 +08:00
1 查完之后推给 MQ ,2 从 MQ 拉取到数据后再分成小批次交给线程池多线程去处理
|
6
5boy 2023-02-09 10:10:08 +08:00
楼上回复分页查的一看就是菜鸟。分页查完汇总不还是这么多数据吗?数据又不会少,还是会 oom
|
7
wangxin3 2023-02-09 10:18:26 +08:00
就是分页查询 然后发送到 MQ ,查一批发一批,内存占用转移到 MQ 中去,然后多开消费者按需消费 MQ 的数据。
|
8
zzzzz001 2023-02-09 10:55:05 +08:00
简单点,在表里面加个同步字段,每次同步了就更新这条数据,你每次用 limit 1000 取 1000 条未同步的,无限循环下去,当没有返回就终止循环
|
10
beneo 2023-02-09 11:05:04 +08:00
spring batch
|
11
Juszoe 2023-02-09 11:09:02 +08:00
使用数据流中间件
我没用过,不负责任推荐 https://github.com/mage-ai/mage-ai |