写入锁定的文件有时找不到内容(打开腌制的熊猫DataFrame时)-EOFError:输入用尽

时间:2018-10-29 11:08:45

标签: python pandas file-io multiprocessing readwritelock

这是我的情况:我需要在一个群集上运行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。

1 个答案:

答案 0 :(得分:0)

也许这是一个模糊的问题,但是由于我设法解决了这个问题并更好地了解了情况,所以我认为将我发现的内容发布在这里是有益的,希望其他人也可以找到。在我看来,这是一个可能也可能会引起其他问题的问题。

请登录“ portalocker” github页面获取帮助和答案:https://github.com/WoLpH/portalocker/issues/40

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

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

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

换句话说,在保存文件后添加它:

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

time.sleep(1)

希望这可以帮助其他人。