比较目录状态或散列以获得乐趣和利润的最快方法

jho*_*orn 12 php linux bash hash

我们有一个PHP应用程序,并且认为让应用程序知道自上次执行以来它的构成是否有变化可能是有利的.主要是由于管理缓存等,并且知道我们的应用程序有时会被不记得清除缓存更改的人访问.(改变人民是明显的答案,但唉,不是真的可以实现)

我们已经提出了这个问题,这是我们成功实现的最快速度,在一台典型项目的开发者机器上平均运行0.08.我们用shasum,md5和crc32进行了实验,这是最快的.我们基本上md5ing每个文件的内容,并md5'输出.安全性不是问题,我们只对通过不同的校验和检测文件系统更改感兴趣.

time (find application/ -path '*/.svn' -prune -o -type f -print0 | xargs -0 md5 | md5)
Run Code Online (Sandbox Code Playgroud)

我想问题是,这可以进一步优化吗?

(我意识到修剪svn会有成本,但是发现组件花费的时间最少,所以它将是非常小的.我们在工作副本atm上测试它)

Arn*_*anc 12

您可以使用inotify扩展通知文件系统修改.

它可以用pecl安装:

pecl install inotify
Run Code Online (Sandbox Code Playgroud)

或者手动(下载,phpize && ./configure && make && make install照常安装).

这是linux inotify系统调用的原始绑定,可能是linux上最快的解决方案.

请参阅此简单tail实现的示例:http://svn.php.net/viewvc/pecl/inotify/trunk/tail.php?changevision = 262896&view = markup


如果您需要更高级别的库,或者支持非Linux系统,请查看Lurker.

它适用于任何系统,并且可以在可用时使用.

请参阅自述文件中的示例:

$watcher = new ResourceWatcher;
$watcher->track('an arbitrary id', '/path/to/views');

$watcher->addListener('an arbitrary id', function (FilesystemEvent $event) {
    echo $event->getResource() . 'was' . $event->getTypeString();
});

$watcher->start();
Run Code Online (Sandbox Code Playgroud)


tha*_*guy 6

您可以使用与文件名和时间戳相同的技术,而不是通过文件内容:

find . -name '.svn' -prune -o -type f -printf '%m%c%p' | md5sum
Run Code Online (Sandbox Code Playgroud)

这比读取和散列每个文件的内容要快得多.


Gor*_*don 5

积极寻找变化,为什么不在事情发生变化时得到通知.看看PHP的FAM - File Alteration Monitor API

FAM监视文件和目录,通知感兴趣的应用程序更改.有关FAM的更多信息,请访问http://oss.sgi.com/projects/fam/.PHP脚本可以使用此扩展提供的功能指定要监视的FAM文件列表.当打开从任何应用程序到它的第一个连接时,将启动FAM进程.在关闭所有连接后退出.

CAVEAT:在计算机上需要一个额外的守护程序,并且PECL扩展不受维护.


jho*_*orn 4

我们不想使用 FAM,因为我们需要将其安装在服务器上,而这并不总是可行。有时,客户坚持要求我们在他们损坏的基础设施上进行部署。由于它已经停产,因此也很难让这一变更得到批准。

提高问题中原始版本速度的唯一方法是确保您的文件列表尽可能简洁。IE 仅对更改后真正重要的目录/文件进行哈希处理。删除不相关的目录可以大大提高速度。

除此之外,应用程序使用该函数检查是否有更改,以便在有更改时执行缓存清除。由于我们实际上并不想在应用程序执行此操作时停止应用程序,因此最好使用 fsockopen 将此类事情小心地作为异步进程进行处理。这提供了总体上最好的“速度提升”,只是要小心比赛条件。

将此标记为“答案”并支持 FAM 答案。