上一篇 下一篇 分享链接 返回 返回顶部

如何在香港服务器的Windows Server上部署DFS-R,解决多机房文件一致性与复制延迟?

发布人:Minchunlin 发布时间:2025-08-29 09:12 阅读量:863


凌晨 1:40,我站在香港将军澳机房 7 排 18 柜前,HK-FS01 的硬盘灯一串常亮。监控板上 SMB 写入时延一路红到 600 ms,dfsrdiag backlog 定格在 12,847 条;Teams 里设计部还在追问:深圳刚改过的模型,香港看到的却还是三小时前的版本,新加坡干脆把共享盘拖到本地改。继续靠临时脚本对拷、手工比时间戳只会越救越乱,我当场拍板:上 DFS 命名空间 + DFS-R,做统一入口、按站点就近命中,把复制延迟从“小时级”拉回“分钟级”。我把变更单摊在机柜门上,确定以香港 HK-FS01 为 Hub,深圳 SZ-FS01、新加坡 SG-FS01 为 Spoke,先预置数据、再分时限速——今晚先把这口子止住。

一、现场与目标

站点与链路(真实数值取平均):

站点 服务器 系统/角色 连接带宽 单向 RTT 备注
香港(HK) HK-FS01 Windows Server 2022 Datacenter,AD 成员,文件+DFS 根 专线 1 Gbps 14–18 ms 到深圳;45–60 ms 到新加坡 Hub
深圳(SZ) SZ-FS01 Windows Server 2019 Standard,AD 成员,文件+DFS 专线 500 Mbps 14–18 ms 到香港 Spoke
新加坡(SG) SG-FS01 Windows Server 2022 Standard,AD 成员,文件+DFS 专线 300 Mbps 45–60 ms 到香港 Spoke

文件结构与体量:

  • 共享根:\\contoso.local\Files
  • 关键文件夹:Projects(~800 GB,70 万小文件 + 少量 4–20 GB 的视频/贴图)、Assets、Docs
  • RPO(允许的数据滞后):10 分钟内
  • RTO(现场故障切换):< 30 分钟
  • 约束:不改变用户访问路径,周间白天业务高峰需限速,夜间可放开

方案目标:

  • 统一入口:使用 域型 DFS 命名空间(Domain-based DFSN),站点就近访问。
  • 多主复制:使用 DFS-R 在 HK⇄SZ⇄SG 之间做 Hub-and-Spoke(HK 为 Hub)。
  • 复制优化:RDC 差异复制、大文件预置(pre-seeding)、分时限速、增大 staging/conflict 配额。
  • 可观测性:Backlog 可视化、事件订阅、性能计数器告警。

二、前置检查(别跳过,这些坑我都踩过)

域与 DNS:三台都加入同一 AD 域;站点与子网在“Active Directory 站点和服务”里正确映射。

时间同步:域控对上上游 NTP,成员机与域控对时(DFS-R 对时钟非常敏感)。

卷与路径一致:各站点共享路径保持一致的盘符与目录(例如 D:\Shares\Projects)。

防火墙端口:SMB 445/TCP,RPC 135/TCP,WMI 与 RPC 动态端口(默认 49152–65535/TCP)。

杀软/EDR 排除:排除 D:\Shares\*\DfsrPrivate\*、System Volume Information\DFSR\*、DFS 服务进程。

USN 日志:确保 NTFS USN 日志开启且足够大(大工作集强烈建议手动扩容)。

fsutil usn queryjournal D:
fsutil usn createjournal m=1073741824 a=1073741824 D:

m 与 a 分别是最大与分配大小(此处 1GB/1GB),视体量可上 2–4GB。

不适合 DFS-R 的文件:持续打开/写入的数据库、PST、虚机磁盘(VHDX)等,建议 排除 或改用应用层复制/对象存储。

三、设计要点(为什么这么配)

拓扑:Hub-and-Spoke

  • 全互联在三站点时会产生 N*(N-1) 链路与冲突复杂度;以 HK 为中心,SZ/SG 只与 HK 互联,降低冲突面,也便于限流和排障。

命名空间:域型 DFSN + 站点感知

  • 客户端访问 \\contoso.local\Files\Projects,DFS 根据站点成本把就近的 \\HK-FS01\Projects$、\\SZ-FS01\Projects$、\\SG-FS01\Projects$ 下发为优先顺序。

复制策略:多主 + 边缘只读(可选)

  • 设计/产出在深圳较多,我将 Projects 设为多主;Assets 在 SG 只读(防止边缘误改)。

staging 与冲突目录配额

  • staging 配额建议 ≥ 1.5×最大单文件 或 ≥ 8–32 GB 起步(我们设 32 GB)。
  • conflictAndDeleted 配额 8–16 GB(我们设 16 GB)。

