本文讨论 Windows 中(具体而言,是 DFSR 复制的文件夹中)缺少多主机分布式文件锁定机制的问题。
- 分布式文件锁定 – 指的是这么一个概念:多台计算机上存在某个文件的多个副本,打开其中一个副本进行写入时,所有其他副本就会被锁定。 这可以防止多个用户同时在多个服务器上修改某个文件。
- 分布式文件系统复制 (DFSR) 在多主机、基于状态的设计中运行。 在基于状态的复制中,多主机系统中的每个服务器在其副本抵达时这些副本应用更新,且不会交换日志文件(而是改用版本向量来维护“最新”信息)。 在完成初始同步后,任何一台服务器都永远不是任意性的权威服务器,因此它在各种网络拓扑上高度可用且非常灵活。
- 服务器消息块 (SMB) 是 Windows 中用于通过网络访问文件的常用协议。 简而言之,它是一种利用重定向器的客户端-服务器协议,能使远程文件系统看起来像是本地文件系统。 它并非专门与 Windows 有关,而且一门相当通用的技术 – 众所周知的与 Microsoft 无关的示例是 Samba,它允许 Linux、Mac 和其他操作系统充当 SMB 客户端/服务器并参与 Windows 网络。
清楚地描述 DFSR 和 SMB 在复制数据环境中的位置非常重要。 SMB 允许用户访问自己的文件,且无法感知 DFSR。 同样,DFSR(使用 RPC 协议)使文件在服务器之间保持同步,且无法感知 SMB。 请不要混淆本文中定义的分布式锁定和机会锁定。
正如 Brits 指出,事物在此处可能呈梨形分布。
由于用户可以修改多台服务器上的数据,并且每台 Windows 服务器只知道本身的文件锁,另外,DFSR 对其他服务器上的这些锁一无所知,因此,用户可以覆盖彼此的更改。 DFSR 使用“最后写入者获胜”冲突算法,因此必须有一个写入者认输,而最后保存的人可以保留他们的更改。 丢失的文件副本被放入 ConflictAndDeleted 文件夹中。
现在,这种情况远没有人们相信的那样常见。 通常,真正的共享文件是在本地环境中修改的:在分支机构或同一排小隔间中。 这些文件通常由同一个团队的成员共同处理,因此人们通常都知道同事在修改数据。 由于他们通常在同一个场地,处理共享文档的所有用户使用同一台服务器的可能性要高得多。 Windows SMB 可以处理这种情况。 当某个用户锁定文件进行修改并且其同事试图编辑该文件时,另一个用户将收到如下错误:
如果打开文件的应用程序确实很聪明(例如 Word 2007),它可能会显示:
DFSR 确实为锁定的文件提供了一个机制,但该机制只能在服务器自身的上下文中工作。 如果某个文件的本地副本具有独占锁,则 DFSR 不会将该文件复制进来或复制出去。 但这不会阻止另一台服务器上的任何人修改该文件。
回到我们的话题,在地理上修改共享数据时面临的问题确实存在,而且对于某些人来说,此问题相当棘手。 偶尔有人问我们,为何 DFSR 不处理这种锁定,通过挥舞魔杖来摆平一切。 事实证明,对于多主机复制系统,这是一个有趣且难以解决的情况。 接下来,将探索双精度类型。
有一些供应商可以解决此问题,他们通常采用以下一种或多种方法*:
- 使用中介机制
指派一名中心“交通警察”,使一台服务器能够感知所有其他服务器以及被用户锁定的文件。 遗憾的是,这也意味着分布式锁定系统中经常会出现单一故障点。
- 完全路由网络的要求
由于中心中介必须能够与参与文件复制的所有服务器通信,此机制无法处理复杂的网络拓扑。 环形拓扑和多中心/分支拓扑通常是不可行的。 在非全路由网络中,某些服务器可能无法直接相互通信或者与中介通信,而只能与某个伙伴通信,不过该伙伴本身就能与另一台服务器通信 – 各种问题不一而足。 这种拓扑在多主机环境中是可行的,但不适合与中介机制配合工作。
- 仅限一对服务器
某些解决方案将拓扑限制为一对服务器,以简化其分布式锁定机制。 对于较大的环境,这种方案可能不可行。
- 在客户端和服务器上使用代理
- 不使用多主机复制
- 不使用 MS 群集
- 使用专业设备
*请注意,我说的是典型情况! 请不要过于极端,因为解决方案可以执行,也可以不执行其中的一种或多种方法!
当你进一步思考此问题时,一些根本性的问题开始浮现。 例如,如果我们有四台服务器,其中的数据可由四个场地的用户修改,而其中一台服务器的 WAN 连接断开了,我们该怎么办? 用户仍可以访问他们各自的服务器 – 但我们应该让他们访问吗? 我们不希望他们做出有冲突的更改,但绝对希望他们继续保持工作,为公司赚钱。 如果我们在当时任意阻止他们做出更改,即使实际上可能不会发生任何冲突,也没有任何用户可以正常工作! 没有办法告知其他服务器该文件正在使用中,于是你又回到了原来的问题。
我们要处理 SMB 本身的问题,还要处理报告锁的错误。 我们无法真正改变 SMB 报告共享违规的方式,因为这需要调查大量的应用程序,而且客户端无论如何也不会理解新的扩展错误消息。 Word 2007 之类的应用程序会采取一些秘技来确定谁正在锁定文件,但绝大多数应用程序并不知道谁正在使用文件(甚至不知道 SMB 是否存在。确实是这样。) 因此,当用户收到“此文件已被使用”消息时,这种问题还真不好处理 – 他们都应该呼叫技术支持吗? 技术支持是否有权访问所有文件服务器,查看哪些用户正在访问文件? 非常棘手。
由于我们希望通过多主机实现高可用性,而中介系统不太符合需要,因此可能需要在所有服务器上运行某种软件,使所有服务器甚至可以通过非完全路由网络进行通信。 这需要用到非常复杂的同步技术。 它会在网络上增加一些开销(虽然可能不多),并且需要很快地确保我们不会防碍用户的工作;它需要超越文件复制本身 - 事实上,这种方案可能需要真正与复制保持某种程度的关联性。 它还必须考虑与网络相关的服务器中断,而不是服务器崩溃。
我们回到此方案的特殊客户端软件,它可以更好地理解锁并为用户提供一些有用信息(“去给会计部门的 Susie 打电话,让她发布那个文档”、“对不起,文件锁定拓扑已损坏,你的管理员阻止你打开此文件,直到文件被修复”,等等)。 让该软件与 Windows 中运行的数百万个应用程序完美配合工作肯定很有趣。 有很多操作系统不受支持或无法安装该软件 – Windows 2000 已不再享受主流支持,而 XP 很快也是如此。 Linux 和 Mac 客户端只有在觉得该软件非常重要时才会安装该软件,因此客户只能希望他们的供应商能够开发类似的软件。
现在,在 DFSR 中控制这种情况的最简单方法是使用 DFS 命名空间将用户导向至可预测的位置,并使用一致的命名空间。 通过正确配置 DFSN 站点拓扑和服务器链接,可以强制所有用户共享同一个本地服务器,并且只允许他们在“主”服务器关闭时访问远程计算机。 对于大多数环境而言,这种方法非常有效。 SharePoint 是可以替代 DFSR 的一个选项,因为它有签出/签入系统。 BranchCache(在 Windows Server 2008 R2 和 Windows 7 中引入)可能是一个选项,因为它旨在简化分支方案中的文件读取,但权威数据最终仍仅驻留在一台服务器中 – 此处了解提供了详细信息。 同样,这些供应商也有他们的解决方案。