首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >网络共享拷贝合作:

网络共享拷贝合作:
EN

Stack Overflow用户
提问于 2013-11-20 09:02:35
回答 2查看 57关注 0票数 0

我有一个网络服务器,它有一个公开一组文件的共享。这些文件由运行在多个服务器上的进程使用,有时是同一台计算机上的多个进程。

这组文件每天更新几次,并且这组文件相当大。

我们试图通过使同一台机器上的进程共享相同的文件集来减少检索这些文件集的进程所使用的带宽。

为此,我们希望同一台计算机上的每个进程与需要相同文件的其他进程进行协调,以便只有一个进程会尝试下载这些文件,然后这些文件将在完成后由所有进程共享。

此外,我们需要防止服务器在下载过程中对文件集执行更新。

为了方便这个需求,我创建了一个文件锁类。该类在指定位置打开一个名为.lock的文件。该文件是以读/写方式打开的,因此它将阻止另一个进程执行相同的操作,而不管该进程在哪台计算机上运行。它被封装在try/catch中,这样如果文件已经被锁定,异常就会被捕获,锁就不会被获取。这已经可以正常工作了。

我试图解决的问题是,如果一个进程由于某种原因挂起,而它拥有锁,所有其他进程将无限期地无法同步这些文件,因为它们无法获得锁。

我们今天探索的一种解决方案是有一个多锁设置,其中每个锁的名称中都有一个guid,而不是争夺一个硬锁,可以根据请求获取任意多个锁。但是,进程将负责确保在开始下载时只设置了一个锁。这就是说,如果一个带有锁的进程挂起,我们可以认为它在特定的时间限制后已经过期,并且没有什么能阻止一个新的进程除了挂起的锁之外还请求一个锁。

这里的问题是,这些多锁的创建需要在进程之间同步,否则在创建和检查锁计数时可能会出现竞争条件。

我看不到像第一个解决方案那样不重新引入硬锁定机制就可以同步的方法,但是我们又回到了开始的地方,挂起的进程将阻止其他进程进行下载。

有什么建议吗?

EN

回答 2

Stack Overflow用户

发布于 2013-11-20 09:20:26

解决这个问题的一种常见方法是使用某种可共享的锁文件,通过内容执行真正的锁逻辑。例如,考虑一个包含单个表作为锁文件的SQlite数据库文件:

代码语言:javascript
复制
CREATE TABLE lock (
  id INTEGER PRIMARY KEY AUTOINCREMENT, 
  host TEXT,
  pid INTEGER,
  expires INTEGER
)

丢弃never-expiring

  • expired行的进程心跳:崩溃的进程将停止更新,最终它们的锁将被丢弃lock

  • Processes持有同一主机上的的最低id可能会评估host字段,以找出同一主机上的另一个进程是否已经想要复制,从而使请求另一个副本的操作作废<UPDATE>H214INSERT>F215>

当然,如果可行的话,可以通过数据库服务器(或者实际上的锁定服务器)而不是数据库文件来完成,但是SQlite方法的优点是只需要文件访问。

票数 0
EN

Stack Overflow用户

发布于 2013-11-20 09:56:56

这里的诀窍是很好地使用缓存。

更新文件集的指定“下载”进程应该首先从远程位置获取文件集,并将其存储在临时文件中。然后,它应该继续尝试获取您想要替换的本地文件的读/写锁。当它成功时,执行交换并删除锁。这部分应该非常非常快。

此外,在本地驱动器上执行简单的文件复制时,也不太可能“挂起”。这意味着,无论这个进程发生什么情况,其他相关进程都将能够继续运行。

为了确保下载进程正常工作,您需要一个监控程序,该程序会经常ping下载进程,以确保它具有响应能力。如果不是,那就通知别人..

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20085417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档