繁体   English   中英

锁定分布式系统中的文件

[英]Locking file in distributed system

我有一个分布式应用程序; 也就是说,我有一个在多个计算机上运行的同质进程,这些计算机与中央数据库进行对话并访问网络文件共享。

此过程(通过CIFS)从网络文件共享中选择收集文件,对这些文件运行转换算法,然后将输出复制回网络文件共享中。

我需要锁定输入文件,以便其他运行相同进程的服务器无法在相同文件上运行。 为了便于讨论,假设我的描述过于简单,并且锁是绝对必要的。

这是我提出的解决方案和一些想法。

1)使用机会锁(oplock)。 此解决方案仅使用文件系统来锁定文件。 这里的问题是,我们必须尝试获取锁以查明该锁是否存在。 这似乎是昂贵的,因为网络重定向器会协商锁定。 这样做的好处是,可以以这样的方式创建操作锁:当出现错误时,它们可以自行删除。

2)使用数据库应用程序锁(通过sp_getapplock)。 这似乎会快得多,但是现在我们正在使用数据库来锁定文件系统。 另外,数据库应用程序锁可以通过事务或会话来确定范围,这意味着如果我要保留(并在以后发布)应用程序锁,则必须保留连接。 当前,我们正在使用连接池,该连接池必须进行更改,这本身可能是一个更大的话题。 这种方法的好处是,如果我们失去与服务器的连接,锁将被清理。 当然,这意味着如果我们失去与数据库的连接,但没有失去网络文件共享,则在我们仍在处理输入文件时,锁将消失。

3)创建一个数据库表和存储过程来表示我想锁定的项目。 这个过程很简单。 不利的一面当然是潜在的网络错误。 如果由于某种原因数据库无法访问,则锁定将保持有效。 然后,我们需要导出某种算法以在以后进行清理。

最佳解决方案是什么?为什么? 答案不限于上面提到的那些。

对于您的情况,您应该使用共享模式锁。 这正是他们的目的。

Oplock不会满足您的要求-Oplock并不是锁,并且不会阻止任何人做任何事情。 这是一种通知机制,可让客户端计算机知道是否有人访问该文件。 这是通过“破坏”您的oplock来传达给计算机的,但这并不是通往应用程序层(即通往您的代码)的方式-它只是向客户端操作系统生成一条消息,告诉它使缓存无效。复制并再次从服务器获取。

在此处查看MSDN:

这里是当另一个进程打开一个您持有oplock的文件时发生的情况的解释:

但是,重要的一点是oplock不会阻止其他进程打开文件,它们只是允许客户端计算机之间进行协调。 因此,oplock不会在应用程序级别锁定文件-它们是网络文件系统堆栈用于实现缓存的网络协议的功能。 它们并不是供应用程序真正使用的。


由于您是在Windows上编程,因此合适的解决方案似乎是共享模式锁定,即使用SHARE_DENY_READ|SHARE_DENY_WRITE|SHARE_DENY_DELETE打开文件。

如果CIFS服务器不支持共享模式锁,则可以考虑使用flock()类型的锁。 (以传统的Unix技术命名)。

如果您正在处理xyz.xml创建一个名为xyz.xml.lock的文件(使用CREATE_NEW模式,这样就不会破坏现有的文件了)。 完成后,将其删除。 如果由于文件已存在而无法创建该文件,则意味着正在处理另一个进程。 将信息写入锁定文件可能很有用,这对调试很有用,例如服务器名和PID。 您还必须有一些清除废弃锁文件的方法,因为这不会自动发生。

例如,如果CIFS是复制系统,则数据库锁可能是合适的,这样flock()锁就不会在整个系统上自动发生。 否则我会坚持使用文件系统,因为那样只会出错。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM