see also:Data Replication
Step1:向复制伙伴发起请求
假设DC服务器A和B互为复制伙伴,在某个时间点服务器A向B发起复制请求。服务器B会把更新传输给A,这是一个单向的复制过程。没有更新从A传输到B。
除非B向A发起另一个请求开始另一个复制过程。
如果服务器A
服务器A发送的请求中包括5个重要的复制相关的元数据:
1.服务器A希望接受的更新的NC
2.可接收的最大对象数目
3.可接收的最大数量
4.服务器A的High-watermark矢量表中B的USN (方便B对照自己的USN来大概估计有没有和有多少更新,2个USN之差)
5.服务器A的Up-to-Dateness矢量表 (方便B过滤出A上已经有了的更新)
如下图:图2 Initiating replication with Server B for NC xxxx
注意:在对站点链接规划复制时间安排的时候,要考虑到这一点:当一个复制周期开始后,它会一直复制所有的更新
而不管包有多少或者需要多长时间除非网络连接完全中断。你可以指定复制什么时候开始,但是无法指定它什么时候
结束。复制会一直进行直到完成或者DC直接的物理网络连接中断。
Step2:复制伙伴找出需要发送的更新
server B首先找到自己的NC拷贝的最高USN,和A发给自己的HWMV中B的USN比较.
如果有更新,B马上就能知道了。只需比较USN之差。
但是问题是也许B上的某些更新A上已经有了(A可能从其他DC复制了这些更新),如何过滤掉这些A不需要的更新呢?
UTDV起的就是这个作用。
对于每个B将要发送给A的更新,B检查2个数据:Originating-DC-GUID和Originating-USN.
例如用户密码的修改在D上,在B的UTDV中,原始修改DC是D,原始DC相应的USN=2345.
B检查A发送的UTDV,如果发现 UTDV中server D的USN>=2345,那说明A上已经有这个更新了。
假定B已经有4个更新相对于A如下图:1个原始写和3个复制写。
A发来的HWMV(水印)中B的最高USN为1108. 所以更新应该从1109-1112.
Server B USN |
Originating DC GUID |
Originating DC USN |
---|---|---|
1109 |
Server E's GUID |
567 |
1110 |
Server E's GUID |
788 |
1111 |
Server B's GUID |
1111 |
1112 |
Server D's GUID |
2345 |
根据图2,A已经有了serverD的2345更新,因为A的UTDV中D的USN是2350.因此A和B都已经有了D上的2345更新。
所以没有必要浪费带宽去再次发送一次了。
那么具体B是如何筛选出需要发生的数据的呢?
当B收到A的请求时,它拷贝一份A发过来的的UTDV,建立一个表,然后搜索整个NC,查找所有对象的usnChanged属性值,
如果该值大于A发送的HWMV(高水印)中B的USN,就列入表中。该表按usnChanged大小升序排列
接下来,server B建立一个空的输出缓冲区用来存放将要发生给A的更新条目。
同时B也初始化一个称作Last-Object-USN-Changed的值。这个值用来表示复制过程最后发送的对象的USN.
这个值不是任何对象的属性,只是一个传输数据。serverB 接着枚举升序排列的表中的对象,使用以下算法对每个对象计算一番:
1.如果对象已经在输出缓存区,server B就设置Last-Object-USN-Changed为该对象的usnChanged属性值,然后计算下一个对象。
2.如果对象还没有加入缓冲区,server B就测试对象看是否它包含了需要被发送的更新。对于对象的每个属性,server B
检查其原始写的DC-GUID然后查找A发过来的UTDV中相应的DC所对应的USN,与属性的原始USN比较,
如果大于A的UTDV表中的USN值,那么这个属性就应该被发送,更新条目被加入到输出缓冲区。
server B设置Last-Object-USN-Changed值为当前对象的usnChanged值。之后继续下一个
如果没有更新要发送,就设置Last-Object-USN-Changed值为当前对象的usnChanged值,继续下一个。
在此过程中,如果达到A所要求的请求限制(对象更新数量或者最大值),则提前终止,一个标记
More-Data被设置为真。反之则为假。
Step3:复制伙伴传输更新给发起服务器(B到A)
B将更新发生给A,如果more-data=false,一个额外的metadata将被发送。
B发送如下信息给A
1.B的输出缓冲区的内容
2.B的Last-Object-USN-Changed值
3. More-Data 标记
4.B的up-to-date 矢量(当more-data=false时发送)
如图:
Server B sends the updates to Server A for NC xxxx
当B计算出A已经更新过了而不需要从B得到更新了,那么只有后2项发送给A.
这一般发生在如下情形:
1.B的最高USN和A发送过来的HWMV(高水印)中B的USN一样--例如没有更新发生自上次更新后
2.B的最高USN已经改变了,但是A已经从其他复制伙伴得到了所有B已知的原始更新。
|
Step 4. 发起服务器处理更新 A处理更新
A逐条更新从B得到的数据,根据分配的事务号修改每个对象的usnChanged的属性。
之后A的HWMV(高水印表)中的B的值设置为Last-Object-USN-Changed--(从B得到的)
换句话说,A现在知道了它和B更新到一样的了
上个例子中,server B的USN 1112没有发生给A,因为A已经有该更新,但是
Last-Object-USN-Changed仍然是1112而不是1111.
Step5. 发起服务器检查是否达到更新状态
A检查more-Data状态,如果=ture,继续步骤1.
如果=false,所有更新应该都从B收到了。最后A的up-to-dateness矢量也会自我更新。
A逐条检查收到的UTDV表条目然后做2件事情:
1.如果一个服务器条目没有列在自己的UTDV中,则增加该条目--A知道有了新的服务器。
2.如果条目存在,并且收到的值更大,则用新的值修改现有的UTDV。
最后,A被更新了,并且有比B更好的记录。
HWMV for Server B |
Server B UTDV |
Server C UTDV |
Server D UTDV |
Server E UTDV | |
---|---|---|---|---|---|
Before step 1 |
1108 |
1108 |
100 |
2350 |
540 |
After step 5 |
1112 |
1111 |
100 |
2350 |
790 |
总结:
1.HWMV(高水印值)矢量用于检查哪些更新需要发送
2.UTDV矢量用于筛选出发起服务器没有见过的更新。
3.每个对象上的usnChanged属性用于标识哪些对象需要被作为更新发送。
note:DC上可以强制更新
复制冲突解决:
1.对象建立时名字冲突:
版本号>时间戳>原始写DC的GUID
未赢得的对象不会丢失或者删除,而是被修改为一个已知的统一值。最终,2个对象都存在,
只是其中一个的冲突的名字改为统一值。这个统一值如下组成:objectname lineFeed CNF: objectGUID
2.同一属性修改
版本号>时间戳>GUID
所有的复制元数据的时间戳都是GMT时间
3.在一个正在删除的父容器下移动或者建立对象
父容器被删除,对象被移动到lost and found 容器。
http://www.cnblogs.com/jjkv3/admin/ldap://cn=LostAndFound,dc=microsoft,dc=com