我正在尝试开发一个应用程序,该应用程序将在链接到共享Lustre存储的多台计算机上运行,执行各种操作,包括但不限于:
如您所见,可以实现基本的I / O.
由于大部分时间都是并发的,我应该需要某种锁定才能安全地进行不同的着作,但我已经看过Lustre不支持flock(2)s默认情况下(我不确定我是否想在fcntl(2)上使用它,我想我会这样做),而且我还没有看到任何有关fcntl(2)的信息来确认它支持。
研究它主要是因为我阅读了很多关于使用Lustre进行I / O优化的论文,但这些通常解释了他们的硬件/软件/网络的结构是如何工作的,而不是解释它是如何在代码中完成的。
那么,我可以在Lustre中使用fcntl(2)吗?我应该用吗?如果没有,还有哪些其他选择允许不同的客户端同时修改数据?
或者甚至可能吗? (我在Luster门票中看到mmap是可能的,所以fcntl也应该工作(没有逻辑背后声明),但可能存在我想要注意的限制。)
我会继续编写一个测试应用程序来检查它,但我想我还是应该问,如果有更好的替代方案(或者如果它的功能有限,我应该注意,因为我的测试将是有限的,我们不希望未知的限制在开发过程的后期成为问题)。
谢谢,
编辑:LustreOne已经正确回答了基本问题,在这里我提供了有关我的用例的更多具体信息,以便人们添加有关Lustre并发访问的相关附加信息。
Lustre客户端将成为其他应用程序的服务器。 这些应用程序的客户端将各自拥有自己的文件集,但我们希望支持允许客户端同时从多台计算机登录到其客户端空间,为此,我们需要允许并发文件读写。
然而,这些在总I / O操作中占很小比例。
虽然在LustreOne的答案中给出了非常有趣的见解,但其中很多都没有适用于这个用例(或者更确切地说,它们确实适用,但是对整个系统的复杂性可能不会对性能)。
也就是说,对于目前考虑的用例,我确信它可以对某些人有所帮助,以后我们自己也会有所帮助。但是,我们现在正在寻求的更多的方法是轻松地允许两个节点或线程响应两个请求的节点修改数据以让一个通过并检测冲突,从而有效地防止相关客户端。
我认为文件锁定对于该用例是足够的,但是优先考虑字节锁定,因为一些最关注的文件被一些客户端不间断地附加,并且被其他人读取/修改到最后。
但是,根据我对LustreOne的回答判断:
也就是说,如果您的申请没有严格的要求 知道它在做什么。 Lustre已经保持不重叠 写入一致,并且可以处理并发的O_APPEND写入。
后一种情况已由Lustre开箱即用。
对什么是最佳选择的任何意见?在完整文件上使用简单的flock()就足够了吗?
请注意,某些文件也会有索引,可用于确定数据的可用性而不锁定任何数据文件,应该使用还是字节锁定足够快,以避免增加代码库大小以支持这两种情况?
关于mmap
的最后一次提及。我很确定它不适合我们的用例,因为我们有很多文件和很多客户端,所以OST可能无法缓存太多,但是要确保......它会被使用,如果是的话,怎么样? ^^
很抱歉这么啰嗦,这是我的不良特质之一。 :/
度过愉快的一天,
答案 0 :(得分:1)
您应该使用" -o flock"安装所有客户端mount选项以启用全局一致锁定。然后flock()(我认为fcntl()锁定)将起作用。
也就是说,如果您的应用程序知道它在做什么,则没有严格的要求。 Lustre已经保持非重叠写入一致,并且还可以处理并发O_APPEND写入。但是,由于Lustre必须对附加执行内部锁定,如果有许多不同的客户端同时附加到同一文件,这会显着损害写入性能。 (注意,如果只附加一个客户端,这不是问题)。
如果您自己编写应用程序,那么您可以做很多事情来提高性能: - 让一些中心线程分配一个"写槽号"每个编写器(本质上是一个递增的整数),然后客户端写入offset = recordsize *插槽号。除了分配插槽号(可以批量完成以获得更好的性能)之外,客户端之间不存在争用。在大多数HPC应用程序中,线程使用MPI等级作为插槽号,因为它是唯一的,并且同一节点上的线程通常将被分配到相邻的插槽,因此Lustre可以进一步聚合写入。如果您使用生产者/消费者模型,其中线程可能产生可变数量的记录,那么这不起作用。 - 使IO记录大小为4KiB的倍数,以避免线程之间的争用。否则,将强制客户端或服务器对磁盘块中的部分记录执行读取 - 修改 - 写入,这是低效的。 - 根据您的工作流程是否允许,而不是读取和写入同一文件,将一堆记录写入一个文件,然后整个处理文件并写入第二个文件可能会更有效率文件。并不是说Lustre不能对单个文件进行并发读写,但这会导致不必要的争用。