文件筛选

  • 排除临时与巨型不适合同步的文件,减少无效流量与冲突。
~$*; *.tmp; *.bak; *.iso; *.vhdx; *.pst; Thumbs.db; .git\*; .cache\*

分时限速

  • 周一–周五 09:00–20:00:每连接限 25 Mbps(25600 Kbps)
  • 其余时间:不限速(“无限制”)

四、实施步骤(带命令与我当时的操作手法)

1)安装角色与管理工具(所有文件服务器)

# 以管理员 PowerShell 运行
Install-WindowsFeature FS-DFS-Namespace, FS-DFS-Replication, RSAT-DFS-Mgmt-Con -IncludeManagementTools -Restart:$false

2)创建共享与权限(三台一致)

New-Item -ItemType Directory -Path 'D:\Shares\Projects' -Force | Out-Null
New-SmbShare -Name 'Projects$' -Path 'D:\Shares\Projects' -FullAccess 'CONTOSO\Domain Admins' -ChangeAccess 'CONTOSO\Designers' -ReadAccess 'CONTOSO\Domain Users'
# 启用 ABE(基于访问的枚举)
Set-SmbShare -Name 'Projects$' -FolderEnumerationMode AccessBased

注意:NTFS ACL 与共享权限要一致、可继承清晰;跨站点复制 ACL 的变更本身也会触发复制。

3)创建域型 DFS 命名空间与文件夹

# 在 HK-FS01 上执行一次即可
Import-Module DFSN

# 创建域型根:\\contoso.local\Files ,并在 HK-FS01 挂载为命名空间服务器
New-DfsnRoot -TargetPath "\\HK-FS01\Files$" -Type DomainV2 -Path "\\contoso.local\Files" -Description "Global File Namespace"

# 将 SZ 与 SG 作为命名空间服务器加入,提升可用性
New-DfsnRootTarget -Path "\\contoso.local\Files" -TargetPath "\\SZ-FS01\Files$"
New-DfsnRootTarget -Path "\\contoso.local\Files" -TargetPath "\\SG-FS01\Files$"

# 在命名空间下创建逻辑文件夹,并挂上三地实际共享作为目标
New-DfsnFolder -Path "\\contoso.local\Files\Projects" -TargetPath "\\HK-FS01\Projects$"
New-DfsnFolderTarget -Path "\\contoso.local\Files\Projects" -TargetPath "\\SZ-FS01\Projects$"
New-DfsnFolderTarget -Path "\\contoso.local\Files\Projects" -TargetPath "\\SG-FS01\Projects$"

# 启用站点感知与故障恢复
Set-DfsnRoot -Path "\\contoso.local\Files" -EnableSiteCosting $true -EnableTargetFailback $true

如果 Files$ 只是命名空间根的占位共享,可设为仅管理员可见;业务访问走 \\contoso.local\Files\Projects。

4)DFS-R 复制组与成员(Hub-and-Spoke)

这一步我用 GUI(DFS 管理器)做连接的分时限速更直观;其余用 PowerShell。

Import-Module DFSR

# 新建复制组
New-DfsReplicationGroup -GroupName "RG-Projects"

# 添加成员
Add-DfsrMember -GroupName "RG-Projects" -ComputerName "HK-FS01","SZ-FS01","SG-FS01"

# 添加要复制的文件夹(逻辑名)
New-DfsReplicatedFolder -GroupName "RG-Projects" -FolderName "Projects"

# 设定每个成员的本地路径(与共享一致)
Set-DfsrMembership -GroupName "RG-Projects" -FolderName "Projects" -ComputerName "HK-FS01" -ContentPath "D:\Shares\Projects" -PrimaryMember $true
Set-DfsrMembership -GroupName "RG-Projects" -FolderName "Projects" -ComputerName "SZ-FS01" -ContentPath "D:\Shares\Projects"
Set-DfsrMembership -GroupName "RG-Projects" -FolderName "Projects" -ComputerName "SG-FS01" -ContentPath "D:\Shares\Projects"

# 建立 Hub(HK)<-> Spoke 的连接
Add-DfsrConnection -GroupName "RG-Projects" -SourceComputerName "HK-FS01" -DestinationComputerName "SZ-FS01" -Description "HK<->SZ"
Add-DfsrConnection -GroupName "RG-Projects" -SourceComputerName "HK-FS01" -DestinationComputerName "SG-FS01" -Description "HK<->SG"

为什么把 HK 设为 PrimaryMember:初始基线(初始状态)以 HK 为准,减少首次同步冲突。

5)文件预置(Pre-seeding,极大缩短初次同步)

我在业务低谷先从 HK 拷一遍到 SZ/SG,并保留 ACL 与时间戳,DFS-R 会做哈希比对,只传差异。

