Прогноз: облачно

Синхронизация между подразделениями и узлами с помощью SQL Azure

Джозеф Фулц

В период работы до перехода в Microsoft и еще несколько лет после этого я активно участвовал в разработках для сферы розничной торговли. Вся ирония в том, что за это время я увидел, насколько часто по мере технологического прогресса заново решается задача синхронизации между подразделениями и узлами (branch-node synchronization).

В нынешней должности я отдаю много времени нефтегазовой промышленности (O&G) и обнаружил, что и в этой сфере есть аналогичная проблема с синхронизацией данных между узлами. Во многом подобно розничным сетям нефтегазовые компании имеют дело с широким спектром устройств и проблем подключения. Несмотря на спутниковые соединения хоть на нефтедобывающей платформе, хоть на буровой установке, требования к своевременному получению точных данных не меняются.

Итак, с учетом розничной торговли и нефтегазовой промышленности я вновь рассматриваю ту же задачу, но на этот раз принимаю во внимание SQL Azure и Sync Framework. Мы обсудим, как облако поможет решить задачу перемещения данных между информационным центром (внутри корпорации), подразделениями (например, магазином, буровой платформой, центральной станцией и т. д.) и индивидуальными устройствами (наладонниками, общедоступными терминалами, специфическим оборудованием и др.).

Сегодня я уделю больше внимания общей архитектуре и меньше — реализации. Тем не менее я приведу несколько примеров кода для настройки синхронизации между узлами и SQL Azure и для фильтрации контента как способа уменьшения трафика и времени синхронизации. В следующей статье я рассмотрю применение подхода к синхронизации на основе сервисов, который позволяет создать масштабируемое решение для синхронизации, выходящее за рамки распределения данных по базам данных SQL Azure на основе контента или территориального размещения.

Хотя базовая задача не изменилась, появились дополнительные требования по мере развития технологий. Вместо решения простой задачи перемещения данных между узлами мы начинаем добавлять те вещи, которые было бы неплохо иметь, например увеличение объема данных для получения более детальной информации, включение различных устройств для сбора и отображения данных и получение данных в режиме, более близком к реальному времени.

Будем откровенны:чем больше мы имеем, тем большего нам хочется. Десятилетие назад в большинстве случаев решение проблем потоков данных было бы простым, но в современном мире это решение представляло бы собой лишь субстрат для более надежного решения. В рознице поток данных может быть как довольно простым, — принимая форму нисходящей передачи данных каталожного типа (меню, товары на складе и т. д.) и восходящей передачи заказов, — так и весьма сложным из-за частого обновления уровней запасов, анализа в реальном времени для предотвращения убытков и создания вручную записей по новой продукции; при этом информация передается от подразделения в центральный офис и между подразделениями. В большинстве случаев в компаниях нефтегазового сектора выявляются те же шаблоны, но с дополнительными сложностями, связанными с эксплуатацией, оценкой и настройкой используемого оборудования. Чтобы получить приблизительное представление об уровне сложности (каждый вышестоящий уровень труднее в реализации и поддержке), я рассматриваю следующие варианты синхронизации.

  1. Распространение данных только для чтения от центрального офиса в подразделение и далее.
  2. Двухстороннее распространение разных данных:один поток идет от центрального офиса в подразделение (например, каталог), а другой — в обратном направлении (например, заказы и позиции на складе); этот вариант включает обмен д��нными между подразделениями.
  3. Двухсторонняя синхронизация данных между центральным офисом и узлами (например, ввод вручную записей о продуктах или информации о сотрудниках).
  4. Одноранговая синхронизация между подразделениями и синхронизация между подразделениями и центральным офисом.

Тип 4 на сегодняшний день самый сложный и обычно ведет ко множеству конфликтов. Поэтому я стараюсь избегать этого шаблона, и лишь два критерия могут вынудить использовать его:потребность в обновлениях в реальном времени между узлами или поддержка синхронизации для подразделений в ситуации, когда корпоративное хранилище данных недоступно. Поскольку обновления в реальном или почти реальном времени между слишком большим количеством узлов, как правило, создают слишком интенсивный трафик и обычно не считаются приемлемым решением, я признаю только один критерий, а именно поддержка синхронизации без главной базы данных. В некоторых случаях необходим обмен информацией между узлами в реальном времени, но, в целом, это не относится к синхронизации данных. Это скорее ситуация, где нужны уведомления о событиях, и подобная задача решается другим способом — не синхронизацией.

Определение архитектуры решения

