Este artigo foi traduzido por máquina.

Previsão: Nublado

Sincronização de nó de ramificação com SQL Azure, parte 2: sincronização baseada em serviços

Joseph Fultz

Este artigo discute uma versão de pré-lançamento do 4. 0 Sync Framework.todas as informações estão sujeitas a alterações.

No mês passado , me concentrei na arquitetura geral e design para a sincronização corporativa bancos de dados com SQL Azure e com vários nós de destino a partir daí. Eu falei sobre como otimizar a filtragem e também usando a distribuição geográfica — ou usando as duas estratégias em conjunto — para otimizar a rede de distribuição e a coleta de dados geral.

Este mês, vou receber Azure do Windows para hospedar um serviço de sincronização e o foco na sincronização por meio de uma interface de serviço na nuvem. Isso fornecerá um meio de dimensionamento do mecanismo de sincronização para lidar com muitos mais nós de extremidade não pôde ser tratada pela sincronização direta ao banco de dados. Usarei o de 2010 de outubro a versão CTP (Community Technology Preview) do Microsoft Sync Framework 4. 0 ( bit.ly/dpyMP8 ), que é construída sobre o framework 2. 1 usado na edição de janeiro.

Um serviço de sincronização pode ser criado diretamente na parte superior da versão 2. 1 e um bom exemplo e detalhado pode ser encontrado em bit.ly/bibIdl e bit.ly/epyImQ . No entanto, com a disponibilidade do 4. 0 CTP e os elementos voltados para Internet do lançamento, faz sentido boa aproveitá-lo para o serviço de sincronização do Windows Azure. Uma quantidade razoável de código ainda precisa ser escrito para tornar uma solução funcional, mas no final, Terminaremos com um serviço de sincronização que pode ser consumido por qualquer dispositivo usando o OData.

Sincronizando em escala de Internet

Abordei algumas idéias no mês passado sobre como dimensionar a sincronização direta ao banco de dados. No entanto, em alguns — se não são muitos — casos há inúmeras razões que o problema de escala não é resolvido com tanta facilidade. Dando apenas algumas idéias superficial para coisas que não serão cobertas por usando os métodos descritos anteriormente, um pode facilmente surgir com o seguinte:

  1. Devido à relação dos dados, ele não pode facilmente ser dividido.
  2. Não há segmentação que faça sentido e qualquer divisão seria arbitrário, que provavelmente poderia levar a imprevistos pontos nas várias partições da solução.
  3. A quantidade de dados que precisam ser replicados seria de aumentar o custo além do que está sendo econômica se ele teve que existe em vários lugares.
  4. Tempos de intermitência para sincronização;Por exemplo, o final do dia de processamento de centenas ou milhares de lojas cria contenção independentemente do particionamento.

Isso obviamente não esgotar todas as possíveis razões que seriam necessário um design diferente de straight para Azure SQL para sincronização, mas é uma lista de bom o suficiente para broach o tópico e dê uma olhada em como resolver o problema. Como na maioria das coisas em ciências da computação, eu vai tentar resolver os problemas acima, inserindo uma camada de indireção. Nesse caso, será uma camada de serviço hospedada em uma função do Windows Azure Web usado como ponto de sincronização em vez de sincronização diretamente com a instância SQL Azure. Atualizei o diagrama de estado final do mês passado, adicionando um espaço reservado para o serviço de sincronização hospedado no Windows Azure, chegam a um projeto lógico, como é mostrado a Figura 1 .

Figura 1 arquitetura corporativa típica

Introdução

O Sync Framework 4. 0 é particularmente adequado para ajudar a resolver esse problema. No entanto, ela exigirá que posso fazer um pouco mais trabalhoso do que o modelo simple de sincronizar diretamente entre bancos de dados. O CTP 4. 0 é fornecido com um bom exemplo e detalhado no arquivo de Ajuda, é intitulado "Criando um serviço de sincronização no Windows Azure". Utilizarei como base para discutir a implementação do serviço de sincronização. O código do cliente é um pouco mais difícil porque na versão 4. 0 não uma biblioteca de tempo de execução de cliente para ajudá-lo, devido à abstração criada para abrir a sincronização de qualquer plataforma que funcionarão com OData. No entanto, há uma amostra nos exemplos 4. 0 para Windows Mobile 6. 5 usando o SQL Server CE. Eu já co-opted o código necessário e modificada para funcionar com o padrão do SQL Server. Para começar, de outubro de 2010 4. 0 CTP usa um determinado conjunto de objetos para desempenhar a atividade de sincronização e ajuda a estar familiarizado com eles. O aplicativo cliente consome um CacheController, que é responsável pela comunicação com o serviço de sincronização usando OData. No lado do local, o CacheController usa um OfflineSyncProvider, que é o armazenamento-específicos de dados — e provavelmente por--plataforma de destino — interface entre o aplicativo e os dados (consulte a Figura 2 ). Nessa implementação, sendo com base na amostra, há um objeto de StorageHandler usado para controlar o acesso de dados local. O OfflineSyncProvider é um tipo conhecido que é usado pelo CacheController, mas o StorageHandler é o código personalizado para manipular a interação da armazenamento de back-end. Considere o OfflineSyncProvider como a inteligência de biblioteca de acesso a dados e o StorageHandler como a biblioteca de acesso a dados. Notavelmente, 4. 0 CTP apenas acompanha um CacheController interno para o armazenamento isolado em um cliente do Silverlight, que deixa-me com algum trabalho a fazer para usar o padrão do SQL Server. O layout dos objetos e os limites de interação são representados em um nível alto na a Figura 2 .

Figura 2 objetos de sincronização do cliente do Sync Framework 4. 0

Desenvolvendo o serviço de sincronização de nuvem

Sempre me contou para oferecer a má notícia último primeiro e a boa notícia. Dessa forma, a conversação — e espera-se a Bebidas daqueles participando ele — termina em uma nota positiva. No entanto, nesse caso, eu vou para inverter a ordem de entrega, na esperança de vender a solução nos méritos da parte fácil. A maior parte do trabalho vem no lado do cliente, mas o framework fornece muita assistência para o lado do servidor. Em uma sessão de design que posso levar, eu foi disse uma vez por alguém que venderam morte-care services (funerais, plotagens, coffins e assim por diante) que eles nunca faria uma única venda se eles concentrada em "o que é" e que em vez disso, o foco precisava ser sobre"o que ele faz";no caso de cuidado de morte, paz de espírito era a mercadoria real comprou, não um caixão e o orifício na ponta a ponta. É o caso com o Sync Framework. O 2. 1 do Sync Framework cuidou de muitas coisas para o desenvolvedor, mas não ele alcançou um pouco objetivo quando chegou à sincronização baseada em serviços. Ele sequer não abordou a grande quantidade de dispositivos e plataformas que podem sincronizar com os dados que são disponibilizados por meio de um serviço de sincronização com a Internet. Com o — agora popularmente chamados — consumo de IT, Meus clientes estão tendo que lidar com muitos dispositivos nas mãos de pessoas em todos os níveis da empresa mais. Sync Framework 4. 0 CTP é destinado a ajudar com esse tipo de desafio, particularmente em relação à sincronização de dados para esses dispositivos.

Colocar o lado servidor desta solução em indo são bem simple. Basicamente, ele atende a essas etapas:

  1. Definir o banco de dados.
  2. Criar um arquivo de configuração para ele
  3. Use o SyncServiceUtil para provisionar o banco de dados usando o arquivo de config
  4. Use o SyncServiceUtil para gerar classes necessárias para o serviço de sincronização
  5. Criar uma função baseada em Windows Azure da Web para hospedar o serviço
  6. implantar

Se você for como eu ao ler neste resumo, você pensa, "o arquivo de configuração"? O esquema do arquivo pode ser encontrado na biblioteca MSDN em bit.ly/h2FJod . Usando o que e referenciando o banco de dados de ListDB e o arquivo de configuração relacionados para ela que acompanha as amostras de 4. 0, um pode criar um arquivo de configuração personalizado que representa um banco de dados com o mínimo de confusão. Depois que esse arquivo existe, a criação dos serviços baseados em Windows Azure é um snap. Primeiro, o banco de dados de destino — nesse caso o ListDB de exemplo no 4. 0 SDK — precisa ser criado no Windows Azure. Depois disso, o novo SyncServiceUtil pode ser usado para configurar o banco de dados usando um comando semelhante a:

