管理大量 Python 3 数据分析小脚本的最佳方案是什么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
locktionc
V2EX    问与答

管理大量 Python 3 数据分析小脚本的最佳方案是什么?

  •  
  •   locktionc 2018-03-06 19:07:23 +08:00 3488 次点击
    这是一个创建于 2852 天前的主题,其中的信息可能已经有所发展或是发生改变。

    应用场景

    有一个原始数据库 A,里面包含所有需要的数据。

    • 脚本 1. 从 A 中捞出每天新增的数据,去重后塞入数据库 B
    • 脚本 2:从 A 中捞出每天新增数据,计算与昨日相比的增量并发邮件
    • 脚本 3:从 B 中捞出每天的新增数据,计算与昨日相比的增量并发邮件
    • 脚本 4: 从 B 中捞出所有 tag 为'video'的数据,把它们的 ID 和所有 tag 为'news'的数据进行对比,找出'title'相同的记录
    • 脚本 5:从 B 中捞出数据,查询 Solr,把查询到的数据中的某些字段与 B 中的数据合并,然后写入数据库 C
    • 脚本 6,7,8,9,10,……

    例子中主要是数据分析的脚本,在实际中不仅限于此,还有不少 log 分析的脚本,警报脚本等等。

    这样的需要定时运行的小脚本有 40 多个。现在全靠 crontab 和 jenkins 运行,已经感觉难以管理了。

    对于这些要长不长,要短不短的小脚本,大家有什么比较好的管理方案吗?

    需求

    1. 支持定时启动

    2. 满足某些条件(某个脚本运行完,某个脚本的输出结果满足什么条件等等)启动

    3. 热拔插,添加 /修改新脚本不影响老脚本

    4. 新脚本可以轻松获取某个或者某些老脚本的输出结果

    5. 脚本量大了以后,快速找到实现某个功能的脚本文件以方便排查问题

    在 Python 2 时代,有一个 Frabic 可以大致实现这个功能,不知道在 Python 3 时代,有没有更好的方式?

    14 条回复    2018-03-07 23:27:05 +08:00
    simple2025
        1
    simple2025  
       2018-03-06 22:16:19 +08:00 via iPhone
    这不是写文档的作用吗
    locktionc
        2
    locktionc  
    OP
       2018-03-06 23:25:34 +08:00
    @chenqh 文档不能解决小脚本的调度和组合的问题。
    ToT
        3
    ToT  
       2018-03-07 04:21:09 +08:00
    公司内部有 scheduler, 可以将任何 job 部署到指定 nodes 运行,可以订制时间+dependency。Python 应该也有类似 lib 吧。
    http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html


    小报告多的话,我是单独写一个 UI 让大家查看的。
    bxh566
        4
    bxh566  
       2018-03-07 07:45:14 +08:00 via Android
    luigi?
    locktionc
        5
    locktionc  
    OP
       2018-03-07 08:12:16 +08:00 via iPhone
    @bxh566 我看看
    httplife
        6
    httplife  
       2018-03-07 08:22:17 +08:00
    再写一个 管理 py
    locktionc
        7
    locktionc  
    OP
       2018-03-07 09:01:48 +08:00 via iPhone
    @httplife 实在找不到更好的情况下,也只有这样做了。
    udumbara
        8
    udumbara  
       2018-03-07 09:03:54 +08:00 via Android
    airflow
    monsterxx03
        9
    monsterxx03  
       2018-03-07 10:04:04 +08:00
    用过 luigi, airflow, 这些为了 ETL 做的工具不太适合管理这些脚本,这些工具都需要脚本做适配, 我们的问题是脚本数太多,还是分散到好多人写的,最后框架还是自己写的,给每个脚本写一段 yaml 的配置定义:

    daily_log_cal:
    type: call
    once: per_day
    timeout: 600
    func: 'path.to.moudule:main'
    args:
    - a
    - b
    kwargs:
    c: 1
    slack:
    - '@somebody'
    deps:
    - upstream_job1

    每个脚本暴露一个 main 入口函数, 可以从 yaml 中传入参数, 用子进程来运行每个任务,防止一些脚本写的有问题耗内存太多不释放, 用 signal 实现超时控制, 任务运行失败直接 slack 通知到人, deps 定义一个简单的 DAG 依赖管理, 上游任务失败直接跳过.

    还可以根据需求定制一些其他类型的任务,比如 type: sql, 就是制定一个 sql 文件,直接在数据仓库里执行(一般是刷新一些表).

    至于运行启动时间, 如果任务有精确到几点几分的要求就单独设置 cronjob,如果只是要求 hourly 或者 daily 运行一次,就定制一个任务 list 作为入口,用 cronjob 触发.
    locktionc
        10
    locktionc  
    OP
       2018-03-07 10:12:54 +08:00
    @monsterxx03 yaml 对缩进太敏感了。实在要自己写的话,我们可能会用 ini 或者 json
    iyaozhen
        11
    iyaozhen  
       2018-03-07 10:17:11 +08:00 via Android
    @locktionc 哥你都用游标卡尺了。还怕配置文件的缩进。yaml 用作配置文件比 json 和 ini 体验好很多
    wibile
        12
    wibile  
       2018-03-07 10:21:36 +08:00
    airflow
    locktionc
        13
    locktionc  
    OP
       208-03-07 17:22:51 +08:00
    @wibile 我看看
    RangerWolf
        14
    RangerWolf  
       2018-03-07 23:27:05 +08:00
    遇到同样的问题!
    没有什么太好的解决方案, 目前也是 crontab 为主。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2771 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 02:23 PVG 10:23 LAX 18:23 JFK 21:23
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86