В целом, самый распространенный шаблон, какой я видел, — распространение данных напрямую из главной корпоративной базы данных (через дистрибутор какого-либо типа) на серверы в подразделениях и на мобильные устройства пользователей. Распространение информации на рабочие станции, терминалы в торговых точках (point-of-sale, POS) и другие подобные устройства обычно выполняется с серверов подразделения, тогда как синхронизация с мобильными устройствами (например, лэптопами) осуществляется непосредственно с сервера главной корпоративной базы данных, при этом инициатором синхронизации является клиент (рис. 1).

image: Typical Architecture for Data Distribution

Рис. 1. Типичная архитектура распространения данных

В некоторых организациях это делают через встроенные в реляционные СУБД средства репликации, а в других — создают процессы для обработки распространения и сбора данных. Я буду придерживаться этого шаблона, но вместо дистрибутора использую экземпляр SQL Azure, а вместо репликации — Sync Framework, которая поддерживает SQL Azure. Таким образом, я просто добавляю уровень между дистрибутором и подразделениями (рис. 2).

image: Base Architecture Using SQL Azure and the Sync Framework

Рис. 2. Базовая архитектура с использованием SQL Azure и Sync Framework

Что я получаю, вставляя SQL Azure? Некоторые из преимуществ в сценарии «подразделение-узел» таковы:

  1. масштабирование сервиса данных без наращивания мощностей информационного центра;
  2. высокая доступность данных без дополнительных затрат и усилий;
  3. потенциально меньшая уязвимость к проблемам в защите из-за того, что главного хранилища данных нет.

Если взять первый вариант, то в случае отсутствия соединения с центральным офисом или сбоя хранилища данных все клиенты вынуждены приостанавливать свои транзакции. Это может легко привести к потере данных из-за сбоя устройства в процессе ожидания соединения или из-за того, что на устройстве просто закончится свободное место для хранения транзакций. Кроме того, если в подразделениях есть общие данные (например, данные складского учета), они будут работать с устаревшими данными, пока не восстановится связь с центральным офисом. Хотя это не идеальное решение, SQL Azure позволяет справиться с такой ситуацией автоматическим созданием копий данных и поддержкой автоматического восстановления после сбоев. А за счет разделения потока данных по нескольким базам данных SQL Azure я могу уменьшить риск сбоя и еще больше сократить время загрузки, используя не только раздельные экземпляры, но и разные информационные центры.

Я должен учитывать влияние инициации синхронизации из подразделений или с центрального сервера. Если приложение рассчитано на синхронизацию от главной базы данных или дистрибутора до узлов, я получаю преимущество — уменьшение количества точек управления и поддержки; с другой стороны, это накладывает некоторые технические ограничения на реализацию, требуя:

  1. знания конечных точек;
  2. знания соответствующих областей для каждого целевого устройства;
  3. сложного процесса, обеспечивающего параллельную синхронизацию множества узлов (семантика API на самом деле рассчитана на одну пару конечных точек и одну область единовременно).

Запуск синхронизации с целевого устройства (например, узла или сервера подразделения) позволяет уменьшить сложность кода синхронизации, так как:

  • можно ограничиться областью (областями) для приложения/устройства;
  • проще обрабатывать периодические разрывы соединения;
  • достаточно знать и управлять несколькими конечными точками, с помощью которых синхронизируются распространяемые данные.

Однако это немного усложнит приложения на целевом устройстве и затруднит поддержку и обслуживание, так как потенциально может потребоваться отладка процесса или агента синхронизации на каждом устройстве. В идеале, если данные нужно синхронизировать для разных приложений, следует создать отдельный процесс, который управляет синхронизацией на основе конфигурационного файла, где для агента определяются область, частота синхронизации и строки подключения. Этот агент синхронизации будет существовать вне приложений, которые являются потребителями данных на устройствах, хотя процесс предоставит приложениям средства инициации синхронизации своих данных. Тем самым вы получаете преимущество запуска синхронизации с узла, но попутно уменьшаете возможности поддержки и обслуживания, так как сводите все в единый процесс.

