用于并发访问的 Lustre 文件锁定

Lustre file locking for concurrent access

我正在尝试开发一个应用程序,该应用程序将 运行 在链接到共享 Lustre 存储的多台计算机上执行各种操作,包括但不限于:

如您所见,基本的 I/O 是人们所希望的。

因为大部分都是并发的,我应该需要某种锁定来允许安全地进行不同的写作,但我看到 Lustre 默认不支持 flock(2)s(而且我'我不确定我是否想在 fcntl(2) 上使用它,我想如果需要的话我会的),而且我还没有看到任何关于 fcntl(2) 的信息来确认它的支持。

研究它主要是让我阅读了很多关于 I/O 使用 Lustre 进行优化的论文,但这些论文通常解释了他们的硬件/软件/网络的结构是如何工作的,而不是解释它是如何在代码中完成的。

那么,我可以将 fcntl(2) 与 Lustre 一起使用吗?我应该使用它吗?如果不是,还有哪些其他替代方案可以让不同的客户端对数据执行并发修改?

或者有可能吗? (我在 Lustre 票证中看到 mmap 是可能的,所以 fcntl 应该也可以工作(语句背后没有逻辑),但我想知道可能存在一些限制。)

我会继续写一个测试应用程序来检查它,但我想我还是应该问问是否有更好的选择(或者它的功能是否有我应该知道的限制,因为我的测试将受到限制,我们不希望未知的限制成为开发过程后期的问题)。

谢谢,

编辑:基本问题已由 LustreOne 正确回答,这里我提供有关我的用例的更多具体信息,以允许人们添加有关 Lustre 并发访问的相关附加信息。

Lustre 客户端将成为其他应用程序的服务器。 这些应用程序的每个客户端都有自己的一组文件,但我们希望支持允许客户端同时从多台机器登录到他们的客户端 space,为此,我们需要允许并发文件读取和写。

但是,这些在总 I/O 操作中所占的比例始终很小。

虽然 LustreOne 的回答中给出了非常有趣的见解,但没有多少适用于此用例(或者更确切地说,它们确实适用,但可能不希望增加整个系统的复杂性以影响性能) .

也就是说,对于目前考虑的用例,我相信它会对某些人以及以后的我们自己有很大帮助。但是,我们现在寻求的更多的是一种方法,可以方便地让两个节点或者线程一个节点响应两个请求修改数据让一个通过并检测冲突,有效防止客户端的担心。

我认为文件锁定对于该用例来说已经足够了,但我更喜欢字节锁定,因为一些最关心的文件被一些客户不停地追加,并且 read/modified 直到被别人终结。

不过,从我从LustreOne的回答中了解到的情况来看:

That said, there is no strict requirement for this if your application knows what it is doing. Lustre will already keep non-overlapping writes consistent, and can handle concurrent O_APPEND writes as well.

后一种情况已经由开箱即用的 Lustre 管理。

对什么可能是最好的选择有什么看法吗?对完整文件使用简单的 flock() 就足够了吗?

请注意,某些文件也将有索引,可用于确定数据的可用性而无需锁定任何数据文件,如果使用或字节锁定足够快,我们可以避免增加代码库大小来支持两种情况?

最后提到 mmap。我很确定它不太适合我们的用例,因为我们有很多文件和很多客户端,所以 OST 可能无法缓存太多,但可以肯定的是......是否应该使用它,如果是的话,如何? ^^

抱歉这么冗长,这是我的缺点之一。 :/

祝你有愉快的一天,

您应该使用“-o flock”挂载选项挂载所有客户端以启用全局一致性锁定。然后 flock() (我认为 fcntl() 锁定)将起作用。

也就是说,如果您的应用程序知道它在做什么,则对此没有严格的要求。 Lustre 已经可以保持非重叠写入的一致性,并且还可以处理并发 O_APPEND 写入。然而,由于 Lustre 必须为追加进行内部锁定,如果有许多不同的客户端同时追加到同一个文件,这会显着损害写入性能。 (请注意,如果只有一个客户端正在附加,这不是问题)。

如果您自己编写应用程序,那么您可以做很多事情来提高性能: - 让一些中央线程为每个写入器分配一个 "write slot number"(本质上是一个递增的整数),然后客户端写入 offset = recordsize * slot number。除了分配槽号(可以分批完成以获得更好的性能)之外,客户端之间没有争用。在大多数 HPC 应用程序中,线程使用 MPI rank 作为插槽号,因为它是唯一的,并且同一节点上的线程通常会被分配相邻的插槽,因此 Lustre 可以进一步聚合写入。如果您使用线程可能产生可变数量记录的 producer/consumer 模型,那将不起作用。 - 使 IO 记录大小为 4KiB 的倍数以避免线程之间的争用。否则,客户端或服务器将被迫对磁盘块中的部分记录进行读取-修改-写入,效率低下。 - 根据您的工作流程是否允许,与其对同一个文件进行读取和写入,不如将一堆记录写入一个文件,然后将文件作为一个整体处理并写入第二个文件可能更有效文件。并不是说 Lustre 不能对单个文件进行并发读写,但这会导致不必要的争用,而这本可以避免。