SyncSvcUtil /mode:provision 
/scopeconfig:listdbconfig.xml

A única coisa que terá que ser definida no arquivo de configuração é a conexão ao banco de dados SQL Azure. No final do arquivo config arquivo é o <TargetDatabase/>elemento, que precisará ser configurado corretamente para a nuvem:

<Databases>
  <TargetDatabase Name="listdb" DbServer="[URI for the SQL Azure DB 
   Instance]" DbName="listdb" UserName="[username]" Password="[password]" 
   UseIntegratedAuth="false" /> 
</Databases>

Executando o utilitário gera dois arquivos: DefaultScopeEntities.cs e DefaultScopeSyncServices.svc. A parte "defaultscope" do nome vem do arquivo de configuração e é encontrada no elemento <SyncScope/>:

<SyncScope Name="DefaultScope" IsTemplateScope="true">

O arquivo de entidades é bastante quanto descrito, mas o arquivo DefaultScopeSyncServices.svc é um pouco mais significativo conforme ele gera a classe parcial que me permite interceptar chamadas de serviço e adicionar lógica personalizada (algo de novo para 4. 0). A lógica de sincronização de base é tudo incluída como parte do objeto base. Figura 3 mostra a classe DefaultScopeSyncService e a classe de entidades relacionadas como o tipo de modelo para a classe de modelo SyncService.

Figura 3 código gerado pelo modo de exibição do objeto de navegador de SyncServices

Observe, no lado direito da a Figura 3 , a lista abreviada de interfaces de serviços que são expostos para fazer a sincronização (em comparação com a que precisaria ser expostos diretamente usando o Sync Framework 2. 1). Se eu quisesse adicionar qualquer lógica personalizada para o processo de sincronização, eu poderia simplesmente abrir o arquivo DefaultScopeSyncServices.svc, escolha o método interceptador e grave minha vontade. Para implementar a sincronização básica por meio da interface de serviço que acabou de criar, eu simplesmente precise associar o projeto de serviço/Web que contém os arquivos com uma função de Web e no método WebRole:OnStart, adicione uma linha para criar o contexto de ativação:

public override bool OnStart()
{
  DiagnosticMonitor.Start("DiagnosticsConnectionString");

  // For information on handling
  // configuration changes, see the MSDN topic at 
  // go.microsoft.com/fwlink/?LinkId=166357
  RoleEnvironment.Changing += RoleEnvironmentChanging;
  Microsoft.Samples.Synchronization.ActivationContext.
CreateActivationContext();
  return base.OnStart();
}

Em seguida, fazer algumas alterações de configuração para garantir que os binários do Sync Framework estiver definidos como CopyAlways. Para obter o novo serviço interface é muito bom, posso garantir que o Microsoft.Synchronization.dll 4. 0 é referenciado e definida para ser publicada com o pacote. Em seguida, eu publicá-lo à minha função de Web e estou pronto para ir. Posso fazer um teste simples solicitando os escopos de sincronização estão disponíveis no momento, digitando uma solicitação como jofultz.cloudapp. net/defaultscopeSyncService.svc/$syncscopes no meu navegador. Posso voltar a seguinte resposta, o que me dá alguma certeza de que o serviço está funcionando:

- <service xml:base="http://rd00155d3a1a55:20000/defaultscopesyncservice.svc/" 
xmlns:atom="http://www.w3.org/2005/Atom" xmlns="http://www.w3.org/2007/app">
- <workspace>
  <atom:title>SyncScopes</atom:title> 
- <collection href="defaultscope">
  <atom:title>defaultscope</atom:title> 
  </collection>
  </workspace>
  </service>

Também pode solicitar o outros dados, e se houver alterações, abordarei-los como OData por padrão. Pode fazer isso em um navegador ou por meio de uma ferramenta. Usando a ferramenta de Visualizador de OData no CodePlex ( dataservicestool.codeplex.com/releases/view/52805 ), emito a solicitação para fazer o download de alterações: jofultz.cloudapp. net/defaultscopeSyncService.svc/DefaultScope/DownloadChanges?userid=BA9152CC-4280-4DAC-B32D-1782E2E8C3D3, que fornece os resultados conforme mostrado na a Figura 4 .