Используя Sync Framework, я начинаю со смешанной моделью синхронизации, запуская процесс с главного хранилища данных в SQL Azure и впоследствии с узлов для синхронизации между каждым узлом и SQL Azure. Иначе говоря, данные «проталкиваются» от главной базы данных и «вытягиваются» подразделениями; при этом SQL Azure становится высокодоступным центральным концентратором между главной базой данных и подразделениями. Исходя из потребностей и ограничений решения я изучаю затраты и преимущества переноса управления процессом синхронизации из одной точки в цепочке в другую (например, с устройства в облако или с центрального сервера в облако). Некоторые из соображений можно сформулировать в виде следующих вопросов.

  • Есть ли место для хостинга процесса синхронизации для главной базы данных?
  • Существуют ли политики безопасности, конфликтующие с хостингом процесса синхронизации в SQL Azure?
  • Сколько узлов на каждом уровне подлежат синхронизации?
  • Действительно ли целевое устройство способно поддерживать процесс синхронизации?
  • Каковы требования в отношении своевременности синхронизации данных?

Более того, каждый из этих вопросов многослоен, и вы должны рассмотреть все слои, потому что какие-то из них могут наложить вето на возможное решение. Хотя единого решения на все случаи жизни нет, я предпочитаю начинать с ранее описанной модели и либо запускать множество односторонних синхронизаций для достижения примерно тех же целей, что и в случае двухсторонней синхронизации данных, либо использовать двухстороннюю синхронизацию между устройством/корпоративной базой данных и SQL Azure. После этого я ищу сценарии, где такой вариант не будет работать, и вношу изменения в проект. В целом, единственный вид синхронизации, которой я стараюсь избегать, — одноранговая (peer-to-peer).

Настройка синхронизации

Настроить синхронизацию с применением Sync Framework 2.1 можно двумя способами, разместив клиент синхронизации либо в облаке, либо на локальном компьютере. В данный момент я сосредоточусь на втором варианте. Этапы настройки отношения синхронизации (synchronization relationship) в самом простейшем случае перечислены ниже.

  1. Идентифицируйте данные, подлежащие синхронизации, и направление потока данных. Это понадобится для определения областей (scopes) (SqlSyncScopeProvisioning), используемых при синхронизации данных.
  2. Скачайте и установите Sync Framework 2.1 (bit.ly/gKQODZ). Примечание: Если целевой платформой является x64, нужно будет добавить мишень сборки для x64, а иначе SyncOrchestrator не сможет разрешать свои зависимости.
  3. Подготовьте базы данных и таблицы для синхронизации; в синхронизации можно задействовать всю базу данных, только отдельные таблицы или определенные поля.
  4. Добавьте необходимые фильтры. Фильтры могут понадобиться, если вам требуется горизонтально разделять или иным образом фильтровать данные.
  5. Создайте и запустите процесс для синхронизации.

В этом примере я предпочту больше специфики, чтобы лучше прояснить суть, и начну работу с базами данных, уже размещенными на обеих сторонах. Я создаю соединение с локальной базой данных и получаю определение синхронизируемой таблицы (DbSyncTableDescription), а затем добавляю эту таблицу в область (DbSyncScopeDescription). Кроме того, я укажу конкретные поля, но это не обязательно, если вам нужно синхронизировать таблицу целиком. Ограничение отношения синхронизации до конкретных полей — хороший способ оптимизации используемой полосы пропускания и ускорения процессов (рис. 3).

Рис. 3. Создание области синхронизации

SqlConnection azureConn = new SqlConnection(AzureConnectionString);
SqlConnection onPremiseConn = new SqlConnection(LocalConnectionString);

// List of columns to include
Collection<string> columnsToInclude = new Collection<string>();
columnsToInclude.Add("au_id");
columnsToInclude.Add("au_lname");
columnsToInclude.Add("au_fname");
columnsToInclude.Add("phone");
columnsToInclude.Add("address");
columnsToInclude.Add("city");
columnsToInclude.Add("state");
columnsToInclude.Add("zip");
columnsToInclude.Add("contact");

// Definition for authors from local DB
DbSyncTableDescription authorsDescription =
  SqlSyncDescriptionBuilder.GetDescriptionForTable("authors", 
  columnsToInclude, onPremiseConn);

// Create a scope and add tables to it
DbSyncScopeDescription authorScopeDesc = new DbSyncScopeDescription(ScopeName);

// Add the authors table to the sync scope
authorsScopeDesc.Tables.Add(authorsDescription);

Для каждой структуры, подлежащей синхронизации, понадобиться написать немного кода, чтобы получать описание; впоследствии вы должны добавить его в область синхронизации. Следующий этап — получить объект инициализации области (scope-provisioning object) и использовать его для охвата каждой базы данных, если в ней еще нет такой области (рис. 4).

Рис. 4. Инициализация области

// Create a provisioning object for "customers" and 
// apply it to the on-premises database
SqlSyncScopeProvisioning onPremScopeConfig = 
  new SqlSyncScopeProvisioning(onPremiseConn, authorsScopeDesc);
