NVMeOF/RDMA 同步文件修改
NVMeOF/RDMA sync file modifications
我只是设置了 NVMeOF/RDMA 环境来玩。我有一个目标节点,一些客户端节点访问了 NVMe SSD。但是,当我在一个客户端节点上删除一个文件say test
时,其余节点看不到这个操作并且仍然可以正常读取test
的内容。我知道 RDMA 绕过内核,所以我猜这是因为缓存?然后我尝试使用这些命令清理缓存:
sudo sync; echo 3 | sudo tee /proc/sys/vm/drop_caches
sudo sync; echo 1 | sudo tee /proc/sys/vm/drop_caches
sudo sync; echo 2 | sudo tee /proc/sys/vm/drop_caches
不幸的是,其他节点仍然保留着这个文件。
其实我有两个问题:
- 是否正是缓存的原因?它是如何工作的?
- 清理缓存以便其他节点可以看到删除而无需重新挂载的正确方法是什么?
任何帮助将不胜感激!
NVMeoF(使用 RDMA 或任何其他传输)是块级存储协议,而不是文件级存储协议。因此,无法保证 NVMeoF 系统中跨节点文件操作的原子性。即使一个节点删除了一个文件,也不能保证:
- 删除操作实际上被转换为块擦除操作并发送到存储服务器;
- 即使存储服务器删除了块,也不能保证缓存了该数据的其他客户端不会继续读取它。此外,另一个客户端可以覆盖已删除的文件。
总的来说,我认为要在文件级别有任何保证,您应该考虑分布式文件系统,而不是 NVMeoF。
What is the correct way to clean up the cache so that other nodes can see the deletion without re-mount?
没有好的办法。刷新所有节点上的缓存,然后才读取可能有效,但这取决于文件系统。
相对简短的回答
正如 Boris 所说,您不想那样做(存储的分布式一致性是一个 hard 问题),您需要其他东西来做您想做的事。刷新缓存可能不起作用,因为您有多个不同的系统视图 + 缓存行为
更长的答案:
正如 Boris 提到的,NVMeoF 是一个 block 协议。这意味着在广泛的层面上(需要一些技巧)它所能做的就是在特定地址读取和写入块。在实践中,我们通常在 NVMe/NVMeoF 通信层 之上 层,例如处理此抽象的文件系统。
我现在无法判断您是在使用文件系统还是直接 reading/writing 设备,但无论哪种情况,您至少部分正确,页面缓存可能正在进入顺便说一下,即使使用 RDMA。
现在,如果您在客户端节点上使用本地文件系统,您很快就会得到不一致的视图。文件系统(以及因此整个操作系统及其页面缓存和块存储状态的视图)不知道其他人写了什么。因此,即使您在一个客户端上写入和同步,您也可能不得不绕过另一个客户端上的页面缓存(例如,使用 O_DIRECT 读取,它们有自己的一组复杂性)并确保您的目标最终指向从您的其他客户端写入 NVMe 目标的相同 块 地址。
从理论上讲,如果一切都正确排列,这将允许您读取另一个写入的数据,但实际上这可能会导致混淆,尤其是如果一个客户端上的文件系统或应用程序在一个位置写入内容,而另一个客户端试图在不知不觉中读取或写入该位置。现在你遇到了一致性问题。
我只是设置了 NVMeOF/RDMA 环境来玩。我有一个目标节点,一些客户端节点访问了 NVMe SSD。但是,当我在一个客户端节点上删除一个文件say test
时,其余节点看不到这个操作并且仍然可以正常读取test
的内容。我知道 RDMA 绕过内核,所以我猜这是因为缓存?然后我尝试使用这些命令清理缓存:
sudo sync; echo 3 | sudo tee /proc/sys/vm/drop_caches
sudo sync; echo 1 | sudo tee /proc/sys/vm/drop_caches
sudo sync; echo 2 | sudo tee /proc/sys/vm/drop_caches
不幸的是,其他节点仍然保留着这个文件。
其实我有两个问题:
- 是否正是缓存的原因?它是如何工作的?
- 清理缓存以便其他节点可以看到删除而无需重新挂载的正确方法是什么?
任何帮助将不胜感激!
NVMeoF(使用 RDMA 或任何其他传输)是块级存储协议,而不是文件级存储协议。因此,无法保证 NVMeoF 系统中跨节点文件操作的原子性。即使一个节点删除了一个文件,也不能保证:
- 删除操作实际上被转换为块擦除操作并发送到存储服务器;
- 即使存储服务器删除了块,也不能保证缓存了该数据的其他客户端不会继续读取它。此外,另一个客户端可以覆盖已删除的文件。
总的来说,我认为要在文件级别有任何保证,您应该考虑分布式文件系统,而不是 NVMeoF。
What is the correct way to clean up the cache so that other nodes can see the deletion without re-mount?
没有好的办法。刷新所有节点上的缓存,然后才读取可能有效,但这取决于文件系统。
相对简短的回答
正如 Boris 所说,您不想那样做(存储的分布式一致性是一个 hard 问题),您需要其他东西来做您想做的事。刷新缓存可能不起作用,因为您有多个不同的系统视图 + 缓存行为
更长的答案:
正如 Boris 提到的,NVMeoF 是一个 block 协议。这意味着在广泛的层面上(需要一些技巧)它所能做的就是在特定地址读取和写入块。在实践中,我们通常在 NVMe/NVMeoF 通信层 之上 层,例如处理此抽象的文件系统。
我现在无法判断您是在使用文件系统还是直接 reading/writing 设备,但无论哪种情况,您至少部分正确,页面缓存可能正在进入顺便说一下,即使使用 RDMA。
现在,如果您在客户端节点上使用本地文件系统,您很快就会得到不一致的视图。文件系统(以及因此整个操作系统及其页面缓存和块存储状态的视图)不知道其他人写了什么。因此,即使您在一个客户端上写入和同步,您也可能不得不绕过另一个客户端上的页面缓存(例如,使用 O_DIRECT 读取,它们有自己的一组复杂性)并确保您的目标最终指向从您的其他客户端写入 NVMe 目标的相同 块 地址。
从理论上讲,如果一切都正确排列,这将允许您读取另一个写入的数据,但实际上这可能会导致混淆,尤其是如果一个客户端上的文件系统或应用程序在一个位置写入内容,而另一个客户端试图在不知不觉中读取或写入该位置。现在你遇到了一致性问题。