:: 在 SZ-FS01 / SG-FS01 上,以管理员 CMD 运行
robocopy \\HK-FS01\Projects$ D:\Shares\Projects /MIR /COPYALL /DCOPY:T /R:0 /W:0 /MT:32 /XJ /XD "D:\Shares\Projects\DfsrPrivate" /LOG:C:\preseed_projects.log

/MIR 镜像同步;/COPYALL 保留所有属性与 ACL;/DCOPY:T 保留目录时间戳;/MT 多线程加速。

不要复制 DfsrPrivate。

可抽样对比哈希确认预置效果:

dfsrdiag filehash /path:"D:\Shares\Projects\某大文件.dat"

6)staging 与冲突目录调优

# staging 32 GB,冲突与已删除 16 GB(按容量与文件规模适当增减)
Set-DfsrMembership -GroupName "RG-Projects" -FolderName "Projects" -ComputerName "HK-FS01" -StagingPath "D:\Shares\Projects\DfsrPrivate\Staging" -StagingPathQuotaInMB 32768 -ConflictAndDeletedQuotaInMB 16384
Set-DfsrMembership -GroupName "RG-Projects" -FolderName "Projects" -ComputerName "SZ-FS01" -StagingPathQuotaInMB 32768 -ConflictAndDeletedQuotaInMB 16384
Set-DfsrMembership -GroupName "RG-Projects" -FolderName "Projects" -ComputerName "SG-FS01" -StagingPathQuotaInMB 32768 -ConflictAndDeletedQuotaInMB 16384

7)文件筛选与只读边缘(可选)

在 DFS 管理器 → 复制组 → “Projects” → 属性 → “文件筛选器”:

~$*; *.tmp; *.bak; *.iso; *.vhdx; *.pst; Thumbs.db; .git\*; .cache\*

将 Assets 文件夹在 SG 设为 Read-Only 成员(GUI 勾选),防止边缘误改。

8)分时限速(建议用 GUI 配时段图,更直观)

连接属性(HK↔SZ、HK↔SG)→ 计划:

周一–周五 09:00–20:00:自定义带宽 25600 Kbps

其它时间段:不限制

这样白天不挤占设计师的 SMB 在线编辑体验,晚上快速追平 backlog。

9)让 DFS-R 读取配置并开始跑

# 促使成员尽快拉取 AD 中的 DFS-R 配置
dfsrdiag PollAD /Member:HK-FS01
dfsrdiag PollAD /Member:SZ-FS01
dfsrdiag PollAD /Member:SG-FS01

五、验收与观测(我怎么判断“好了”)

即时 backlog(是否还有未复制的变更)

dfsrdiag backlog /rgname:RG-Projects /rfname:Projects /smem:HK-FS01 /rmem:SZ-FS01
dfsrdiag backlog /rgname:RG-Projects /rfname:Projects /smem:HK-FS01 /rmem:SG-FS01

也可 PowerShell:

Get-DfsrBacklog -GroupName "RG-Projects" -FolderName "Projects" -SourceComputerName "HK-FS01" -DestinationComputerName "SZ-FS01" | Measure-Object

复制状态快照

dfsrdiag replstate

事件日志(常用事件与含义)

事件 ID 含义 我当时如何处理
4102/4104 开始/完成与伙伴的同步 初次建立后看到 4102→4104 基本安心
2213 非正常关机后复制被挂起 用 WMI 恢复(见下)
2212/2214 数据库损坏/重建 等其重建,观察磁盘与 CPU;预置能减少概率
4012 拒绝连接(拓扑不一致/伙伴未准备好) 检查 AD 复制、PollAD、连接方向
5002/5004 staging 清理/失败 增大 staging 或排除巨型文件

快速筛选 DFSR 事件:

Get-WinEvent -LogName "DFS Replication" -MaxEvents 50 | Select TimeCreated, Id, LevelDisplayName, Message

性能计数器(PerfMon 建议)

DFS Replicated Folders:Files Installed、Staging Bytes Generated

DFS Replication Connections:Bytes Sent、Compressed Size

Network Interface:带宽利用

Logical Disk:staging/冲突分区的写入队列

六、那些夜里遇到的坑与处理手记

2213:复制停止(我们在 SZ 突发断电)

观察到 SZ 机器报 2213。解决:

# 查询卷 GUID
wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig get volumeGuid,RootPath
# 恢复复制(替换为实际 GUID)
wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig where volumeGuid="{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" call ResumeReplication

恢复后 dfsrdiag replstate 出现流动,事件 4102 随后出现。

初次同步“卡 0%”

其实是我们没有 pre-seed 完整,ACL/时间戳不一致导致重复比对,改用上面 robocopy 参数后顺利推进。

白天“保存很慢”

白天限速没配,HK↔SZ 链路被 DFS-R 与 SMB 抢带宽。按上面的 分时限速 后,用户编辑明显顺畅。

