Python 有无某种实现 Checkpoint / Snapshot 的包? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
CatCode
V2EX    Python

Python 有无某种实现 Checkpoint / Snapshot 的包?

  •  
  •   CatCode 2022-05-09 15:43:54 +08:00 3617 次点击
    这是一个创建于 1317 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求:一个步骤非常多,执行时间很长的脚本。在其中某些时刻,可以创建一个检查点文件,把当前状态(变量、执行上下文之类的)给保存下来。如果当前进程在某个时刻因为某些原因被 kill 了,可以从之前保存的检查点处继续(除了系统时间、进程号之类的变了,其他的都一样)。就像游戏里面的手动存档机制一样。

    类似于:

    a = do_something() checkpoint.save("ck01.bin") b = do_other_thing1(a) do_other_thing2(a, b) 

    例如正在执行do_other_thing2(a, b)的时候被 kill 了,可以恢复从ck01.bin文件里面恢复

    checkpoint.load("ck01.bin") checkpoint.continue() 

    就会从b = do_other_thing1(a)处开始重新执行。

    不知道 V 友们有没有见过比较成熟的实现类似功能的包,或者需要参考哪些方面的内容。 (很久之前我自己是糊了一个,但是用起来限制太大。所有要保存的参数必须放到一个字典里面,并且各种手动传递,非常蛋疼)

    第 1 条附言    2022-05-09 16:21:11 +08:00
    不考虑多线程 /多进程
    22 条回复    2022-05-10 11:25:34 +08:00
    est
        1
    est  
       2022-05-09 15:47:05 +08:00
    请使用泡菜(pickle)模块
    xupefei
        2
    xupefei  
       2022-05-09 15:47:06 +08:00 via iPhone
    dill
    Latin
        3
    Latin  
       2022-05-09 15:49:59 +08:00
    gh 关键词检索
    发现以下适配你需求的东西
    https://github.com/a-rahimi/python-checkpointing2
    mobbdeep
        4
    mobbdeep  
       2022-05-09 15:50:36 +08:00   1
    @est pickle 应该是酸黄瓜吧
    bbbbbbbbbyron
        5
    bbbbbbbbbyron  
       2022-05-09 15:56:19 +08:00
    可以试试 joblib, 提供自动的 checkpoint 管理
    CatCode
        6
    CatCode  
    OP
       2022-05-09 15:58:34 +08:00
    @est 要实现的话 pickle 肯定是要用到的。我想要的是更高基本的 api
    CatCode
        7
    CatCode  
    OP
       2022-05-09 16:39:05 +08:00
    joblib 似乎不是专为这个目的开发的,看了一下官网的例子 用起来似乎不那么直观,更多的是用于缓存某些变量的计算进度。

    python-checkpointing2 似乎对 CPython 的依赖度非常高,如果不采用 CPython 可能会炸
    dill 似乎也非常依赖于 CPython ?看了 dill 的 test_session.py 依然云里雾里,不知道怎么用
        8
    catsoul  
       2022-05-09 16:41:24 +08:00
    @CatCode 总得牺牲一点代价的,要不就只能自己上...
    LeeReamond
        9
    LeeReamond  
       2022-05-09 17:21:12 +08:00
    @CatCode 感觉 cpython 似乎并无此类功能,要不然 jupyter notebook 也无需用到 ironpython 。自己实现的话多进程显然是一个简单的方案,特定点位 fork 一下就什么都有了,如果一定要落盘的话,就算追踪字节码能够实现某种程度的状态保存,遇到不可序列化的或者复杂对象也不太好办
    lolizeppelin
        10
    lolizeppelin  
       2022-05-09 18:26:23 +08:00
    taskflow 支持保存

    但是只能保存基本数据结构,自定义类可以和字典互相转化就可以保存

    或者说 taskflow 就是干这个的
    lolizeppelin
        11
    lolizeppelin  
       2022-05-09 18:26:47 +08:00
    lolizeppelin
        12
    lolizeppelin  
       2022-05-09 18:30:30 +08:00
    哦你要保存本身进程信息啊...额这...
    推荐错了
    CatCode
        13
    CatCode  
    OP
       2022-05-09 18:36:25 +08:00
    @lolizeppelin 233333
    不过这个我大概看了一下文档,也获得了一些“如果要自己做,哪些功能可以搞一搞”的启发
    lolizeppelin
        14
    lolizeppelin  
       2022-05-09 19:27:29 +08:00
    -_,- 如果可以参考直接用也是不错的
    这玩意本来就是用来处理复杂冗长的虚拟机创建流程而开发的
    ch2
        15
    ch2  
       2022-05-09 19:38:03 +08:00
    你想要这么 toplevel 的 api ,不太可能
    你用的端口、pid 、文件被别的进程占用或者改动了咋办?你建立的 tcp 长连接被 reset 了咋办?直接 crash?
    对整个进程 checkpoint 的工具确实有,它叫 CRIU
    不过如果你不配合容器一起用,这玩意基本上没有可用性的
    而且它对进程 checkpoint 之后的外部环境不可变性要求非常高,提到的那几个条件必须全部满足才能保证 restore 后的进程仍然能跑
    sujin190
        16
    sujin190  
       2022-05-09 19:42:26 +08:00
    pyflink 这种能满足?
    CatCode
        17
    CatCode  
    OP
       2022-05-09 22:30:34 +08:00
    @ch2 我既然有这个需求,端口、文件、TCP 连接这些肯定会添加额外的代码处理,或者这些方面,我添加检查点的位置会在没有 TCP 链接、所有打开的文件已经关闭这种情况下进行。类比于游戏,游戏里可不是随时都能手动存档的。
    换句话说,我要处理的任务可能是分段的:前一段和后一段不搭着,只有一些变量要传递。
    ch2
        18
    ch2  
       2022-05-10 00:01:35 +08:00
    @CatCode #17 在你能够保证严格的外部条件不变的情况下,可以手动调用 docker checkpoint create 命令将 python 进程制作为快照,再使用 docker checkpoint restore 命令进行还原:
    https://docs.docker.com/engine/reference/commandline/checkpoint/
    CatCode
        19
    CatCode  
    OP
       2022-05-10 08:31:40 +08:00
    @ch2 这个是依赖于 docker 的 依赖外部环境而不是 Python 本身了
    如果可以考虑外部软件,不考虑“重量”的话,直接用虚拟机快照效果更好,端口文件那些都不需要考虑了(笑)
    我期望的是 Python 自身实现
    ch2
        20
    ch2  
       2022-05-10 10:21:00 +08:00 via iPhone
    @CatCode 你可以参考 CRIU 的代码,为了保存和恢复一个进程的运行时状态他们做了多少 hack ,我相信没有人比他们更有毅力跟恒心坚持于这个目标。你想要的无非是一个 Python 版本的 CRIU 实现,或者是一个 Python 的 libcriu 引用。
    但是不使用容器,非常难以避免因为环境改变导致的进程还原冲突。举个例子:为了避免 pid 被别的进程占了无法还原,你得在一开始就用 pid namespace 给你的 Python 进程开一个命名空间,但是容器在一开始创建的隔离环境就包含了各种命名空间,顺手把网络跟存储挂载都解决了。而且你的进程必须脱离 tty 运行,否则还原的时候找不到之前的 shell 也还原不成直接 core dump 。
    这也就是只有容器才提供了进程级别 checkpoint 功能的原因,你自己想做进程的 checkpoint 最后无非都还要走一遍容器的老路,否则你会遇到各种 bad case ,无法 checkpoint 无法 restore 。
    最简单的例子你可以 apt-get install criu ,然后试试 criu dump 你的 Python 进程,看看能不能顺利 dump
    CatCode
        21
    CatCode  
    OP
       2022-05-10 10:47:41 +08:00
    @ch2 我说过我并非想处理每一种情况。我已经注明了不考虑多线程 /多进程意味着我创建检查点的时候只有一个线程和进程。17 楼里我也说了检查点的创建是在没有 TCP 链接、所有打开的文件已经关闭的情况。我的任务也不依赖于 PID 号,所以变了也无所谓。17 楼真的说的很明白了,是一段一段地处理大量操作。如果还不明白,找个类比,GitHub Actions 里面的 steps 。
    gengchun
        22
    gengchun  
       2022-05-10 11:25:34 +08:00
    前段时间有个类似的需求,我是每步直接缓存结果,类似于 http GET 缓存的处理方式,通过一个标志符和一个上下文 hashmap 做键值。每步就检查有没有缓存,有就直接返回缓存结果,没有就算一次。

    检查缓存的逻辑本身,当然可以用装饰器语法加上。不需要考虑多子任务,并发结果合并什么的,感觉用不到什么高级的库。

    只是想开拓一下思路。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1212 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 23:48 PVG 07:48 LAX 15:48 JFK 18:48
    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