当前位置: 首页 > 知识库问答 >
问题:

从NFS挂载的50000个文件目录中检索目录树的更好方法

养学
2023-03-14

我被带到一个现有的CMS和文件管理web应用程序上工作,该应用程序为商家的在线网店提供一个管理界面。管理应用程序是用PHP开发的。

当网站用户查看网店时,页面资产(主要是嵌套文件夹路径中的图像)直接从网店的HTML中引用,并直接从独立于CMS系统的web服务器提供服务。

但为了列出/搜索/允许文件导航(即文件管理部分),CMS应用程序需要能够访问文件/文件夹目录结构。

因此,我们使用LinuxNFS挂载从CMS服务器到文档文件服务器。如果任何特定商家的目录树中的文件数量不太大(

检索任何一个目录中的文件列表都非常快,但是当我们试图识别这些“文件”中的哪些实际上是目录条目时,问题就来了,这样我们就可以沿着树递归。

检查文件类型的PHP函数(或者在使用readdir或scandir检索的每个文件路径上调用is_dir,或者使用带有标志的全局GLOB_ONLYDIR)似乎对每个文件单独工作,而不是批量工作。所以现在有1000个和1000个NFS命令被发送。从我到目前为止的研究来看,这似乎是NFS的限制,而不是PHP的限制。

一个精简的类,只显示所讨论的函数:

class clImagesDocuments {

    public $dirArr;

    function getDirsRecursive( $dir ) {

        if ( !is_dir( $dir )) {
            return false;
        }

        if ( !isset( $this->dirArr )) {
            $this->dirArr = glob( $dir . "/*", GLOB_ONLYDIR );
        } else {
            $this->dirArr = array_merge( $this->dirArr, glob( $dir . "/*", GLOB_ONLYDIR ) );
            return false;
        }

        for( $i = 0; $i < sizeof( $this->dirArr ); $i ++) {
            $this->getDirsRecursive( $this->dirArr [$i] );
        }

        for( $i = 0; $i < sizeof( $this->dirArr ); $i ++) {
            $indexArr = explode( $dir, $this->dirArr [$i] );
            $tempDir[$indexArr[1]] = $this->dirArr [$i];
        }

        $this->dirArr = $tempDir;
    }
}

在文件文档服务器上本地执行相同的PHP代码来检索目录树etc要快得多(2或3个数量级),大概是因为本地文件系统正在缓存目录结构。我不得不认为我的问题是由于NFS。

我正在考虑编写一个简单的webapp,它将在文件文档web服务器上运行,并通过API提供目录结构的实时查找。

我将感谢任何想法或建议。

共有2个答案

谭宏盛
2023-03-14

老问题,但我现在的问题。

一个解决方案:

在存储服务器上运行树https://linux.die.net/man/1/tree,在每个目录上运行-X(XML输出),或者在顶目录上运行一次,并将输出发送到“tructure.xml”文件(. at开始,所以你可以忽略它从上市)

树-x-f-q-s-D-dirfirst-x

然后让你的脚本加载这个结构,并用它来显示树结构。您可以为每个商家或一个全局商家创建此文件,然后遍历它以查找商家。

您可以每分钟通过cron运行一次,也可以创建和API来调用在存储机器上运行它。

您可以在更改文件时更新此xml。

不需要数据库。

您还可以监视存储端目录的更改,并在每次发生更改时重新创建xml。https://superuser.com/questions/181517

编辑:如何在Linux中监视完整的目录树的更改?

锺离嘉茂
2023-03-14

另一种解决方案——你可以用一些字符串作为所有目录的前缀,当你用文件获得列表时,你可以通过检查它们是否包含字符串来检查哪些目录实际上是目录。这样可以完全避免is_dir()

 类似资料:
  • 问题内容: Docker文档指出,可以将单个文件装载到Docker容器中: -v标志还可用于从主机挂载单个文件-而不是目录。 这会将您放入新容器中的bash外壳中,您将从主机获得bash历史记录,退出容器时,主机将具有在容器中键入命令的历史记录。 但是,当我尝试将文件挂载为目录时: 我的Dockerfile看起来像这样: Docker版本为1.9.1,内部版本为a34a1d5。 这是文档问题,还是

  • 本文向大家介绍PHP统计目录中文件以及目录中目录大小的方法,包括了PHP统计目录中文件以及目录中目录大小的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了PHP统计目录中文件以及目录中目录大小的方法。分享给大家供大家参考,具体如下: 更多关于PHP文件与目录操作相关内容感兴趣的读者可查看本站专题:《php文件操作总结》与《PHP目录操作技巧汇总》 希望本文所述对大家PHP程序设计有所帮

  • 挂载主机目录 挂载一个主机目录作为数据卷 使用 --mount 标记可以指定挂载一个本地主机的目录到容器中去。 $ docker run -d -P \ --name web \ # -v /src/webapp:/opt/webapp \ --mount type=bind,source=/src/webapp,target=/opt/webapp \ training/

  • 问题内容: 我有一个仅在成功完成几个测试后才能启动的过程。 我需要进行的一项测试是,我所有的NFS挂载均正常运行。 我能做得比蛮力方法更好吗: 这是一个实用程序,它将在后台运行命令,并在给定时间后将其杀死(如果在时间限制之前未捕获到该命令),则以明显的方式返回成功/失败。 用英语:解析输出,检查每个NFS安装点(有一个超时)。可选地(不在上面的代码中)在第一个陈旧的挂载上中断。 问题答案: 您可以

  • 在服务器上有一个目录,我现在可以访问,除了nfs-挂载。我通过nfs将目录挂载到本地linux系统中。新文件到达目录,一些旧文件可能会通过服务器上的其他进程得到更新。 我想写一个Python脚本,每当创建或更改这样的文件时,它就会启动。我知道可以使用inotify(或旧版本中的d通知)使用Linux和Python来观看本地目录。然而,这些似乎不适用于远程安装的卷。 我有什么选择,或者已经实施了解决

  • 问题内容: 我在用 我想用bash脚本检查一下,看看是否已挂载?如果不是,则调用上面的mount命令,否则执行其他操作。我怎样才能做到这一点? CentOS是操作系统。 问题答案: 运行不带参数的命令将告诉您当前的安装。在shell脚本中,您可以使用和if语句检查挂载点: 在我的示例中,if语句正在检查的退出代码,该代码指示是否存在匹配项。由于我不希望在匹配时显示输出,因此将其重定向到。