【问题标题】:How to handle file server race conditions?如何处理文件服务器竞争条件?
【发布时间】:2019-04-10 06:51:58
【问题描述】:

我正在开发一个应用程序,该应用程序每 1 分钟轮询网络文件服务器 (cifs) 上的一个文件夹以查找计划的 cron 作业中的新文件。

当它看到一个新文件时,它会临时将其复制到本地文件系统,然后对文件执行各种操作,然后从本地和网络文件系统中删除它。

我担心在有人将文件添加到网络文件夹的同时,我的应用程序会轮询网络文件夹,这可能会遇到争用情况。这些文件非常小(1kb),因此当我轮询文件夹时文件仍然在复制的情况应该是非常罕见的,但它可能会发生。

我的问题是,这是一个合理的担忧吗?如果是,我应该如何处理?

【问题讨论】:

  • 您可能希望在写入文件时以某种方式“锁定”文件。看看:serverfault.com/questions/806156/… - 如果你做到了,你的计划作业将无法处理文件,将等待下一次。
  • 嗯,我认为这不会起作用,因为文件没有以编程方式添加到网络文件夹中。员工正在通过 Windows 资源管理器将文件复制到此文件夹。
  • 啊,太糟糕了。只处理最后修改日期在特定时间(例如一小时)之后的文件呢?这实际上取决于您在编写它们后需要多快处理它们。
  • 这是我考虑过的一种选择。我可能会在 5 分钟后检查文件。不知道有没有更好的办法。
  • 最好的解决方案是让应用程序将文件复制到一个临时名称,然后重命名它。重命名是一个原子操作,因此您永远不会看到正在复制的文件。

标签: php filesystems race-condition fileserver


【解决方案1】:

这是我解决问题的方法。

请注意,我在工作流程的几个方面都遇到了这个问题。第一个是我必须使用我的应用程序监视目录中的新文件并确保它们完成传输等。第二个是我必须将文件上传到另一个软件正在监视的目录a)我没有控制权,并且 b) 非常陈旧,本身并没有进行任何验证。

解决第一个问题:

在我计划的作业中,我扫描了目录中的所有文件,然后生成每个文件的 md5 哈希值,并将其与文件路径一起保存到数据库中的表中。

下次我计划的作业运行时(1 分钟后),我从数据库中获取所有行(文件路径和哈希),检查文件是否仍然存在,然后再次生成文件的 md5 哈希。如果文件都存在并且哈希值相同,我会对文件进行处理(并将其从目录中删除)。如果这两个之一失败,我只需跳到循环中的下一个文件。

处理完所有文件后,我会截断索引文件的表,然后重新索引所有文件,将它们重新保存到数据库中。一分钟后,我的工作重新开始使用索引中的文件。

这样我就永远不会处理我没有从以前的作业运行中索引的文件。我相信可以安全地假设,如果文件哈希值在 1 分钟内没有发生变化,则文件已完成传输,我可以使用它。

解决第二个问题:

为了确保其他软件不会使用我可能正在上传的文件,我只是在服务器上创建了另一个目录,该软件没有监控并将文件上传到那里。文件传输完成后,我发出了一个移动命令将文件移动到受监控的目录,由于移动是文件系统上的原子操作,因此可以避免竞争条件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多