- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我们在 EC2 上有一个 nginx/php-fpm 设置,它将文件 block 接收到一个 NFS 安装的“ block ”文件夹(特别是 SoftNAS),该文件夹在多个应用程序服务器之间共享。我们遇到一个问题,应用程序在将完成的文件上传到 S3 之前检查文件是否存在,但即使文件存在,文件检查也失败。
应用在 is_file() 或 file_exists() 之前有一个 clearstatcache()(我们都试过了),但该文件在 10-20 秒内对应用不可见。
这是该测试的一些运行的输出:
app1 write timestamp 1484702190.5575
app2 read timestamp 1484702216.0643
25.5068 seconds
app1 write timestamp 1484702229.0130
app2 read timestamp 1484702246.0652
17.0522 seconds
app1 write timestamp 1484702265.6277
app2 read timestamp 1484702276.0646
10.4369 seconds
app1 write timestamp 1484702286.0136
app2 read timestamp 1484702306.0645
20.0509 seconds
app1 write timestamp 1484702314.4844
app2 read timestamp 1484702336.0648
21.5804 seconds
app1 write timestamp 1484702344.3694
app2 read timestamp 1484702366.0644
21.6950 seconds
app1 write timestamp 1484702374.0460
app2 read timestamp 1484702396.0645
22.0185 seconds
app1 write timestamp 1484702404.0346
app2 read timestamp 1484702426.0647
22.0301 seconds
app1 write timestamp 1484702434.2560
app2 read timestamp 1484702456.1092
21.8532 seconds
app1 write timestamp 1484702466.0083
app2 read timestamp 1484702486.1085
20.1002 seconds
app1 write timestamp 1484702496.5466
app2 read timestamp 1484702516.1088
19.5622 seconds
app1 write timestamp 1484702525.2703
app2 read timestamp 1484702546.1089
20.8386 seconds
app1 write timestamp 1484702558.3312
app2 read timestamp 1484702576.1092
17.7780 seconds
我们已经尝试了多种检查文件的方法:
这些事情似乎都没有任何区别。我们没有对每个选项进行广泛的测试,但在文件存在检查通过之前,每个选项似乎都花费了过长的时间。
有一件事确实奏效了。在 shell 中的 app2 上运行“ls”循环,app2 脚本可立即读取该文件。
app1 write timestamp 1484703581.3749
app2 read timestamp 1484703581.3841
0.0092 seconds
app1 write timestamp 1484703638.81 00
app2 read timestamp 1484703638.8139
0.0039 seconds
app1 write timestamp 1484703680.8548
app2 read timestamp 1484703680.8576
0.0028 seconds
因此,shell 中的某些内容正确地清除了 NFS 缓存,但 PHP 中的清除缓存命令似乎没有任何区别。
(编辑)有问题的代码:
public static function get($filepath) {
clearstatcache(TRUE, $filepath);
if (file_exists($filepath)) {
$instance = new static::$_class;
$instance->init($filepath);
return $instance;
} else {
// Sometimes a new file is not found with the first is_file() attempt.
// Clear the stat cache and try to find the file again.
clearstatcache(TRUE, $filepath);
if (file_exists($filepath)) {
$instance = new static::$_class;
$instance->init($filepath);
return $instance;
}
}
Log::error("AJRFSFILE " . $_SERVER['PATH_INFO'] . " " . $_SERVER['HTTP_DEVICE'] . " " . $filepath . " " . json_encode(stat($filepath)));
return false;
}
(Edit2) 结果表明,在代码中使用“ls”运行 exec() 可以成功清除系统级发生的任何文件级缓存,但出于显而易见的原因,每次执行 file_exists 时 exec() 都是一个次优解。
最佳答案
这是正在发生的事情。 PHP 统计缓存依赖于 atime 属性,该属性可从底层 VFS 获得。当 NFS 为 VFS 提供动力时,属性会被缓存以减少服务器往返。不幸的是,这些可能导致 PHP 对状态“撒谎”,因为实际上 NFS 服务器没有提供 VFS 当前信息。
您可以使用 noac
挂载选项强制立即保持一致性。我建议在您绝对肯定地需要在尽可能短的时间内获得最新信息的任何服务器上使用它:
Use the noac mount option to achieve attribute cache coherence among multiple clients. Almost every file system operation checks file attribute information. The client keeps this information cached for a period of time to reduce network and server load. When noac is in effect, a client’s file attribute cache is disabled, so each operation that needs to check a file’s attributes is forced to go back to the server. This permits a client to see changes to a file very quickly, at the cost of many extra network operations.
如果 noac
太慢,还有其他挂载选项可能会根据您的需要更好地调整缓存。请参阅:lookupcache
和 actimeo
。例如,减少 actimeo
将减少 NFS 本地缓存信息的时间:默认值为 30 秒(最小值)到 60 秒(最大值)。或者,作为另一个示例,lookupcache=positive
将提供有关新文件外观的更快智能,但即使在取消链接后也会长期缓存它们的存在。
但是,为什么在没有这些挂载选项的情况下,目录中的 ls
会“修复”这个问题?结果是 opendir
和 closedir
序列使 NFS 属性缓存无效,这会强制调用回服务器。
因此,在您的情况下,您使用 opendir()/closedir()
序列来使缓存无效。我不确定 system("ls")
是否有效,因为我相信每个进程对底层属性缓存都有不同的看法,但值得一试。
关于PHP file_exists 或 is_file 在 NFS 文件 (EC2) 上无法正确回答 10-20s,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41723458/
我正在运行 Debian GNU/Linux 7 VM mount.nfs 版本 mount.nfs: (linux nfs-utils 1.2.6) 我想在 NFS 挂载上设置配额。 NFS 服务器
我正在尝试使用 VirtualBox 作为提供程序并使用 ansible 作为配置工具来“升级”一台 CentOS 机器 (centos7-x64-vbox43)。我执行了以下命令: vagrant
我最近使用 inotify 创建了一个保管箱系统,监视在特定目录中创建的文件。我正在监视的目录是从 NFS 服务器挂载的,并且 inotify 的行为与我的预期不同。考虑以下场景,其中 inotify
我已经在我的本地机器上安装了一个 NFS 挂载(所以,我想我的机器是 NFS 客户端)并且一个文件正在被托管 NFS 挂载的远程机器(NFS 服务器)写入 NFS 挂载中。现在,我如何使用 JAVA
我关注这个tutorial为我的服务器设置 NFS。目前,我有 1 台服务器将其部分目录共享为 HOST,2 台服务器将这些目录作为 CLIENT。 我的问题很直接,如果我的HOST包含200万张图片
我在主机上有一个 NFS 分区,如果将其添加到容器中 docker run -i -t -v /srv/nfs4/dir:/mnt ubuntu /mnt 将包含共享数据,但它不会导致冲突吗?因为它还
没有 iptables 规则,我可以挂载我的 NFSSERVER:/PATH 但有了它(firewall/iptables) 已启用,但我无法安装。 [.e.g., after iptables --
我们有两个数据中心,每个数据中心都有许多共享一个基于 EMC 的大型 nfs 的 Linux 服务器。 挑战在于保持两个 nfs 同步。目前假设写入仅发生在 nfs1 上,然后 nfs1 必须将更改传
我在尝试挂载 nfs 导出时遇到以下错误。 sudo mount 192.168.1.175:/mnt/nas /mnt/c/nas mount.nfs: No such device 关于如何解
NFS 挂载在我的 RHEL 7 AWS 实例中不起作用。 当我做一个 mount -o nfsvers=3 10.10.11.10:/ndvp2 /root/mountme2/ 我得到错误: mou
我正在复制 Controller 示例 [1] 中尝试 Kubernetes NFS 卷声明。 我已经设置了 NFS 服务器、PV 和 PVC。我的复制 Controller 看起来像这样 apiVe
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我想查找并更改用户帐户及其在本地文件系统上的默认组,但不包括大量 NFS 安装和指向这些安装的符号链接(symbolic link)。我尝试了多种语法但没有成功 - find / -user dumm
我正在使用 docker NFS 容器,但是在安装导出的目录(即使在本地主机上)时遇到了麻烦。 问题 exportfs: does not support NFS export 设置 我的容器使用入
HDFS NFS GateWay mount.nfs:输入/输出错误? 1.报错如下: [root@xx sbin]# mount -t nfs -o vers=3,proto=tcp,nolock,
我无法为 Docker Swarm 安装 NFS 卷,并且缺乏有关 --mount 语法( https://docs.docker.com/engine/reference/commandline/s
我有一个 Kubernetes 集群设置(本地),它有一个 NFS 共享(my-nfs.internal.tld)安装到 /exports/backup在每个节点上创建备份。 现在我正在设置我的日志记
我想将 sqlite 数据库嵌入到现有的 tcl 应用程序中(从平面文件迁移)。 目前;我们的 tcl 解释器是从网络位置运行的; /bin/tclsh8.3 我有一个 nfs $PATH对于已经为所
我在一台服务器上为客户端创建了一个 NFS 共享服务器和客户端都是centos 6系统。服务器 nfs 导出:/srv/diskless/tmp *(rw,sync,no_root_squash)。
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 10 个月前关闭。 Improve
我是一名优秀的程序员,十分优秀!