Figura 4 Resultado do Visualizador de OData ferramenta DownloadChanges

A boa notícia é que as adições no Sync Framework 4. 0 CTP fornecem as interfaces de sincronização simplificada com resultados possam ser recuperados em um ÁTOMO de OData e OData JSON. Isso abre a sincronização para outras plataformas do ponto de vista do cliente e relegates os formatos de dados proprietários para sendo formatos herdados — e tudo o que precisava fazer era executar um utilitário, configurar um projeto e adicionar uma linha de código.

Implementação de sincronização do cliente

Aqui está o ponto na implementação de onde os fones de ouvido vá e multitarefa fornece a maneira de foco. O serviço de nuvem foi quase uma questão de configuração, mas a parte cliente leva um pouco mais trabalhoso se você estiver começando do zero. Porque o CTP do Sync Framework 4. 0 é fornecido com um CacheController para o armazenamento isolado, se o Silverlight é a plataforma de cliente de destino, a implementação de cliente será tão fácil quanto a implementação de serviços de nuvem. No entanto, meu objetivo é um cliente Windows executando o SQL Server Standard/Express, e que exigirá algum esforço. A SyncServiceUtil ainda auxilia gerando as entidades necessárias, mas um personalizado CacheController e OfflineSyncProvider terá que ser criado. Mais importante, o armazenamento de dados precisarão ser modificados para facilitar o controle de alterações. Uma possível fazer isso com um banco de dados do versão 2. 1-provisionados ou seu próprio esquema personalizado para o controle de alterações. Tal implementação foi possível adicionar um trabalho significativo e a complexidade do aplicativo geral em termos de uma implementação mais complicada do banco de dados e uma base de código mais complicado. No entanto, ele precisa ser feito a fim de aproveitar o restante do framework. Em descrevendo isso para outras pessoas, obter perguntei, "por que não fazê-lo apenas todos os você mesmo?" A resposta é simples: devo fazer dessa maneira para reduzir o corpo do trabalho e abra a implementação para sincronização por outros 2. 1 e 4. 0 framework sync clientes/agentes (inclusive plataformas não Windows).

Dê uma olhada a segmentação de trabalho mostrada no a Figura 5 para que apenas os cliente e serviço partes sendo discutidas. Você pode ver que usando a estrutura reduz a quantidade de trabalho em cerca de 60% ou mais, dependendo da plataforma de cliente de destino.

Figura 5 segmentação de trabalho para o cliente e serviço

Unidade de trabalho Esforço
Esquema de banco de dados para sincronização (servidor) Configuração
Implementação de serviço Gerado + 1 linha de código
Personalizar ganchos de validação em sincronia Ganchos gerados;Só é preciso escrever um código de valor agregado
Esquema de banco de dados para sincronização (cliente) Poderia usar o provisionamento 2. 1 ou personalizado
Implementação de sincronização para o Silverlight não Personalizar
Cliente de sincronização para o Silverlight. Configuração + geração

Trabalhando com o SQL CE e Mobile 6. 5 exemplo fornece-me com um exemplo de implementação do que você pode fazer com o banco de dados para implementar a sincronização do cliente;Observe os campos IsDirty, IsTombstone e metadados, como visto na a Figura 6 .

Figura 6 colunas para implementação de sincronização do suporte personalizado

Com um esquema no lugar, preciso de uma série de outras coisas:

  1. Implementação de CacheController, conforme mencionado anteriormente
    1. Interação com o armazenamento local
    2. Interação de serviço
    3. Manipulador de conflito de sincronização
    4. Manipulador de erro de sincronização
  2. Alguns códigos para gerar e consumir o OData
  3. Definição de código para as entidades que estão sendo sincronizados
  4. OfflineSyncProvider para o banco de dados do SQL Server local

Para os itens 1 e 2, posso usar o código fornecido no exemplo 6. 5 (consulte a Figura 7 ) e o coloca no meu próprio projeto CacheController, que consiste inteiramente emprestado do exemplo de código.

