你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
管理文件锁
Azure 文件存储通过以下协议提供对云文件共享的访问:
- 服务器消息块 (SMB)
- 网络文件系统 (NFS)
- FileREST (HTTPS)
本主题介绍如何管理 SMB 与 FileREST 之间的文件锁定交互。 NFS 文件共享具有不同的锁定语义,并支持 FileREST API 的子集。 本主题不适用于 NFS 文件共享。
SMB 文件锁定
装载文件共享的 SMB 客户端可以使用文件系统锁定机制来管理对共享文件的访问。 其中包括:
- 使用完整文件访问共享可以实现读取、写入和删除。
- 使用字节范围锁可以管理对单个文件中的区域的读取和写入访问。
当 SMB 客户端打开文件时,它将指定文件访问和共享模式。 SMB 客户端通常使用以下文件访问选项,但允许所有组合:
- 没有: 仅打开一个用于查询属性访问的文件。
- 读: 打开一个文件,仅供读取访问。
- 写: 打开一个文件,仅供写入访问。
- 读/写: 使用读/写权限打开文件。
- 删除: 打开一个文件,仅供删除访问。
SMB 客户端通常使用以下文件共享模式:
- 没有: 拒绝共享当前文件。 在文件关闭之前,任何使用读取、写入或删除访问权限打开文件的请求都将失败。
- 共享读取: 允许随后打开文件进行读取。 如果未指定此标志,则打开文件进行读取的任何请求都将失败,直到文件关闭为止。
- 共享写入: 允许随后打开文件进行写入。 如果未指定此标志,则打开文件进行写入的任何请求都将失败,直到文件关闭。
- 共享读/写: 允许随后打开文件进行读取或写入。 如果未指定此标志,则打开文件进行读取或写入的任何请求都将失败,直到文件关闭为止。
- 共享删除: 允许后续删除文件。 如果未指定此标志,则删除文件的任何请求都将失败,直到文件关闭为止。
SMB 客户端打开文件示例
请考虑以下打开文件示例:
文件打开且不违反共享
- 客户端 A 使用
FileAccess.Read
打开文件,FileShare.Write (在打开) 时拒绝后续的读取/删除。 - 然后,客户端 B 使用
FileAccess.Write
FileShare.Read 打开文件, (在打开) 时拒绝后续写入/删除。 - 结果: 这是允许的,因为文件访问和文件共享模式之间没有冲突。
- 客户端 A 使用
由于文件访问而导致的共享冲突
- 客户端 A 使用
FileAccess.Write
打开文件,FileShare.Read (在打开) 时拒绝后续写入/删除。 - 然后,客户端 B 使用
FileAccess.Write
FileShare.Write 打开文件, (在打开) 时拒绝后续的读取/删除。 - 结果: 客户端 B 遇到共享冲突。 客户端指定了客户端 A 之前指定的共享模式拒绝的文件访问。
- 客户端 A 使用
共享模式导致的共享冲突
- 客户端 A 使用
FileAccess.Write
打开文件,FileShare.Write (在打开) 时拒绝后续的读取/删除。 - 然后,客户端 B 使用
FileAccess.Write
FileShare.Read 打开文件, (在打开) 时拒绝后续写入/删除。 - 结果: 客户端 B 遇到共享冲突。 客户端指定了一个共享模式,该模式拒绝对仍打开进行写入访问的文件进行写入访问。
- 客户端 A 使用
FileREST 文件访问
执行 FileREST 操作时,此操作必须遵循为 SMB 客户端上打开的任何文件指定的共享模式。 使用以下文件访问模式确定是否可以完成操作:
FileREST 操作 | 等效的文件访问 |
---|---|
列出目录和文件 | 不适用。 |
创建文件 | 写入、删除。 |
获取文件 | 读取。 |
设置文件属性 | 写入。 |
获取文件属性 | 不适用。 |
设置文件元数据 | 写入。 |
获取文件元数据 | 不适用。 |
删除文件 | 删除。 |
放置范围 | 写入。 |
列出范围 | 读取。 |
租约文件 | 在租约期间写入、删除和共享读取。 |
列出目录和文件、 获取文件属性和 获取文件元数据 不对文件内容进行操作。 这些操作不需要对文件具有读取访问权限 (也就是说,即使 SMB 客户端为独占读取访问) 打开了文件,这些操作也会成功。
下面是与 SMB 共享模式交互的 FileREST 请求的示例:
FileREST 获取文件共享冲突
- SMB 客户端使用
FileAccess.Read
打开文件,FileShare.Write (在打开) 时拒绝后续的读取/删除。 - 然后,REST 客户端对文件 (执行 获取文件 操作,从而使用
FileAccess.Read
上表) 中指定的 。 -
结果: REST 客户端的请求失败,状态代码为 409 (冲突) ,错误代码
SharingViolation
为 。 SMB 客户端仍打开文件,并拒绝读取/删除访问权限。
- SMB 客户端使用
FileREST 放置范围共享冲突
- SMB 客户端使用
FileAccess.Write
打开文件,FileShare.Read (在打开) 时拒绝后续写入/删除。 - 然后,REST 客户端对文件 (执行 放置范围 操作,从而使用
FileAccess.Write
上表) 。 -
结果: REST 客户端的请求失败,状态代码为 409 (冲突) ,错误代码
SharingViolation
为 。 SMB 客户端仍打开文件,并拒绝写入/删除访问权限。
- SMB 客户端使用
下一部分包括 FileREST API 共享冲突情况的综合表。
SMB 客户端共享模式对 FileREST 的影响
根据 SMB 客户端打开文件时指定的共享模式,FileREST 可能会返回状态代码 409 (冲突) 错误代码 SharingViolation
。 下表列出了许多方案。
SMB 客户端文件共享模式 | FileREST 操作失败,并出现共享冲突 |
---|---|
None (Deny Read, Write, Delete) |
对文件的以下读取、写入、租用和删除操作将失败:
|
Shared Read Deny Write, Delete) |
对文件的以下写入、租用和删除操作将失败:
|
Shared Write (Deny Read, Delete) |
对文件的以下读取、租用和删除操作将失败:
|
Shared Delete (Deny Read, Write) |
对文件执行以下读取、写入和租用操作将失败:
|
Shared Read/Write (Deny Delete) |
对文件执行以下租用和删除操作将失败:
|
Shared Read/Delete (Deny Write) |
对文件的以下写入、租用和删除操作将失败:
|
Shared Write/Delete (Deny Read) |
对文件执行以下读取和租用操作将失败:
|
Shared Read/Write/Delete (Deny Nothing) |
删除文件 |
仅当文件在 SMB 客户端上打开时,Azure 文件存储才会返回共享冲突。 要使 FileREST 删除文件 操作成功,不能有针对该文件打开句柄的 SMB 客户端。 有关详细信息,请参阅 删除文件 操作和 FileREST 和 SMB 机会锁之间的交互。
SMB 文件锁定对 FileREST 租用文件 API 的影响
根据 SMB 客户端打开文件时指定的文件访问选项,FileREST 租用文件 API 可能会返回状态代码 409 (冲突) ,错误代码 SharingViolation
为 。 下表提供了进一步的信息:
SMB 客户端文件访问选项 | 使用租约文件 API 获取没有活动租约的文件中的租约 |
---|---|
无 | 成功 |
读取 | 成功 |
写入 | 由于 SharingViolation |
删除 | 由于 SharingViolation |
读取|写 | 由于 SharingViolation |
读取|删除 | 由于 SharingViolation |
写入|删除 | 由于 SharingViolation |
读取|写入|删除 | 由于 SharingViolation |
仅当文件在 SMB 客户端上打开时,Azure 文件存储才会返回共享冲突。 请注意,要使 FileREST 租约文件 操作成功,不能有针对该文件打开 Write 或 Delete 句柄的 SMB 客户端。 有关详细信息,请参阅 租用文件 操作和 FileREST 和 SMB 机会锁之间的交互。
FileREST 租约文件对 SMB 文件锁定的影响
文件租约提供对文件的独占写入和删除访问权限。 当 SMB 客户端打开文件时,它必须遵循 FileREST 租约文件操作租用的任何文件的锁。 可以使用下表确定是否可以完成 SMB 打开文件操作:
FileREST 文件租用状态 | SMB 操作因共享冲突而失败 |
---|---|
已租用 | 使用以下文件访问打开文件的 SMB 客户端将失败:
|
可用 | 无 |
已损坏 | 无 |
SMB 删除对 FileREST 的影响
当 SMB 客户端打开要删除的文件时,它会将该文件标记为 待删除,直到关闭该文件的所有其他 SMB 客户端打开句柄。 当文件标记为待删除时,该文件上的任何 FileREST 操作都将返回状态代码 409 (冲突) ,错误代码 SMBDeletePending
为 。 未返回状态代码 404 (找不到) ,因为 SMB 客户端可以在关闭文件之前删除挂起的删除标志。 换而言之,仅当删除文件后,才应返回状态代码 404 (找不到)。
当文件处于 SMB 挂起删除状态时,它不会包含在结果中 List Files
。
另请注意,FileREST Delete File
和 Delete Directory
操作以原子方式提交,不会导致挂起的删除状态。
文件属性对 FileREST 的影响
SMB 客户端可以读取和设置文件属性,包括:
- 存档
- 只读
- Hidden
- 系统
如果文件或目录标记为 只读,则尝试写入文件的任何 FileREST 操作都将失败,状态代码为 412 (先决条件失败) ,错误代码 ReadOnlyAttribute
为 。 这些操作包括:
Create File
Set File Properties
Set File Metadata
Put Range
无法设置或从 REST 客户端读取这些文件属性。 将文件设为只读后,在 SMB 客户端删除只读属性之前,REST 客户端无法写入文件。
FileREST 和 SMB 机会锁之间的交互
SMB 机会锁 (oplock) 是 SMB 客户端为了提高性能并减少网络传输而请求的缓存机制。 SMB 客户端可以缓存特定文件或目录的最新状态。 有多种机会锁类型,称为 SMB 租约类型:
- 读取 (R) :SMB 客户端可以从本地缓存进行读取。
- 写入 (W) :SMB 客户端可以在本地写入,而无需将数据刷新回 Azure 文件共享。
- 处理 (H) :关闭句柄时,SMB 客户端不需要立即通知 Azure 文件共享。 当应用程序继续使用相同的访问和共享模式打开和关闭文件时,此锁类型非常有用。
这些租约类型独立于指定的访问和共享模式。 通常,无论访问和共享模式如何,SMB 客户端在针对文件打开新句柄时,都会尝试获取所有租约类型。
根据调用的 FileREST 操作,可能需要请求中断现有的机会锁。 对于写入 oplock,SMB 客户端必须将缓存的更改刷新到 Azure 文件共享。 下面是需要破坏每种类型的机会锁的情况:
每当发出写入操作时,都需要断开读取 (R) oplock,例如
Put Range
。每当发出读取操作时,都需要断开写入 (W) oplock,例如
Get File
。每当客户端发出删除操作时,都需要断开句柄 (H) oplock。 Azure 文件存储要求,如果删除操作要成功,则不能打开任何句柄。
当 FileREST 操作面临与现有 SMB 句柄的共享冲突时,句柄 oplock 也会断开。 发生这种情况是验证客户端上运行的应用程序是否仍打开句柄。
中断 oplock 可能需要刷新缓存的 SMB 客户端更改,这可能会导致操作响应时间延迟。 刷新还可能导致操作失败,状态代码为 408 (请求超时) ,错误代码 ClientCacheFlushDelay
为 。
以下部分讨论 oplock 中断的方案。
需要 oplock 中断和 SMB 客户端刷新,并且 REST 客户端遇到延迟
请考虑以下示例:
SMB 客户端打开文件,获取 RWH oplock,并在本地写入数据。
REST 客户端发送
Get File
请求。- Azure 文件共享中断写入 (W) oplock,使客户端具有 RH oplock。
- SMB 客户端针对 Azure 文件共享刷新其缓存数据,并确认 oplock 中断。
- Azure 文件共享处理
Get File
请求并使用请求的数据进行响应。
在此示例中,REST 客户端遇到延迟。 这种情况是由于 oplock 中断以及 SMB 客户端将其数据刷新到 Azure 文件共享所花费的时间造成的。
对 的后续调用 Get File
不会遇到任何其他延迟,因为写入 (W) oplock 已中断。
需要破坏 oplock,但 REST 客户端不会遇到延迟
请考虑以下示例:
SMB 客户端已获取 RH oplock。
REST 客户端发送
Put Range
请求。- Azure 文件共享将 oplock 中断请求发送到 SMB 客户端,并且不会等待响应。
- Azure 文件共享处理请求
Put Range
。
在此示例中,需要 oplock 中断,但 Put Range
请求不会遇到任何其他延迟。 中断读取操作锁时不需要响应。
Azure 文件存储行为
下表总结了每个 FileREST 操作Azure 文件存储的行为。 此行为基于已获取同一文件的句柄的 SMB 客户端的 oplock 状态。 此外,该行为假定 SMB 处理访问和共享与 FileREST 操作不冲突。
如果存在冲突,则也会破坏句柄 oplock,以确保该句柄仍在客户端上打开。 如果出现阻止的 oplock 中断,Azure 文件存储必须等待确认中断成功。 在非阻塞性 oplock 中断的情况下,Azure 文件存储不必等待。
FileREST 操作 | 当前 oplock 类型 | 执行的 Oplock 中断 | 生成的 oplock |
---|---|---|---|
获取文件 | RWH | 是(阻塞) | RH |
获取文件 | RH | 否 | RH |
获取文件 | RW | 是(阻塞) | R |
获取文件属性 | RWH | 是(阻塞) | RH |
获取文件属性 | RH | 否 | RH |
获取文件属性 | RW | 是(阻塞) | R |
列出范围 | RWH | 是(阻塞) | RH |
列出范围 | RH | 否 | RH |
列出范围 | RW | 是(阻塞) | R |
获取文件元数据 | RWH | 是(阻塞) | RH |
获取文件元数据 | RH | 否 | RH |
获取文件元数据 | RW | 是(阻塞) | R |
列出文件 | RWH | 否 | RWH |
列出文件 | RH | 否 | RH |
列出文件 | RW | 否 | RW |
放置范围 | RWH | 是(阻塞) | 无 |
放置范围 | RH | 是(非阻塞) | 无 |
放置范围 | RW | 是(阻塞) | 无 |
设置文件属性 | RWH | 是(阻塞) | 无 |
设置文件属性 | RH | 是(非阻塞) | 无 |
设置文件属性 | RW | 是(阻塞) | 无 |
设置文件元数据 | RWH | 是(阻塞) | 无 |
设置文件元数据 | RH | 是(非阻塞) | 无 |
设置文件元数据 | RW | 是(阻塞) | 无 |
删除文件 | RWH | 是(阻塞) | RW |
删除文件 | RH | 是(阻塞) | R |
删除文件 | RW | 否 | RW |
如果需要阻止 oplock 中断,在某些情况下,FileREST 操作会失败。 如果在指定的请求超时内或在 30 秒内中断不成功(以先完成者为准),则服务将返回状态代码 408 (请求超时) ,错误代码 ClientCacheFlushDelay
。
该 Delete File
请求还要求中断 oplock 句柄 (H) 租约。 中断句柄可确保在 REST 客户端调用 Delete File
时,SMB 客户端应用程序仍不会打开任何文件句柄。 如果存在共享冲突,则请求失败,状态代码为 409 (冲突) ,错误代码 SharingViolation
为 。