ZFS over NFS 并发写入问题

ZFS over NFS 并发写入问题

我运行一个 Proxmox 集群,在这个集群上,我在一个私有网络上拥有一些虚拟机,并且有一个(Proxmox 管理的)CEPH 存储后端用于虚拟机磁盘。

运行“Ubuntu 16.04 服务器最小虚拟机”的一个(KVM)虚拟机配置了第二个“硬盘”,设置为一个磁盘 ZFS 池“存储”,使用

zpool create storage /dev/sdb1

它会自动挂载到 /storage。此虚拟机还运行 nfs-kernel-server。

然后使用 /etc/exports 中的以下行通过 nfs 导出此目录:

/storage        10.10.0.0/16(rw,sync)

我通过以下方式从另外两台机器(一台运行 Ubuntu 14.04 的虚拟机,一台运行 Ubuntu 16.04 服务器的物理机)挂载此导出

mount -t nfs4 10.10.3.1:/storage /mnt

由于这是我的测试存储设置的游乐场,用于测试计划中的两个 Web 服务器,这两个 Web 服务器托管一个写入 Berkeley DB 文件的旧 perl 应用程序,因此我决定以一种简单的方式测试并发写入,以测试我的共享存储后端,使用一个简单的 php 脚本:

<?php
    $line = str_repeat($argv[1], 30) . "\n";

    for ($i = 1; $i <= 10000; $i++)
    {
        $of = fopen("test.txt", "a") or DIE("can't open output file\n");
            fwrite($of, sprintf("%04d-", $i)  . $line);
        fclose($of);
    }

?>

我进入共享存储目录(这也是 php 脚本所在的位置),然后使用以下命令运行它

php test.php 1

从第一台远程机器,并使用

php 测试.php 2

从第二台机器。

我的问题是某些写入似乎没有到达目标文件,即我得到如下输出:

9286-222222222222222222222222222222
9287-222222222222222222222222222222
9288-222222222222222222222222222222
9289-222222222222222222222222222222
7473-111111111111111111111111111111
7474-111111111111111111111111111111
7475-111111111111111111111111111111
7476-111111111111111111111111111111
7477-111111111111111111111111111111
7478-111111111111111111111111111111
7479-111111111111111111111111111111
9297-222222222222222222222222222222
9298-222222222222222222222222222222
7481-111111111111111111111111111111
9300-222222222222222222222222222222
7482-111111111111111111111111111111
9302-222222222222222222222222222222
7484-111111111111111111111111111111

并验证该行不会被缓存并写入文件的其他位置:

nas:/storage# grep "9290-" test.txt
9290-111111111111111111111111111111
nas:/storage# 

即缺少(除其他外)

9290-222222222222222222222222222222

行。此时,我希望我只是在设置过程中缺少一些配置参数或一两个步骤,以解决此问题。

编辑:我刚刚才注意到写入似乎相互阻塞,即行号之间的间隙始终与来自另一个远程“写入器”的交叉写入数相对应。不过,我仍然无法解释为什么会发生这种情况,也无法解决它。

另外,我在 proxmox 上为虚拟机硬盘启用了“丢弃”和“IO 线程”,并禁用了这两个选项,但没有任何效果(没想到会这样,但还是检查了一下)。行为是一样的。

答案1

好的,显然 Berkeley DB 提供了用于并发访问的锁定机制,因此我的“简单测试场景”是不够的,因为需要在应用程序级别进行锁定;我的测试脚本没有做任何此类事情,因此测试与用例不匹配。

因此,我认为这个问题已经得到解答。谢谢大家的回复!

相关内容