如何进行酸洗以使其能够抵抗崩溃?

问题描述 投票:0回答:3

我经常使用

pickle.dump()
在 Python 2.7 中保存大文件。在我的代码中,我有一个
.pickle
文件,我会在代码的每次迭代中不断更新该文件,每次都会覆盖同一个文件。

但是,我偶尔会遇到崩溃(例如由于服务器问题)。这可能发生在pickle转储的中间,导致pickle不完整并且pickle文件不可读,并且我丢失了过去迭代中的所有数据。

我想我可以做到的一种方法是为每次迭代保存一个

.pickle
文件,然后将所有这些文件合并起来。是否有其他推荐的方法或写入磁盘的最佳实践可以防止崩溃?

python pickle
3个回答
0
投票

您正在有效地进行备份,因为您的目标是相同的:灾难恢复,丢失尽可能少的工作。

在备份中,有以下标准做法,因此请选择最适合您的做法:

  • 备份
    • 完整备份(每次都保存所有内容)
    • 增量备份(仅保存自上次备份以来更改的内容)
    • 差异备份(仅保存自上次完整备份以来更改的内容)
  • 处理旧备份
    • 循环缓冲区/旋转副本(删除或覆盖早于 X 天/迭代的备份,可以选择更改其他名称中的索引)
    • 将旧的增量/差异副本合并到之前的完整备份中(作为故障保护,合并到新文件中,然后才删除旧文件)

0
投票

还有其他推荐的方法,或者最佳实践吗

让我提一下 Mike McKearn 的一个很酷的

dill

import dill as pickle

pickle.dump_session( aRotatingIndexFileNAME ) # saves python session-state
#                                             # session is worth
#                                             # many computing [CPU-core * hrs]

如果需要,只需

import dill as pickle; pickle.load_session( aLastSessionStateFileNAME )

使用旋转文件名是归档到一定深度的回滚功能的常见最佳实践,因此值得在此不再重复。

dill
在这方面确实帮了我的忙,包括故意使用相同的调用签名,以便轻松替换到 python 项目中。


0
投票

问题是写入文件不是原子的。

与保存相反,您使用临时pickle文件并将其重命名为正确的名称,因为重命名是原子的

在这种情况下,即使崩溃后,你的pickle文件也会正常,但它可能会丢失一些数据,这些数据在崩溃时写入临时文件(重命名之前)

CACHE_FILEPATH = 'cache.pkl'

# Open save pickle file
try:
    with open(CACHE_FILEPATH, 'rb') as f:
        CACHE_DICT = pickle.load(f)
except:
    CACHE_DICT = {}

# ====
# Some more code...
# ====

# Save pickle file
tmp_filename = CACHE_FILEPATH + '.tmp'  # XXX: Save to .tmp file first
with open(tmp_filename, 'wb') as f:
    pickle.dump(CACHE_DICT, f)
    os.replace(tmp_filename, CACHE_FILEPATH)  # XXX: Chash-safe atomic rename 
© www.soinside.com 2019 - 2024. All rights reserved.