Figura 7 arquivos usados do exemplo 6. 5

Posso usar o SyncServiceUtil para gerar as entidades usando o mesmo arquivo de configuração como antes, junto com o "/ codegen: modo" e "/ destino: cliente" sinalizadores. Isso gera um arquivo de DefaultScopeEntities.cs que tem objetos my do cliente. Porque eu estou roubo do exemplo 6. 5, eu copio Settings, utility.cs, SqlCeOfflineSyncProvider.cs, DataStoreHelper.cs e SqlCeStorageHandler.cs para o meu projeto Windows Forms. Para minimizar o esforço de codificação, posso fazer as alterações mostradas na a Figura 8 .

Figura 8 as alterações feitas para minimizar o esforço de codificação do código de exemplo

Arquivo / projeto Alterar
DefaultScopeEntities.cs Renomeie a classe para SqlCeOfflineEntity para corresponder ao nome do tipo esperado nos arquivos emprestados
 

Adicione

[Microsoft.Samples.Synchronization.ClientServices.KeyAttribute]

em cada Coloque onde

[System.ComponentModel.DataAnnotations.KeyAttribute()]

existe como ele é usado na implementação de CacheController

Meu novo projeto de CacheController

Substituir todos os namespaces com

namespace Microsoft.Samples.Synchronization.ClientServices.Custom

SqlCeOfflineSyncProvider.cs

Substituir

usando o Microsoft.Samples.Synchronization.ClientServices;

com

usando o Microsoft.Samples.Synchronization.ClientServices.Custom;

Para fazer referência a minha implementação personalizada do CacheController

SqlCeStorageHandler.cs Comente todo [connection].[transação commands] do arquivo: trabalhar contra o SQL Server requer um pouco de implementação diferente que SQL CE, e isso precisa ser adicionado back corretamente para uma implementação real
DataStoreHelper.cs Alterar a seqüência de conexão para apontar para a instância local do SQL Server
Settings.cs Atribuir o URI de SyncServiceUrl para o meu serviço de sincronização de Azure do Windows (http://jofultz.cloudapp. net/DefaultScopeSyncService.svc/)
Utility.cs

Substituir

usando o Microsoft.Samples.Synchronization.ClientServices;

com

usando o Microsoft.Samples.Synchronization.ClientServices.Custom;

Para fazer referência a minha implementação personalizada do CacheController

Aproveitando o código de exemplo e fazer essas alterações, eu sou capaz de escrever um aplicativo de console do small que chamará a função de Utility.Sync, que por sua vez instancia o OfflineSyncProvider e CacheController para executar a sincronização:

var localProvider = new   
  SqlCeOfflineSyncProvider();
var controller = new CacheController(new 
  Uri(Settings.SyncServiceUrl), Settings.
SyncScope, localProvider);

Assim, uma poderia perguntar: onde tem o código para fazer coisas como busca registros alterados de armazenamento local? Todos que mora na implementação de StorageHandler. Dar uma olhada em a Figura 9 para ver uma parte dela.

Figura 9 comandos de dados de armazenamento Local

internal class SqlCeStorageHandler : IDisposable
  {
    #region SQL CE Commands

    private const string GET_ALL_PRIORITY = "SELECT [ID], [Name], [_
      MetadataID] FROM [Priority] WHERE [IsTombstone] = 0";

    private const string GET_ALL_STATUS = "SELECT [ID], [Name], [_
      MetadataID] FROM [Status] WHERE [IsTombstone] = 0";

    private const string GET_ALL_TAGS = "SELECT [ID], [Name], [_
      MetadataID] FROM [Tag] WHERE [IsTombstone] = 0";

    private const string GET_ALL_LISTS =
      "SELECT [ID], [Name], [Description], [UserID], [CreatedDate], 
      [IsTombstone], [_MetadataID] FROM [List] WHERE [IsTombstone] = 0";

    private const string GET_ALL_ITEMS =
      "SELECT ID, ListID, UserID, Name, Description, Priority, Status, 
      StartDate, EndDate, IsTombstone, [_MetadataID] FROM [Item] WHERE 
      [IsTombstone]=0 AND [ListID]=@ListID";

    private const string SELECT_ITEM_CHANGES =
      "SELECT ID, ListID, UserID, Name, Description, Priority, Status, 
      StartDate, EndDate, IsTombstone, [_MetadataID] FROM [Item] WHERE 
      IsDirty = 1";

    private const string SELECT_LIST_CHANGES =
      "SELECT ID, Name, Description, UserID, CreatedDate, IsTombstone, 
      [_MetadataID] FROM [List] WHERE IsDirty = 1";

    private const string SELECT_TAGITEMMAPPING_CHANGES =
      "SELECT TagID, ItemID, UserID, IsTombstone, [_MetadataID] FROM 
      [TagItemMapping] WHERE IsDirty = 1";

