一篇非常好的Microsoft Sync Framework的介绍文章,通俗易懂的概述了MSF的使用场景和逻辑结构。分享给大家。
MSDN原文地址:http://msdn.microsoft.com/en-us/sync/bb821992.aspx
内容
简介
参与方
参与方类型
Microsoft Synchronization Framework
核心组件
数据源
元数据
同步流程
同步示例
冲突示例
摘要
Microsoft Sync Framework 是为应用程序、服务和设备启用协作和离线方案的综合性同步平台。它的特色在于提供了能够漫游、共享和离线提取数据的技术和工具。通过使用 Microsoft Sync Framework,开发人员可以构建同步生态系统,该生态系统能够将任何应用程序与任一网络的任意数据集成,无论它们存储在何处,使用何种协议。
Microsoft Sync Framework 最重要的功能是创建自定义同步提供程序。提供程序是代表同步副本的软件组件。副本是将要进行同步的特殊信息仓库,例如手持设备的文件系统。当代表数据源时,提供程序枚举其副本的变化。当代表目的端时,提供程序将变化应用于副本。如果源端和目的端数据在类型或架构方面存在差异,则每个提供程序都将执行各种必需的映射或转换。
Microsoft Sync Framework 包括大量支持常见数据源的提供程序。尽管您可以为这些数据源编写自定义提供程序,但建议您尽可能地使用 Microsoft Sync Framework 提供的提供程序。因为这样能够将开发时间减到最少,并使您能够重用经过测试的现成代码。包括下列提供程序:
开发人员最终能够使用所提供的所有提供程序,或创建自定义提供程序在设备和应用程序之间交换信息。
本文档其余部分旨在帮助您了解 Microsoft Sync Framework 如何使用同步构建同步拓扑。我们将列出一些有关同步提供程序的主要概念,它们将帮助您理解如何创建提供程序。有关 Microsoft Sync Framework 的更多详细信息,请参阅 http://msdn2.microsoft.com/en-us/sync/default.aspx。
在讨论特定提供程序组件之前,我们需要首先了解 Microsoft Sync Framework 支持的不同类型的同步参加方。参与方是提供程序及其关联副本的组合。要同步的副本(即信息仓库)可以是取自 Web 服务、笔记本电脑、乃至 U 盘中的任何对象。
Microsoft Sync Framework 支持三种类型的参与方:完整、部分和简单。参与方的类型由其存储和处理同步元数据的能力定义。至少,我们可以假定如有请求,副本具备编程返回信息的能力。最后需要确定的是副本是否能够:
区分将成为同步生态系统一部分的参与方的类型十分重要,因为它使我们了解到该参与方是否能够存储提供程序所需的状态信息,以及我们是否能够直接在设备上运行提供程序。最终,参与方模型将成为通用模型。因此,可以将完整参与方配置为部分或简单参与方。
完整参与方是指允许开发人员直接在设备上创建应用程序和新数据存储的设备。笔记本电脑和智能电话就属于完整参与方,因为可以直接从此类设备执行新的应用程序,并且如有必要,您还可以创建新的数据存储以保存信息。
部分参与方是指能够在设备上存储数据的设备。但这些设备无法直接从设备上启动可执行程序。部分参与方的重要特性在于它能够存储同步所需的元数据,并因此得以与任何完整参与方进行同步。部分参与方的一个例子是 U 盘。这些设备类似于硬盘,能够创建、更新或删除信息。但通常它们不提供使应用程序能够直接在设备上运行的接口。
简单参与方是指仅具备当接到请求时提供信息这一种能力的设备。此类设备不能存储或操作新数据,而且不支持创建新的应用程序。简单参与方依靠完整参与方存储其元数据(因此只能与特定的完整参与方进行同步)。
由外部组织(如 Amazon 或 EBay)提供的 RSS 源和 Web 服务都属于简单参与方。这些组织可能会赋予您执行 Web 服务并取回结果的能力,但不会赋予您在其 Web 服务器上创建您自己的数据存储或执行您自己应用程序的能力。
Microsoft Sync Framework 的最终目标是,无论数据源采用哪种参与类型,都允许对它们进行集成。因此,简单和部分参与方可以与完整参与方同步信息。这至少需要一个能够存储信息和启动同步过程的完整参与方。
在使用 Microsoft Sync Framework 实现同步之前,我们需要首先了解同步提供程序的关键组件。将在本文档后面的同步示例中进一步说明这些概念。
下图显示了提供程序如何与数据源进行通信并从元数据存储中检索状态信息。这些提供程序依次通过同步会话与其他提供程序进行通信。
数据源是指存储所有需要同步的信息的位置。数据源可以是关系数据库、文件系统、Web 服务,甚或一系列业务应用程序中包含的自定义数据源。凡是能够以编程方式访问的数据都可以参与同步。
提供程序的基本特征在于它能够存储有关数据存储以及该数据存储中与状态和更改信息相关的对象的信息。元数据可以存储在任意位置,无论它是文件、数据库还是现有的副本数据存储。为方便起见,Microsoft Sync Framework 提供一个以 SQL Server Compact Edition 为基础的完整元数据存储实现。该存储并非必要,但使用它意味着您不必担心如何存储同步元数据。
用于数据存储的元数据可以分为三个主要组件:
当项目发生更改时,存储的有关该更改的信息将包括创建版本 和更新版本。这些版本包含两个组件:a 滴答计数 它是一个在整个源范围内使用以唯一标识一个更改的逻辑时钟,以及一个副本 ID 它用于唯一标识发生更改的数据存储。当首次创建项目时,创建版本与更新版本相同。对该项目的后续更新修改的只是更新版本。
必须至少在项目级别上跟踪所有的更改。换句话说,每个项目必须具备独立的版本。 在某些情况中需要更大力度的跟踪以减少潜在的数据冲突(两位用户在不同的副本上更新相同的项目)。这种方法的弊端在于它增加了需要存储的更改跟踪信息量。
两种主要的版本实现方式是:
因为 tombstone 日志中的信息将随时间增加,所以有必要创建一个进程定期清理该存储。清理 tombstone 数据能够节省空间并且有助于改善同步性能。Microsoft Sync Framework 支持管理 tombstone 信息。
发起同步的副本称为源 而源所连接的副本称为目标。本文接下来的部分将介绍下图所示的同步流程。对于双向同步,将执行此进程两次,第二次迭代时会交换源和目标。
目标端发起同步会话
在这一阶段将建立同步会话,从而创建了从源到提供程序的链接。
目标准备并发送知识
如前所述,每个副本都会存储其自身的知识。存储在目标端的知识将传递到源。
目标知识用于确定要发送的更改
在源端,会将刚刚收到的知识与本地项目版本进行比较,以确定目标端尚不了解的项目。值得注意的是,发送的版本并不是实际的项目,而是每个项目上次发生更改的位置摘要。
更改版本和发往目标端的源知识
当源准备好所需的更改版本列表之后,这些版本将传输到目标端
检索更改项目的本地版本并与源版本和知识进行比较
目标端使用这些版本准备源需要发送的项目列表。目标还使用该信息检测是否存在限制冲突。限制冲突是指违反了项目限制,如文件夹关系或文件系统中同名数据的位置。
检测并解决或推迟冲突
基本上,如果在两次同步期间对两个副本上的相同项目进行更改就会发生冲突。在 Microsoft Sync Framework 运行时中,当其中一个副本的更改版本不包含另一个副本更改的知识时便会检测到冲突。 将在下面的“冲突示例”部分中介绍了说明该检测过程如何工作的更加详细的示例。
副本可以自由实施各种策略,解决同步拓扑间发生冲突的项目。下面列举了一些常用的冲突解决策略:
目标向源请求项目数据
在这一阶段,目标已经确定需要在源中检索的项目,并将请求发送到源。
源准备并发送项目数据
源接收到项目数据请求,并准备要传输到目标的实际数据。如果要跟踪的项目是数据库中的一行,则将发送该行。如果项目是文件夹中的文件,则将传送该文件。
项目应用到目标中
目标接收并应用项目。如果在此过程中出现任何错误(如网络断开),则该项目将被标记为异常,并在下次同步期间进行更正。从源接收的知识将添加到目标知识。
通过使用前面介绍的同步流程,我们将实际操作一次文件同步示例,该示例将说明 Microsoft Sync Framework 如何枚举更改并最终应用项目数据。在本例中有两个副本:副本 A 和副本 B。副本 A 启动与副本 B 的同步(即副本 A 是源而副本 B 是目标)。假定我们希望同步两个副本间的文件。要跟踪的项目是文件夹中的一个文件,表示为 In (例如,I1, I2, I3…)。创建新文件时 (I1) 与该文件相关联的元数据应更新如下:
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I1 | 1 | A | 1 | A |
如果文件再次更新,版本表应如下所示:
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I1 | 5 | A | 1 | A |
在上述示例中,更新滴答计数设置为 5,这是由于用于滴答计数的逻辑时钟在整个源内发挥作用,即:滴答计数 2-4 已用于副本中其他项目的更改。
例如,在下面的图例中,跟踪的副本中有两个附加的项目 I2 和 I3 。您可以看到,随着创建更多的项目,版本信息将变得越来越多。Microsoft Sync Framework 不要求存储以前的更新版本。它只需要了解最新的更新版本。
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I2 | 3 | A | 2 | A |
I3 | 4 | A | 4 | A |
I1 | 5 | A | 1 | A |
如果采用该副本的当前项目状态,我们可以把副本 A 的知识表示为:
副本 A 知识 = A5
如前所述,知识是副本能够感知的数据更改的简约表述。在本例中,A 是分配给该副本的唯一 ID,而 5 是当前滴答计数,它使副本能够了解当前的最大变化个数。如果该副本已经与任意其他副本进行同步,则我们还将在该列表中看到这一知识。
在副本 B 上可能也有很多文件。该副本如下所示:
副本 B
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I104 | 2 | B | 1 | B |
I105 | 4 | B | 3 | B |
副本 B 的当前知识为:
副本 B 知识 = B4
此时我们选择开始在两个副本之间进行同步。副本 A 将成为源(启动同步的副本),副本 B 将成为目标。
同步过程中,目标向源发送其知识。如前所述,两个副本的知识如下:
副本 A 知识 = A5
副本 B 知识 = B4
源(副本 A)收到该知识并使用它来确定将哪个版本发送到目标。由于副本 B 不了解在副本 A 中的任何项目,所以它将发送所有内容。在本例中,副本 A 将包含以下版本。
副本 A 的更改批次
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I2 | 3 | A | 2 | A |
I3 | 4 | A | 4 | A |
I1 | 5 | A | 1 | A |
目标接收这些版本并对其进行枚举以确定需要从源请求哪些项目。它还使用该信息确定是否存在任何冲突(例如,在两个副本上更新了相同的文件)。
完成后,目标请求源发送它没有感知的项目。在本例中,副本 A 将发送与 I1、 I2 和 I3。
目标收到这些文件并将其添加到自己的文件夹中。副本 B 的项目现在将包含从副本 A 接收到的项目。
副本 B – 已更新项目表
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I104 | 2 | B | 1 | B |
I105 | 4 | B | 3 | B |
I2 | 3 | A | 2 | A |
I3 | 4 | A | 4 | A |
I1 | 5 | A | 1 | A |
本次同步结束后,该过程将再执行一遍,这次源将成为目标而目标成为源。这使得副本 A 能够接收到在副本 B 上创建或更改的任何文件(I104 和 I105)。
同步完成后,两个副本上都应包含以下更新知识。
副本 A 知识 = A5, B4
副本 B 知识 = A5, B4
继续前面的示例,两个副本现在已经“同步”,并且每个项目标版本如下:
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I104 | 2 | B | 1 | B |
I105 | 4 | B | 3 | B |
I2 | 3 | A | 2 | A |
I3 | 4 | A | 4 | A |
I1 | 5 | A | 1 | A |
类似地,两个副本的知识如下:
副本 A 知识 = A5, B4
副本 B 知识 = A5, B4
此时,两个副本都决定更新相同的文件(项目 I4)。
在副本 A 上,该项目标版本表更新为:
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I104 | 2 | B | 1 | B |
I105 | 4 | B | 3 | B |
I2 | 6 | A | 2 | A |
I3 | 4 | A | 4 | A |
I1 | 5 | A | 1 | A |
在副本 B 上,该项目标版本表更新为:
项目 |
更新 滴答计数 |
更新 副本 ID |
创建 滴答计数 |
创建 副本 ID |
I104 | 2 | B | 1 | B |
I105 | 4 | B | 3 | B |
I2 | 5 | B | 2 | A |
I3 | 4 | A | 4 | A |
I1 | 5 | A | 1 | A |
两个副本的知识也更新为:
副本 A 知识 = A6, B4
副本 B 知识 = A5, B5
此时,副本 A 启动与副本 B 的同步。跳过源向目标发送项目版本和知识这一步,为项目 I2 执行下列步骤。
更新 滴答计数 |
更新 副本 ID |
6 | A |
更新 滴答计数 |
更新 副本 ID |
5 | B |
如前所述,应用程序能够选择如何处理冲突或延后处理。如果冲突延后处理,则在其解决之前它将在每次同步时重复出现。一旦冲突得到解决,则下一次同步时,原始副本将接收更新后的值。
Microsoft Sync Framework 通过预创建提供程序或编写新的自定义提供程序,包含将应用程序集成到离线或基于协作网络所需的所有组件。无论采用的是哪种网络或设备类型,提供程序均使任何数据源能够参与数据同步。
在本文档中,我们已经讨论了 Microsoft Sync Framework 包含的主要组件。我们可以在文档中看到许多示例,这些示例说明了如何在 Microsoft Sync Framework 中使用知识以有效解决数据存储间交换信息的问题。最后,我们看到 Microsoft Sync Framework 启用了冲突检测,并且允许应用程序或提供程序通过各种机制有效解决冲突。
通过使用该框架,我们构建了一种同步基础,它能够扩展到任何设备上使用任何网络拓扑的任何数据存储。我们可以轻松地集成完全不同的数据源以形成对等网络,甚至在不可能进行构架更改的位置存储数据。
最终,Microsoft Sync Framework 为同步提供了一个高度嵌入式且可扩展的平台。
要了解更多信息或获取 Microsoft Sync Framework CTP1 SDK 副本,请访问 http://msdn2.microsoft.com/en-us/sync/default.aspx。