【问题标题】:Write-locked file sometimes can't find contents (when opening a pickled pandas DataFrame) - EOFError: Ran out of input写锁定的文件有时找不到内容(打开腌制的熊猫数据帧时)-EOFError: Ran out of input
【发布时间】:2018-10-29 11:08:45
【问题描述】:

这是我的情况:我需要在一个集群上运行 300 个进程(它们是独立的),所有进程都添加它们的一部分数据到同一个 DataFrame(它们之前还需要读取文件结果写作)。他们可能需要在整个运行时多次执行此操作。

所以我尝试使用带有portalocker 包的写锁定文件。但是,我遇到了一种错误,我不明白它是从哪里来的。

这是每个进程将写入同一个文件的框架代码:

with portalocker.Lock('/path/to/file.pickle', 'rb+', timeout=120) as file:
    file.seek(0)
    df = pd.read_pickle(file)

    # ADD A ROW TO THE DATAFRAME

    # The following part might not be great,
    # I'm trying to remove the old contents of the file first so I overwrite
    # and not append, not sure if this is required or if there's
    # a better way to do this.
    file.seek(0)
    file.truncate()
    df.to_pickle(file)

上述方法在大多数情况下都有效。但是,我的写锁定同时处理的进程越多,pd.read_pickle(file) 阶段的 EOFError 错误就越多。

EOFError: Ran out of input

回溯非常长且令人费解。

无论如何,到目前为止,我的想法是,由于它有时有效,所以上面的代码一定没问题*(尽管它可能很混乱,我不介意听到更好的方法来做同样的事情)。

但是,当我有太多进程尝试写锁定时,我怀疑文件没有时间保存或其他东西,或者至少以某种方式下一个进程还没有看到由上一个过程。

有办法解决吗?我尝试在我的代码周围添加time.sleep(0.5) 语句(在read_pickle 之前,to_pickle 之后),但我不认为它有帮助。有谁知道会发生什么或知道更好的方法吗?

另外请注意,我认为写锁不会超时。我尝试对这个过程进行计时,并且我还在其中添加了一个标志来标记写锁定是否超时。虽然有 300 个进程并且它们可能正在尝试写入并改变速率,但总的来说,我估计每秒大约有 2.5 次写入,这似乎不会使系统过载,不是吗?*

*腌制的DataFrame大小为几百KB。

【问题讨论】:

  • 仅作记录,您使用的是哪个操作系统?我昨天尝试复制这个并且还观看了您在 github 上的讨论,但未能在我的 Ubuntu 机器上复制您的问题,所以它看起来真的像一个集群。
  • 是的,这绝对是一个集群的东西,它是一个 CentOS 7.5,使用 SLURM 调度程序运行作业。

标签: python pandas file-io multiprocessing readwritelock


【解决方案1】:

这可能是一个有点模糊的问题,但由于我设法解决它并更好地了解情况,我认为在这里发布我发现的内容会很有帮助,希望其他人也能找到这个。在我看来,这似乎是一个可能会出现在其他人身上的问题。

感谢 'portallocker' github 页面的帮助和回答:https://github.com/WoLpH/portalocker/issues/40

问题似乎是我在集群上执行此操作。结果,文件系统有点复杂,因为进程在多个节点上运行。保存的文件“同步”并被不同的运行进程看到可能需要比预期更长的时间。

似乎对我有用的是刷新文件并强制系统同步,另外(尚不确定这是否是可选的)在此之后添加更长的“time.sleep()”。

根据“portallocker”开发人员的说法,文件在集群上同步可能需要不可预测的时间,因此您可能需要改变睡眠时间。

也就是说,在保存文件后添加这个:

df.to_pickle(file)
file.flush()
os.fsync(file.fileno())

time.sleep(1)

希望这可以帮助其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-12
    • 2014-09-07
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    相关资源
    最近更新 更多