if (!(onPremScopeConfig.ScopeExists(authorsScopeDesc.ScopeName)))
{
  onPremScopeConfig.Apply():
}
// Provision the SQL Azure database from the on-premises SQL Server database
SqlSyncScopeProvisioning azureScopeConfig = 
  new SqlSyncScopeProvisioning(azureConn, authorsScopeDesc);
if (!(azureScopeConfig.ScopeExists(authorsScopeDesc.ScopeName)))
{
  azureScopeConfig.Apply();
}

Поскольку мы впервые инициализируем область синхронизации в базе данных, для хранения информации об области понадобится несколько новых таблиц, а также таблица специально для отслеживания области Authors, уже инициализированной в базах данных. Хороший пример консольного приложения для инициализации области и синхронизации локальной базы данных с SQL Azure см. в блоге группы Sync Framework по ссылке bit.ly/dCt6T0.

Боковая панель: SQL Azure Data Sync

SQL Azure Data Sync — это облачный сервис в Windows Azure, который обеспечивает синхронизацию целых баз данных или отдельных таблиц между SQL Server и SQL Azure. На конференции Microsoft Professional Developers Conference 2010 мы объявили об обновлении этого сервиса до версии CTP 2 (Community Technology Preview). Это обновление позволяет организациям легко распространять свои локальные базы данных SQL Server в облако, что дает возможность поэтапно переносить приложения в облако. Решения, использующие SQL Azure Data Sync, позволят по-прежнему обращаться к локальным данным и бесшовно синхронизировать изменения с SQL Azure по мере их внесения. Аналогично любые изменения, вносимые приложениями в SQL Azure, синхронизируются с SQL Server на предприятии.

Поддержание данных в синхронизированном состоянии

SQL Azure Data Sync предоставляет централизованную в облаке систему управления всеми отношениями в процессе синхронизации. Из любого браузера администраторы могут подключаться к этому общедоступному сервису и управлять различными конечными точками базы данных. Кроме того, в SQL Azure Data Sync имеется сервис планирования, определяющий частоту синхронизаций от каждых пяти минут до более длительного периода, чтобы синхронизация выполнялась вне времени пиковых нагрузок.

В недавней версии CTP 2 сервиса SQL Azure Data Sync мы также ввели новый компонент — SQL Azure Data Sync Agent. Этот агент является Windows-службой, которая устанавливается на предприятии и связывает локальные базы данных SQL Server с SQL Azure Data Sync по защищенному исходящему HTTPS-соединению; это позволяет отказаться от брандмауэра и специфической настройки защиты, что резко упрощает весь процесс подготовки. Задача агента — вести мониторинг и протоколировать задания, а также инициировать запросы на синхронизацию от SQL Azure Data Sync.

Новые сценарии

Благодаря SQL Azure Data Sync синхронизация между базами данных SQL Server и SQL Azure открывает множество новых сценариев применения, который в прошлом было бы крайне трудно реализовать. Представьте, что вы хотите обмениваться данными с базами данных ваших филиалов или розничных магазинов. С помощью SQL Azure Data Sync это совсем не сложно, так как администраторы создают «Sync Groups» (группы синхронизации), определяющие, какими данными следует обмениваться между базами данных. Эти Sync Groups могли бы включать корпоративную СУБД SQL Server, которая синхронизировала бы данные с централизованным SQL Azure «Data Hub» (концентратором данных). Потом из этого Data Hub все удаленные или региональные базы данных SQL Server синхронизировали бы изменения данных, что позволило бы пользователям работать с более актуальной информацией и в то же время значительно уменьшить потребляемую полосу пропускания и потребности в VPN-сетях (Virtual Private Networks).

Вдобавок возможность синхронизации с охватом нескольких информационных центров SQL Azure позволяет легко масштабировать нагрузки между территориально удаленными точками. Вообразите, что вы ежеквартально должны предоставлять отчеты, которые создают огромную циклическую нагрузку на вашу базу данных SQL Server. Почему бы не синхронизировать некоторые из этих данных с вашими базами данных SQL Azure по всему миру, когда в этом возникает необходимость? Тогда пользователи могли бы обращаться к данным, которые находятся к ним ближе всего, и это позволило бы уменьшить требования к масштабированию вашей локальной базы данных SQL Server.

За более подробной информацией и для регистрации на участие в программе использования версии CTP 2, пожалуйста, обращайтесь на страницу microsoft.com/en-us/sqlazure/datasync.aspx.