Assim, a cadeia direta de operações funciona da seguinte maneira:

  1. Aplicativo cliente chama a função de sincronização arbitrário
  2. Função de sincronização
    1. Cria uma instância de OfflineSyncProvider
    2. Cria uma instância de CacheController (esse é personalizado), passando o URI de serviço e o OfflineSyncProvider
    3. Finalmente, chama CacheController.Refresh()
  3. CacheController cria um CacheRequestHandler que manipulará a comunicação com o serviço de sincronização no Windows Azure
  4. CachController pede a OfflineSyncProvider o conjunto de alterações local
  5. O OfflineSyncProvider usa o StorageHandler para recuperar as alterações do SQL Server local
  6. CacheController usa o conjunto de alterações para criar uma solicitação e passá-lo para o CacheRequestHandler
  7. O CacheRequestHandler usa o formatador apropriado (OData ATOM aqui) para criar uma solicitação adequada e a envia para o URI do serviço de sincronização

Obviamente, tudo a descompactação e obter os dados de volta para o cliente praticamente da mesma é coisas em ordem inversa. Figura 4 mostra o pacote OData conforme ela flui volta do serviço.

Considerações finais

Obviamente, removendo o suporte a transações e mantendo misnomers como SqlCe [sufixo] para objetos não é a melhor opção para qualquer implementação real, mas ela serviu seu propósito aqui para obter uma versão de cliente trabalhando sem escrever código novo. Qualquer pessoa que desejam criar um CacheController de servidor SQL facilmente poderia começar com a amostra de 6. 5 e refatorar e renomear, com o trabalho principal que vem nos comandos dentro do StorageHandler que teria que ser específica para seus dados de armazenamento.

Meu principal objetivo foi demonstrar uma arquitetura baseada em serviços de sincronização. Eu propositadamente inativos em cache e outras otimizações que precisa acontecer para que ele seja dimensionado, mas que normalmente é bem compreendida. Além disso, eu queria transmitir o que está lá, o que não é e o que é possível ao familiarizar o leitor com o CTP do Sync Framework 4. 0. Espero que fiz essas coisas.

Com o SQL Azure dados sincronização CTP 2 em andamento, há a promessa de poder definir todos esse up — incluindo a parte do cliente — por meio da configuração e o download de um agente do cliente. É claro que seria para computadores baseados no Windows, mas se o objetivo era chegar a um conjunto mais amplo de plataformas, usando o Sync Framework 4. 0 diretamente pode ser a melhor opção.

Quero encorajá-lo e baixar o Sync Framework SDK mais recente e pelo menos siga o tutorial para configurar o serviço de sincronização no Windows Azure usando um banco de dados SQL Azure e siga o exemplo para o cliente do Silverlight ter uma idéia. Para aqueles que são um pouco mais valente, pegue os arquivos conforme descrito a partir do Windows Mobile 6. 5 exemplo na versão 4. 0 CTP (existem dois projetos) e usá-los para criar seu próprio cliente de sincronização baseado em Windows.

Joseph Fultz é arquiteto do Microsoft Technology Center em Dallas, onde trabalha com clientes empresariais e ISVs desenvolvendo e criando protótipos de soluções de software que atendam a demandas dos negócios e do mercado. Ele fez palestras em eventos como o Tech Ed e eventos de treinamento interno semelhantes.

Graças ao especialista técnico seguinte pela revisão deste artigo: Ganeshan Iyer