6.2. GFS2 节点锁定
要获得最佳 GFS2 文件系统性能,了解其操作的基本原理非常重要。单一节点文件系统带有一个缓存,其目的是在频繁使用时减少磁盘访问所造成的访问延迟。在 Linux 中,页面缓存(以及过去的缓冲缓存)提供了这个缓存功能。
使用 GFS2 时,每个节点都有其自身的页面缓存,该缓存中可能包含部分磁盘数据。GFS2 使用一个称为 glocks (发音为 gee-locks)的锁定机制,用于维护节点间缓存的完整性。glock 子系统提供了一个缓存管理功能,它使用 分布式锁管理器(DLM)作为底层通信层。
glocks 在每个内节点中为缓存提供保护,因此在每个内节点中都有一个锁定用来控制缓存层。如果该 glock 被赋予共享模式(DLM 锁定模式:然后,那个 glock 下的数据会同时被缓存在一个或多个节点上,以便所有节点都可以对数据进行本地访问。
如果 glock 被赋予专用模式(DLM 锁定模式:EX)然后,只有一个节点可以缓存那个 glock 下的数据。此模式供需要修改数据(如 write
系统调用)的所有操作使用。
如果另一个节点请求 glock 但无法立即获得,那么 DLM 会向该节点发送一条信息,或者向目前使用 glock 阻止新请求的节点发送一条信息,要求它们释放其锁定。释放 glock 可能需要较长时间(与大多数文件系统操作相比)。释放一个共享的 glock 只需要将缓存设置为无效,它的速度比较快,并与缓存数据的数量相对应。
释放一个专用 glock 需要清除日志,并将所有更改的数据写入磁盘,然后象共享 glock 一样使缓存失效。
单一节点文件系统与 GFS2 之间的区别在于,单一节点文件系统只有一个缓存,GFS2 在每个节点中都有单独的缓存。在这两种情况下,访问缓存的数据的延迟程度类似,但如果另一个节点之前缓冲了同样的数据,GFS2 对未缓存的数据访问的时间延迟要大得多。
诸如 read
(buffered)、stat
和 readdir
等操作只需要共享 glock。write
(buffered)、mkdir
、rmdir
和 unlink
等操作需要一个专用的 glock。如果写入需要分配,则直接 I/O 读写操作需要延迟 glock,如果写入需要分配,则需要延迟 glock(即扩展该文件或填充)。
这有两个主要的性能注意事项。首先,只读操作可在集群中并行化,因为它们可以在每个节点中独立运行。其次,如果有多个节点可以访问同一内节点,则需要一个专用 glock 的操作可以降低性能。因此,在每个节点上考虑工作集是 GFS2 文件系统性能的重要因素,例如您执行文件系统备份时,如备份 GFS2 文件系统所述。
另外,我们建议您尽可能在 GFS2 中使用 noatime
或 nodiratime
挂载选项,在应用程序允许的情况下首选 noatime
。这可防止读取需要专用锁定来更新 atime
时间戳。
对于关注工作集合或缓存效率的用户,GFS2 提供可让您监控 GFS2 文件系统性能的工具:Performance Co-Pilot 和 GFS2 追踪点。
由于采用 GFS2 缓存的方法,在出现以下任意情况之一时都会获得最佳性能:
- 在所有节点上以只读方式使用内节点。
- 只在单一节点中写入或修改内节点。
请注意,在创建和删除文件的过程中插入和删除目录条目计算为写入目录内节点。
有可能会打破这个规则,但并不常发生。过度忽略这个规则会对性能有严重影响。
如果您对在带有一个读写映射的 GFS2 的一个文件执行 mmap
(),但只从中进行读取操作,则只被看作为一个读操作。
如果您没有设置 noatime
mount
参数,则读取还将会导致更新文件时间戳的写操作。我们建议所有 GFS2 用户都不应该使用 noatime
挂载,除非它们对 atime
有具体要求。