我们正在运行一个.NET 4.5控制台应用程序,该应用程序在远程 LDAP 服务器上执行 USNChanged 轮询,然后将记录同步到Windows Server 2008R2 上的本地 AD LDS。DirSync 控件不是远程服务器上的选项,但获取记录不是问题。
该目录非常大,包含数百万条用户记录。控制台应用程序成功拉下记录并构建本地缓存。然后,它通过缓存流式传输,并根据需要对本地目录上的每条记录进行查找/更新/插入。环境中的各种网络约束的性能在每秒 8 到 80 条记录之间运行。因此,我们使用了任务并行库来提高性能:
var totalThreads = Environment.ProcessorCount *2;
var options = new ParallelOptions { MaxDegreeOfParallelism = totalThreads };
Parallel.ForEach(Data.ActiveUsersForSync.Batch(250), options, (batch, loopstate) =>
{
if (!loopstate.IsExceptional
&& !loopstate.IsStopped
&& !loopstate.ShouldExitCurrentIteration)
{
ProcessBatchSync(batch);
}
});
引入此块后,性能提高到每秒 1000 到 1500 条记录。一些重要的注意事项:
- 这是在八核机器上运行的,因此它最多允许同时进行 16 个操作
Environment.ProcessorCount * 2;
- 使用了 MoreLinq 库批处理机制,因此并行集中的每个任务在返回之前处理给定连接(来自池)上的 250 条记录
- 每个批次都是同步处理的(没有额外的并行性)
- 该实现依赖于 System.DirectoryServices.Protocols (Win32),而不是 System.DirectoryServices (ADSI)
每当执行定期完全同步时,系统将通过大约 110 万条记录,然后AD LDS 返回“服务器忙”并且系统抛出 DirectoryOperationException。它在出错之前完成的数字不是恒定的,但始终接近 110 万。
根据 Microsoft ( http://support.microsoft.com/kb/315071),AD LDS 中的 MaxActiveQueries 值在 Windows Server 2008+ 中不再强制执行。无论如何我无法更改该值,它没有显示。它们还显示“服务器正忙”错误仅因违反该值或每个连接有太多打开的通知请求而返回。此代码仅发送简单的查找/更新/插入 LDAP 命令,并且在发生更改时不向服务器请求任何通知。
据我了解,我最多有 16 个线程协同工作来查询 LDS。虽然他们做得很快,但这是给定滴答声中进入的最大查询数,因为每个查询都是单线程处理的。
微软文档不正确吗?我在这里误解了另一个组件吗?任何帮助表示赞赏。