staging 爆满

大视频频繁改名/剪辑,staging 清理跟不上。把 staging 从 8GB 提到 32GB,并排除 .iso/.vhdx。

杀软误杀 DFSRPrivate

SG 的 EDR 把 DfsrPrivate 扫描当作可疑高 IO,拉黑了 DFSR。将 DfsrPrivate 与 System Volume Information\DFSR 加白名单解决。

AD 站点没配对

客户端在深圳却拿到香港的目标优先,改了 AD 站点与子网映射,DFS 命名空间的站点感知才真正生效。

七、数据与效果(上线一周后的量化)

指标 上线前 上线后(白天限速/夜间放开)
Projects 平均复制延迟 2–3 小时 3–8 分钟(白天) / <1 分钟(夜间)
初次基线用时(800 GB) 约 20 小时(纯复制) 4 小时(pre-seed + 校验)
白天用户 SMB 写入平均时延 明显抖动(> 500 ms) 稳定在 50–120 ms
事件告警(2213/5004 等) 偶发频繁 趋于 0(偶有 4102/4104 正常提示)

八、运维清单(上线/日常/变更)

上线当天

  • dfsrdiag backlog 观测至 <100 条 且持续下降
  • 抽查 10 个大文件的哈希一致
  • 客户端随机抽样打开 \\contoso.local\Files\Projects 验证就近访问

日常(每周)

  • 检查事件日志(筛 5000+ 级别)
  • 观察 PerfMon:连接压缩率、staging 生成速率
  • 盘空间:DfsrPrivate 所在卷保持 > 20% 可用

变更(大批量导入/重构目录前)

  • 临时提高 staging 到 48–64 GB
  • 改为“夜间不限速、白天 10–15 Mbps”
  • 写邮件/群里发布“变更窗”与可能的延迟

九、FAQ(同事们最常问)

DFS-R 会复制文件的“打开中”状态吗?

不会,关闭后才复制;持续写入型文件建议排除。

RDC(远程差异压缩)要不要关?

大多数场景 保留开启 很值,尤其跨站点;CPU 非常弱或全是小文件时,收益有限。

能不能只读边缘?

可以,把边缘成员设为 Read-Only,用于分发类内容(例如 Assets)。

多站点冲突谁赢?

DFS-R 是“最后写入赢”(Last-Writer-Wins),冲突副本会丢到 ConflictAndDeleted,所以 staging 与冲突目录配额要足够大,避免被回收过快。

十、收尾:再回机房那天

两周后我又回到机房,不是因为报警,而是去关掉临时的高水位监控。走廊里仍然很冷,风从机柜前后穿过去。工单里设计团队留言:“现在 \\Files\Projects 随便在哪个办公室打开都一样了。”
我把三地 backlog 又看了一遍,SZ 和 SG 都是个位数,HK 的计数器时不时跳一下,然后回到 0。那一刻我知道,我们从折腾到稳定,只差一份坚持的日常运维了。

附录:常用命令速查

# 促使 DFS-R 成员立即读取配置
dfsrdiag PollAD /Member:HK-FS01

# 查看复制状态(正在传哪些文件)
dfsrdiag ReplState

# 查看 backlog(源 -> 目的)
dfsrdiag Backlog /rgname:RG-Projects /rfname:Projects /smem:HK-FS01 /rmem:SZ-FS01

# 事件快速查看
Get-WinEvent -LogName "DFS Replication" -MaxEvents 100 | Format-Table TimeCreated, Id, LevelDisplayName -Auto

# 抽样文件哈希
dfsrdiag filehash /path:"D:\Shares\Projects\bigfile.mov"

参数与配置表(可作为变更记录附件)

项目
DFSN 根 \\contoso.local\Files(域型 V2)
DFSN 目标 \\HK-FS01\Files$\\SZ-FS01\Files$\\SG-FS01\Files$
复制组/文件夹 RG-Projects / Projects
成员路径 三站点均 D:\Shares\Projects
Primary 成员 HK-FS01
拓扑 Hub-and-Spoke(HK↔SZ、HK↔SG)
staging 配额 32 GB(三站点)
冲突/已删除 配额 16 GB(三站点)
文件筛选 ~$*; *.tmp; *.bak; *.iso; *.vhdx; *.pst; Thumbs.db; .git\*; .cache\*
限速(工作日 09:00–20:00) 25 Mbps/连接
限速(其余时间) 不限制
USN 日志 每卷 1–2 GB
监控 backlog、事件 2213/4102/5004、PerfMon

如果你的环境与我这里不完全一致(比如:无专线、VPN 走公网、服务器版本混用、文件量更大/更小),上面的思路依然适用:命名空间统一入口 + 复制拓扑清晰 + 差异复制与预置 + 分时限速 + 可观测性闭环。

目录结构
全文