我们有一个巨大的目录树,有很多层深,并且每一层都有(非常)大量的小文件。
有时我们会有大量文件数据更改,树的某些部分会被替换,这些部分的权限需要重置。无法预见下次会更改哪些部分。
这些文件当前位于 Windows NTFS 分区上。
重置权限需要从根目录开始递归执行。这需要花费大半个工作日的时间,而实际要求是几乎立即更改(否则业务会受到影响)。
我尝试过 GUI。我尝试过 robocopy。我尝试过 powershell。我尝试过 Go 库(Windows API 的包装器),因为 Go 以速度快而闻名,但结果收获甚微。
我曾考虑过让应用程序通过符号链接工作,其中符号链接具有限制性权限,而数据具有(非常)宽松的权限。但根本问题仍然存在:在数据替换后,我们仍然需要浏览树并设置这些宽松的权限。
设置组 acl:s 不是解决方案,我们已经使用了它。替换数据具有一组不同的权限,需要替换这些权限。
Windows 不是必需的,我们也运行 Linux。如果其他操作系统平台可以解决设置大量文件权限并通过常见文件共享协议(http、smb 等)访问文件的任务,则可以考虑这样的操作系统。
所以我的问题是:使用 Windows NTFS 作为基准,是否存在文件系统/操作系统组合,可以提供明显更快的递归文件系统操作(设置权限),同时仍通过通用文件共享协议提供文件?
也欢迎程序建议——我和我的同事是否错过了一些比替换文件系统或操作系统更简单的解决方案?
根据建设性意见进行编辑:是的,我们有一个内部开发团队,可以利用系统管理员黑客(我)和精心设计的代码(开发人员)之间的任何东西。
EDIT2 回答@GregAskew 的问题(大概从假期持续到周一)
ACL 中有多少个 ACE?
- 每个 ACL 大约有 8 个 ACE。
文件系统是否针对性能进行了优化(禁用短文件名、禁用最后访问时间)?
- 不,我不知道这些优化,但我会尝试一下。
目录中的最大文件数是多少>
- 必须要测量。
设置 ACL 之前文件系统碎片和目录索引碎片的状态如何?
- 未知,将进行调查。
该卷的分配单元大小是多少?托管该卷的操作系统版本是什么?
- 目前,VMware vSAN 托管着 Windows 2008 R2 Std,即将升级到 Win2016 Std。
您是否在本地设置权限(根据另一条评论,似乎您正在通过网络执行此操作)?
- 我们在虚拟机本地设置权限,然后让它们进行 DFS 复制以实现冗余(非常痛苦,需要重新设计)。我们完全控制设计,只是初始文件交付的实现不受我们控制(但根据评论,我们可能会尝试更改这一点)。问题只是关于更改本地文件权限(我知道底层 SAN 是网络连接的,但我仍然很乐意接受这方面的建设性建议)。
答案1
避免频繁递归更改 ACL 的标准流程(至少自 1990 年代以来)是使用“访问组”来分配权限。
因此,用户被放入角色组中,角色组又被放入访问组中。权限实际上是通过访问组授予的,并且绝不直接授予用户或角色组。
就您而言,您可能希望为文件夹结构的每个级别都设置一个“访问组”,直到您需要唯一的权限。
当新数据进入时,您创建组“AccessReadFolderX”和“AccessWriteFolderX”,然后设置新文件夹的权限(阻止从其父级继承)。然后,您将新数据复制到此文件夹中。
使用此方法,您永远不会更改文件系统上的 ACL。相反,您只需修改 AD 中的组和用户的嵌套。
答案2
TL;DR 答案:使用更快的磁盘。
说真的,答案很简单。如果你想要“拥有一个庞大的目录树,多层级,每层都有(非常)多的小文件”,为了重置目录树任何部分的权限,你需要对每个文件执行 IO 操作。这需要时间,如果你使用类似慢的5400 rpm SATA 磁盘用于存储,这需要更多时间。像这样的慢速磁盘每秒只能执行大约 40-50 次 IO 操作,而且你无法对此进行任何改进。如果你必须以每张磁盘每秒大约 15-20 个文件的速度更新数百万个文件,那么这将需要时间。当你必须完成这项工作时,文件系统实际上并不重要。
性能良好的 7,200 RPM SATA 驱动器每秒可进行约 70 次 IO 操作,性能良好的快速 SAS 驱动器每秒可进行 200-300 次 IO 操作。SSD 可以进行数千次 IO 操作。
而且由于文件元数据往往分布在几乎所有文件系统的整个磁盘上,因此任何文件系统都无法提高性能,除非您使用昂贵而复杂的文件系统,例如 IBM 的 GPFS 或 Oracle 的 QFS(无论它们现在叫什么)。如果 HP 的 Ibrix 仍在销售,它也可能适合您。但这些文件系统价格昂贵,并且需要大量专业知识才能管理。
您可以尝试将 NTFS 的 IO 操作从默认的 设置为HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisableLastAccessUpdate
来限制。这至少会在您浏览目录树更新权限时禁用访问时间更新。这可能会有所帮助。1
0
更好的答案是设计一个不需要对海量数据存储进行大量更改的系统。因为当“实际要求几乎是即时更改(或业务受损)”时,这是一个非常非常糟糕的设计。
答案3
假设所有文件都需要来自给定根的相同权限,那么用 c++ 或 c# 编写自己的“acl setter”可能会有所帮助。它应该在编写权限之前先检查权限是否正确,然后才能使用异步线程。