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

请教下微服务间大批量数据获取一般是如何处理的

  •  
  •   gibber · 1 天前 · 3314 次点击
    比如 a 服务需要从 b 服务获取几十万的数据处理后生成自己的业务数据,如果 b 服务直接从数据库中一次性查出来返回,对内存的压力就很大。
    现在的方案是使用分页,每次最多 1 万条记录,获取一批处理一批,把整个业务处理的时间拉长了。
    想知道还有没有更好的办法
    39 条回复    2024-10-17 18:56:18 +08:00
    ZGame
        1
    ZGame  
       1 天前
    1.内存压力大?一个作业才几十万数据。。 如果怕影响 a 库业务性能,直接给 a 库做一个从库,从从库里拉数据。
    2.走 cdc 那种从日志里读取,这种时效性会好点。我是感觉没必要
    csys
        2
    csys  
       1 天前 via Android
    1.
    b 服务把数据保存成文件
    a 服务下载文件后进行处理

    2. kafka/cdc
    securityCoding
        3
    securityCoding  
       1 天前
    单独落离线表,明令禁止直接从线上业务表捞数据
    ymz
        4
    ymz  
       1 天前
    kafka
    m2276699
        5
    m2276699  
       1 天前   ❤️ 1
    数据源之间冗余
    xiaohupro
        6
    xiaohupro  
       1 天前
    时间线拉长应该是由于同步导致的吧,查一万处理一万。可以把查处来的数据立马丢给 Kafka 或者 Rabbit MQ 这类消息队列,A 服务监听队列,只要有数据就一直处理,这样应该会分批同步处理快一些。
    sagaxu
        7
    sagaxu  
       1 天前
    这是两个步骤

    1. b 服务从 db 获取几十万条数据
    2. a 服务从 b 服务获取完整数据

    第二个步骤在分页之后,从 1 次 rpc 变成几十次,内网 rpc 的开销是毫秒级的,几十次 rpc 增加几十毫秒,不会显著拉长处理时间。

    那问题就出在第一步,db 端分页之后,几十次小量查询,开销远大于单次全量。这种情况就不建议分页,而是分批,b 服务一次查询分批读取,写入文件或者消息队列等暂存设施,返回给 a 的是数据的指向,a 自己再分批读取
    ymmud
        8
    ymmud  
       1 天前
    才几十万条,服务之间类似于流式处理直接拉过去就行了
    SmartTom
        9
    SmartTom  
       1 天前
    a 服务直接做多数据源直连 b 服务数据库/doge
    povsister
        10
    povsister  
       1 天前 via iPhone
    你这种 case 如果数据量持续上升,应该用 spark 这种离线作业,或者压根不应该拆分服务。
    Wh1t3zZ
        11
    Wh1t3zZ  
       1 天前
    流式数据处理
    Plutooo
        12
    Plutooo  
       1 天前
    把 B 服务当成直接从数据库查不也是存在一样的问题么,还是说担心 B 服务的内存占用
    landerwong99
        13
    landerwong99  
       1 天前
    要么就离线近源处理,来个服务直接调 B 库的只读库,
    要么就流式处理,使用 kafka 之类的。
    ZZ74
        14
    ZZ74  
       1 天前
    搞那么麻烦干啥,导出文件写入共享目录,调用接口通知 喂 数据我放到 xx 目录下的 x 文件里了
    lifei6671
        15
    lifei6671  
       1 天前
    一般情况下是通过下面方式实现的:
    1 、建立只读线下备库,通过从库的方式从线上库实时同步数据,不能用于线上系统读,只能用于线下业务大批量读。
    2 、建立只读从库,和主库实时同步,只能进行线上系统只读。
    3 、通过 binlog 实时建立分析宽表,一般用来汇总各个业务方数据,建立大宽表,支持线下业务分析已经大批量查询等。
    kaf
        16
    kaf  
       1 天前
    流格式数据
    8355
        17
    8355  
       1 天前
    有 id 能排序的话 传起始 id 过来就行了 where id > xx limit 10000 order by id asc
    8355
        18
    8355  
       1 天前
    其实数据没这么大,我的的业务天天导入 300m 的 csv ,200w 左右。
    只要不是一两百个字段带 text 的宽表数据 不会特别大的。
    fengpan567
        19
    fengpan567  
       1 天前
    没条件搞数据同步服务的,直接让对方生成一个 csv 上传到 oss ,你每天去捞当天的文件同步就行了
    print1024
        20
    print1024  
       1 天前
    如果数据库 id 是有序的话可以先排序,然后切分数据,如 1000 条一次,多线程处理,也就这样了,用中间件其实没太大必要
    cccssss
        21
    cccssss  
       1 天前
    直接读 b 库
    不让读的话只能说又想马儿跑又不给马儿吃草
    InkAndBanner
        22
    InkAndBanner  
       1 天前
    oss or 离线数仓,如果在线去拉的话 就算可行,ab 服务的 io 会不会被占满导致其他接口、服务不可用?
    bthulu
        23
    bthulu  
       1 天前
    获取一批处理一批, 怎么就把业务处理时间拉长了?
    你一次获取, 不还是要处理这么多?
    newaccount
        24
    newaccount  
       1 天前
    要么时间换空间,要么空间换时间
    你这又嫌内存占用大又嫌处理时间长的
    就算让 a 直接读 b 库,那内存占用无非是从 b 服务器转移到 a 服务器
    masterclock
        25
    masterclock  
       23 小时 59 分钟前
    看看能不能让 a 不依赖 b ,数据分别进 a 、b 服务
    如果 a 强依赖 b ,那就别微服务了,把 a 整合进 b ,或者 a 的这一部分功能整合到 b
    kchenzhi
        26
    kchenzhi  
       23 小时 9 分钟前
    这事我有经验。
    1 、不要在 responseBody 里返回, 那样内存一定会爆。
    2 、不要分页查询,两个原因:①不同分页的查询不在一个事务中,会有数据一致性的问题。②当查询到靠后的分页时,耗时直线上升,性能太差。
    kchenzhi
        27
    kchenzhi  
       23 小时 7 分钟前
    3 、如果能让 a 直接读库,那是一种解决方案。但如果 b 里有些处理逻辑比较复杂,那你得在 a 中重新实现一遍,重复工作量且代码冗余,不合适。

    我们最终采取的方案是:访问数据源时使用游标,一行行读取数据后,通过 http outputstream ,用流式返回。
    GeekGao
        28
    GeekGao  
       22 小时 25 分钟前
    时间换空间:小批次分批执行
    空间换时间:增加内存,大批量执行
    中间方案:放在共享存储(例如 nfs ),mmap 读文件,增加消费者进程消费
    clf
        29
    clf  
       22 小时 19 分钟前
    数据表做数据冗余吧。
    gibber
        30
    gibber  
    OP
       21 小时 20 分钟前
    @xiaohupro 就是一次查询改为多次查询后比较耗时,不太想引入额外的中间件来处理
    gibber
        31
    gibber  
    OP
       21 小时 10 分钟前
    @kchenzhi a 服务本地数据源的话是会使用流式查询的,倒是不清楚微服务调用也能使用流式处理的方式,感觉可以参考,谢谢
    molicloud
        32
    molicloud  
       19 小时 59 分钟前
    直接在 b 服务处理数据,再通知或调用 a 服务
    vacuitym
        33
    vacuitym  
       19 小时 51 分钟前
    定时生成文件给下载地址(这感觉很像对账单)
    asAnotherJack
        34
    asAnotherJack  
       19 小时 51 分钟前
    @kchenzhi #26 `当查询到靠后的分页时,耗时直线上升,性能太差。`
    盲猜是不是用的 limit offset 做的分页
    gibber
        35
    gibber  
    OP
       19 小时 29 分钟前
    @molicloud b 服务只负责从数据库查询数据,不处理具体业务
    notwaste
        36
    notwaste  
       19 小时 6 分钟前
    b 服务查出来往 kafka 里面丢,a 服务消费处理
    macttt
        37
    macttt  
       18 小时 50 分钟前
    A 服务提交一个任务给 B 服务,B 服务收到任务后推送数据给 A 服务。两个服务之间的数据完备性检查,你可以使用类似于 TCP 传输的形式。A 服务不用管 B 服务怎么实现的,只需要接收数据就行了,B 服务则需要让 A 服务记录数据完整性的元数据。
    snickers
        38
    snickers  
       18 小时 16 分钟前
    不建议走接口 ,ETL 转换调度
    molicloud
        39
    molicloud  
       16 小时 32 分钟前
    @gibber #35 在新建一个 b-analysis 服务,也连和 b 相同的数据库
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5693 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:29 · PVG 11:29 · LAX 20:29 · JFK 23:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.