— Лиам Каванагх (Liam Cavanagh), старший менеджер программ, SQL Azure Data Sync

Синхронизация данных

Должным образом инициализировав области в базах данных, синхронизировать их достаточно легко. Это требует создания SqlSyncProvider для каждой конечной точки с указанной областью. Для этого понадобится объект SyncOrchestrator, который берет на себя идентификацию изменений и их перемещение между конечными точками. Код выглядит примерно так:

SqlConnection LocalConnection = new SqlConnection(LocalConnectionString);
SqlConnection AzureConnection = new SqlConnection(AzureConnectionString);

SqlSyncProvider LocalProvider = new SqlSyncProvider(ScopeName, LocalConnection);
SqlSyncProvider AzureProvider = new SqlSyncProvider(ScopeName, AzureConnection);

SyncOrchestrator orch= new SynOrchestrator();
orch.LocalProvider = new SqlSyncProvider(ScopeName, LocalConnection);
orch.RemoteProvider = new SqlSyncProvder(ScopeName, AzureConnection);
orch.Direction = SyncDirectionOrder.DownloadAndUpload;
orch.Synchronize();

Данные и территориальное распределение

Благодаря обработке простой репликации данных я могу сосредоточиться на оптимизации архитектуры развертывания и потоке данных. Используя Sync Framework, можно указывать фильтры; в сочетании с SQL Azure это позволяет получить по-настоящему большой выигрыш в архитектурах «подразделение-узел». При такой комбинации можно добиться большей актуальности данных для конечных пользователей и оптимизировать потребляемую полосу пропускания (а значит, и расходы), синхронизируя лишь те данные, которые имеют значение для данного региона. Вместо применения серверов данных в различных географических областях данные можно просто синхронизировать с экземпляром SQL Azure в нужной географической области, а клиенты в этой области смогут выполнять синхронизацию с этим экземпляром.

Территориально распределяя данные и реализуя области, имеющие смысл для синхронизации конкретных данных с конкретной частотой, можно добиться тонкого контроля над тем, какие данные передаются по сети, каким образом, когда и сколько; это значительно повышает доступность и актуальность данных для пользователей. Кроме того, для конечных пользователей, часто ездящих из одного подразделения в другое, агент синхронизации мог бы устанавливать текущее местонахождение и синхронизировать данные, актуальные на этой территории. Несколько примеров этого — текущая статистика или предупреждения для сотрудников, посещающих производство/рабочую среду, и продажи за текущий день для региональных менеджеров розничных сетей (см. рис. 5).

image: Synchronizing Data with Filters

Рис.5. Синхронизация данных с применением фильтров

Включение фильтрации не сложнее инициализации области синхронизации. У вас может быть несколько областей с разными фильтрами или вообще без них. От вас потребуется лишь включить две строки кода в каждый добавляемый фильтр: одна строка — для добавления поля фильтра в таблицу, а вторая — для добавления блока фильтра (filter clause), который в основном представляет собой условие «где». В своем примере я добавляю фильтр по штату и синхронизирую только изменения для штата Юта:

onPremScopeConfig.Tables["authors"].AddFilterColumn("state");
onPremScopeConfig.Tables["authors"].FilterClause = "[authors].[state] = 'UT'";

Если бы мне нужна была синхронизация в обоих направлениях на основе этого фильтра, мне пришлось бы добавить его в обе области, так как они инициализируются на каждой стороне.

Заключение

Включение SQL Azure — одного экземпляра или нескольких — может по-настоящему повысить доступность данных и общую производительность при синхронизации с узлами. Поскольку это SQL Azure, вы получаете производительность, масштабируемость и надежность без головной боли от проблем проектирования, инициализации и управления инфраструктурой. В следующей статье я расширю реализацию и покажу, как дополнительно задействовать для синхронизации возможности Windows Azure, используя новейшую версию Sync Framework 4.0 CTP, выпущенную в октябре (bit.ly/dpyMP8).

Джозеф Фулц (Joseph Fultz) — архитектор в Microsoft Technology Center в Далласе, где он работает как с корпоративными заказчиками, так и с независимыми разработчиками ПО (ISV), проектируя и создавая прототипы программных решений, отвечающих потребностям бизнеса и рынка. Выступал на различных конференциях вроде Tech·Ed, а также на внутренних мероприятиях, направленных на повышение квалификации сотрудников.

Выражаю благодарность за рецензирование статьи эксперту Дэвиду Брауну (David Browne)