V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
yellowmarlboro
V2EX  ›  Go 编程语言

用 golang 的做一个 pipeline | ETL 问题有什么好的设计?

  •  
  •   yellowmarlboro · 2021-04-09 11:54:15 +08:00 · 1210 次点击
    这是一个创建于 1335 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有 N 个数据源,根据这 N 个数据源计算出 M 个结果,依赖关系简单如下,实际会略微复杂些,但一定是个有向无环图。
    结果也有有可能会当成另外一个结果的'数据源'
    
        A     B
       / \   /
      /   \ /
     R1    R2     C
             \   /
              \ /
               R3
    
    
    有一些问题
    • 其他调用方会来调用我服务,调用的输入为字符串比如{"R2", "R3"}。
    • 每次要计算的结果的数量是不确定的,其他调用方可能只要 R1 和 R2,那我就不想去调用 C 数据源了。
    • 每个来调用接口的独立请求里,我这里的数据源我只想调用一次,比如我不想算 R1,R2 的时候获取两次 A 数据源,以及如果在算过 R2 之后,再去算 R3 的时候要再算一边 R2 。
    • 我想从下往上算,比如 R3 的逻辑里里 go 出去 R2 和 C,R2 里再 go 出去 A 和 B,那我后续算 R1 的时候,怎么直接取刚刚算 R2 时的获取过的 A,A 写成单例?只要被调用后,再次被调用返回数据源? -当然还有其他的,比如错误中断之类。
    2 条回复    2021-04-09 17:53:44 +08:00
    dayeye2006199
        1
    dayeye2006199  
       2021-04-09 12:29:17 +08:00   ❤️ 1
    > 其他调用方会来调用我服务,调用的输入为字符串比如{"R2", "R3"}。
    > 每次要计算的结果的数量是不确定的,其他调用方可能只要 R1 和 R2,那我就不想去调用 C 数据源了。

    这个操作叫 Cull,是图优化的一种。具体做法就是,对你需要的输出,例如{"R2", "R3"},获得它们的所有依赖,和依赖的依赖... 然后将图里面不属于依赖的节点删除,就得到一个精简以后的 DAG 。

    > 每个来调用接口的独立请求里,我这里的数据源我只想调用一次,比如我不想算 R1,R2 的时候获取两次 A 数据源,以及如果在算过 R2 之后,再去算 R3 的时候要再算一边 R2 。
    我想从下往上算,比如 R3 的逻辑里里 go 出去 R2 和 C,R2 里再 go 出去 A 和 B,那我后续算 R1 的时候,怎么直接取刚刚算 R2 时的获取过的 A,A 写成单例?只要被调用后,再次被调用返回数据源? -当然还有其他的,比如错误中断之类。

    计算的顺序可以将所有节点按照依赖关系进行拓扑排序,就可以保证一个节点计算的时候,它的所有依赖节点都是被计算过的。
    计算过的节点的结果,可以用个 dict 保存一下,下次需要的时候直接按照节点名称取出就不会重新触发计算了。
    yellowmarlboro
        2
    yellowmarlboro  
    OP
       2021-04-09 17:53:44 +08:00
    @dayeye2006199 受教 非常感谢~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1111 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:57 · PVG 02:57 · LAX 10:57 · JFK 13:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.