Главная System Center, Без рубрики, Новое Репликация баз данных в SCCM 2012
  • Репликация баз данных в SCCM 2012

    В этой статье я хотел бы рассказать о новом механизме репликации данных, появившемся в SCCM 2012. Статья не претендует на сверхточность или супердетальность описания этого процесса. Основное внимание будет уделено именно концепции механизма репликации, хотя некоторые детали, который на мой взгляд могут быть полезны, все-таки будут приведены.
    В SystemCenter2012 ConfigurationManager появился дополнительный способ репликации данных иерархии SCCM – репликация данных с помощью механизмов SQLServer. Достаточно оправданный ход со стороны Microsoft в сторону упрощения реализации этой задачи. В процессе репликации задействуется два важных механизма: DatabaseChangeTracking и SQLServerServiceBroker. Первый появился в SQLServer  2008, второй в SQLServer 2005. Видимо из-за отсутствия DatabaseChangeTrackingв SCCM 2007 (или 2007 R2) не было репликации с помощью SQLServer (хотя может и по другим причинам).
     
     
    Основные понятия.

    Для понимания самого процесса репликации очень важно разобраться в используемых механизмах.

    • DatabaseChangeTracking – механизм, который появился в SQL Server 2008. Предназначен для отслеживания изменений в таблицах SQL Server, предоставляет функции для работы с этими изменениями. Подробнее об этой функции можно почитать здесь – http://msdn.microsoft.com/en-us/library/bb933875.aspx.
    • SQLServerServiceBroker – механизм SQL Server, входящий в компонент Database Engine. Предназначен для обмена сообщениями в распределенных приложениях. Механизм пришел на смену MSMQ (Microsoft Message Queuing) и призван упростить задачу межпроцессного обмена информацией. Подробнее о Service Broker можно прочитать здесь – http://msdn.microsoft.com/en-us/library/ms166104(v=sql.100).aspx. Позже мы еще вернемся к Service Broker.
    • Типданныхдлярепликации: global, site, local, global_proxy. Локальные данные не реплицируются, глобальные данные реплицируются на всю иерархию, данные сайта реплицируются с основного (primary) сайта на центральный (central) сайт. Global_proxy – это подмножество глобальных данных. Тип этой репликации используется только между Primary и Secondary сайтами, поэтому, например, на CAS вы не найдете соответствующий код для репликации.

     

    ServiceBroker.

    Этот сервис пришел на смену MSMQ, упростив задачу межпроцессного обмена данными. ServiceBroker
    освобождает вас от рутиной работы и многое далает за вас. Он берет на себя такую работу как авторизация, аутентификация (за счет посредников конечно), доставка данных, хранение, уникальность, очередность и т.д. И причем все эти функции доступные через весьма простые программные интерфейсы и TSQL.
    Для работы с ServiceBroker (в том числе и в SCCM) используются следующие объекты:
    • Диалог (dialog) – можно сказать что это сессия TCP, не в прямом смысле конечно, но
      похоже. То есть также есть некоторые две стороны, которые обмениваются
      сообщениями. При этом обеспечивается гарантированная доставка, подтверждение,
      очередность. Сторона установившая диалог называется инициатор (initiator), отвечающая
      сторона – target.
    • Сообщения (Message) – этими объектами просходит обмен. Сообщения могут
      быть любого типа, от бинарных данных, до «правильного» XML или даже ServiceBroker может проверять
      сообщения с помощью XML-схемы.

    Для SCCM определены ряд сообщений, такие как, DRS_SyncStart, DRS_SyncEnd, DRS_SyncData и т.д. Всего определено порядка 30 сообщений. Например, определение основного сообщения репликации данных DRS_SyncStart выглядит так:

    CREATE MESSAGE TYPE [DRS_SyncData] AUTHORIZATION

    [dbo] VALIDATION = NONE

    • Контракты (Contracts) – эти объекты определяют типы сообщений, которые
      можно послать в диалоге, а также разрешенные типы сообщений для обоих сторон диалога. Например, можно ограничить отправку определенных сообщений, которые может послать только инициатор (initiator), тип сообщений которыми может ответить target или указать что сообщение может использоваться обеими сторонами.

    Для SCCM определены контракты по приоритетам репликации: CriticalPriority, HighPriority и т.д.

    К примеру, для репликации данных с приоритетом ниже среднего определен контракт LowNormalPriority:

    CREATE CONTRACT [LowNormalPriority]
    AUTHORIZATION [dbo] ([DRS_SchemaChange] SENT BY
    ANY,
    [DRS_StartMsgBuilder] SENT BY ANY,[DRS_SyncBinaryData] SENT BY ANY,[DRS_SyncBinaryDataCompressed] SENT BY ANY,[DRS_SyncComplete] SENT BY ANY,[DRS_SyncData] SENT BY ANY,[DRS_SyncDataCompressed] SENT BY ANY,[DRS_SyncEnd] SENT BY ANY,[DRS_SyncStart] SENT BY ANY)

    • Сервисы (Services) – Диалог между участниками происходит как раз с
      использованием сервисов. У сервисов есть имена и очереди сообщений. Можно
      представить что сервисы это почтовые адреса.

    Для SCCM используются такие сервисы как, ConfigMgrDRS_Site<код_сайта> (этот для репликации глобальных данных между сайтами), ConfigMGRDRSSite_Site<код_сайта (для репликации данные
    с областью site) или, например, ConfigMgrDrsMsgBuilder (используется для запуска репликации).

    Например, определение сервиса для репликации глобальных данных (в том числе и global_proxy):

    CREATE SERVICE [ConfigMgrDRS_SiteABC]
    AUTHORIZATION [dbo]
    ON QUEUE [dbo].[ConfigMgrDRSQueue]
    ([CriticalPriority],[HighPriority],[LowNormalPriority],[LowPriority],[NormalPriority])

    • Очереди (Queues) – объекты, которые ассоциированы с некоторым сервисом. Сообщение, отправленное на целевой сервис, попадает в его очередь и ждет обработки. Процесс извлечения сообщений может происходить  вручную или с помощью хранимой процедуры, которая вешается на очередь.

    Для каждого сервиса созданы очереди. Так выглядит очередь для репликации глобальных данных сайта BCD:

    CREATE QUEUE [dbo].[ConfigMgrDRSQueue]WITH STATUS = ON , RETENTION = OFF ,
    POISON_MESSAGE_HANDLING (STATUS = ON)  ON [PRIMARY]

    А так – очередь для инициации репликации:

    CREATE QUEUE [dbo].[ConfigMgrDRSMsgBuilderQueue]

    WITH STATUS = ON , RETENTION = OFF ,
    ACTIVATION (
    STATUS = ON , PROCEDURE_NAME = [dbo].[spDRSMsgBuilderActivation] ,
    MAX_QUEUE_READERS = 5 , EXECUTE AS N’dbo’
    ),
    POISON_MESSAGE_HANDLING (STATUS = ON)  ON [PRIMARY]

    На этой очереди висит процедура spDRSMsgBuilderActivation, которая запускается если в очереди есть сообщения.

    • Маршруты (Routes).С помощью маршрутов определяется расположение целевого сервиса. Можно сравнить данный объект с типом записи SRV в DNS. Если целевой сервис на который отправляется сообщение находится на удаленной системе, то просматривается маршрут, который был создан для этого сервиса и в котором указан сетевой адрес и порт (адрес и порт ServiceBroker). Точнее сначала просматривается маршрут до целевого сервиса, а потом уже определяется что он на удаленной
      системе. Если маршрут не найден, то используется маршрут по умолчанию, который указывает на локальный экземпляр SQLServer.

    Для каждого сервиса определены маршруты. Например, для удаленного сайта создан маршрут ConfigMgrDRSRoute_SiteBCD, который указывает на удаленную систему:

    CREATE ROUTE [ConfigMgrDRSRoute_SiteBCD]
    AUTHORIZATION [dbo]
    WITH
    SERVICE_NAME  =
    N’ConfigMgrDRS_SiteBCD’ ,
    ADDRESS  =
    N’TCP://EF-CM12-02.cm12.local:4022′

    Теперь концептуально рассмотрим сам процесс обмена сообщениями в Service Broker.

    Диалог между сервисами происходит следующим образом:

    1) Приложение-инициатор начинает диалог:

    BEGIN DIALOG CONVERSATION @dialog_handle

    FROM SERVICE [ConfigMgrDRS_SiteABC]

    TO SERVICE ‘ConfigMgrDRS_SiteBCD’

    ON CONTRACT [NormalPriority]

    2) В @dialog_handle возвращается описатель этого диалога. Этот описатель используется для отправки и приема сообщений между участниками.

    3) Формируется сообщение. Способ формирования не имеет значение. Как формируются сообщения в SCCM будет описано чуть ниже.

    4) Далее, сформированное сообщение отправляется:

    SEND

    ON CONVERSATION @dialog_handle

    MESSAGE TYPE DRS_SyncData (@Message)

    5) Диалог и объекты служб (а также контракт) определяется по описателю. По маршруту определяется расположение сервисов.

    6) Сообщение отправляется целевому сервису.

    7) После приема на целевой стороне, сообщение попадает в очередь, которая привязана к сервису.

    8) Далее сообщение, вручную или с помощью ассоциированной с очередью хранимой процедурой, извлекается из очереди. Например, вот такой конструкцией:

    WAITFOR (

    RECEIVE TOP(1) @ReceivedMessageType=message_type_name,

       @ReplicationGroup=message_body,
       @ConversationHandle=conversation_handle

       FROM dbo.ConfigMgrDRSMsgBuilderQueue

                ), TIMEOUT 5000

    9) Полученное сообщение обрабатывается.
    10) Может быть отправлено ответное сообщение.
    11) Диалог завершается конструкцией ENDCONVERSATION @DialogHandle

     
    Репликация SCCM.
    Обсудив принципы работы с ServiceBroker, можно переходить к принципам функционирования репликации в SCCM.
     
    Инициатор.
    1) Например, мы изменили границы (Boundary) в нашей иерархии. Процесс проходит через SMS-провайдер,
    попадает в базу, запускается ряд дополнительных потоков, таких как DatabaseNotification Monitor, HierarchyManager и т.д. На этом этапе данные зафиксированы в БД (в нашем случае в таблице BoundaryEX). Далее.
    2) [SMS_REPLICATION_CONFIGURATION_MONITOR]: Компонент MS_REPLICATION_CONFIGURATION_MONITOR запускает каждую минуту процедуру spDRSInitiateSynchronization (можно увидеть в логе rcmctrl.log).
     
     
    3) [spDRSInitiateSynchronization]: Процедура просматривает таблицу ReplicationData и получает все группы объектов репликации, которые не реплицировались определенный интервал времени (SyncInverval*60)
    и который в данный момент не реплицируются. Для глобальных данных определен интервал в 1 минуту, для данных сайта – 5 минут.
     
     
    Объекты Boundary относятся к группе 3 (столбец ID) с типом репликации global.
    4) [spDRSInitiateSynchronization]: Для каждой группы репликации формируется сообщение типа DRS_StartMsgBuilderс телом равным наименованию группы репликации (ReplicationGroup). Сообщение отправляется сервису  ConfigMgrDRSMsgBuilder (и от сервиса ConfigMgrDRSMsgBuilder). Это локальный сервис. Отправка сообщения происходит, если репликация инициируется с сервера в Primary сайте или область репликации не равна site. То есть это проверка, что CAS не должен отсылать данные с областью site другим сайтам (Primary).
    5) [ServiceBroker]: Сообщение попадает в очередь ConfigMgrDRSMsgBuilderQueue (ассоциирована с сервисом ConfigMgrDRSMsgBuilder). На очереде висит процедура spDRSMsgBuilderActivation.
    6) [spDRSMsgBuilderActivation]: Процедура spDRSMsgBuilderActivation сканирует очередь ConfigMgrDRSMsgBuilderQueue, вытаскивает сообщения с типом DRS_StartMsgBuilder и запускает другую процедуру – spDRSSendChangesForGroup.
     
     

    7) [spDRSSendChangesForGroup]: Это основная процедура для отправки изменений. В этой процедуре происходят различные проверки, получение описателей диалогов ServiceBrokerи т.д.
    8) [spDRSSendChangesForGroup]: Определяется максимальная версия данных в базе данных. Версию можно восприниматься как некий USN(UniqueSequenceNumber), который ассоциируется с изменениями. MaxVersion = CHANGE_TRACKING_CURRENT_VERSION().
    9)      [spDRSSendChangesForGroup]: Определяются последние версии (USN) отправленные в целевой сайти (а также полученные). Эти данные извлекаются из таблицыDRS_MessageActivity иDRS_MessageActivity_Sent.
    10) [spDRSSendChangesForGroup]: Дальше происходит определение статей (таблица ArticleData), которые необходимо реплицировать. Статьи в данном случае это таблицы (нас интересует BoundaryEx). У каждой статьи есть группа репликации (в нашем случае 3). С помощью функций DatabaseChangeTracking определяется USNстатьи и, если USN статьи больше чем USN последней отправленной репликации, то статья попадает под процесс репликации.
    11) [spDRSSendChangesForGroup]: Сами данные необходимые для репликации  (измененные с момента последней удачной репликации) определяется с помощью хранимой процедуры SCCM_RDS_spGet<Имя статьи>Changes в случае если область репликации равна  site или с помощью функции SCCM_DRS.fnGet<Имя статьи>Changes в ином случае. Процедуры spGet<Имя статьи> существуют только на первичном сайте (не standalone), поскольку CAS не реплицирует данные с областью site. Последнее предложение справедливо и для вторичного сайта.
    12) [fn|spGet<имя статьи>Changes]: В этой функции (или процедуре) используется обычная конструкция TSQL  fromCHANGETABLE(CHANGES <имя таблицы>). Измененные данные возвращаются в формате XML или бинарном виде (после сериализации процедурой spDRSSerializeQuery). Бинарный вид данных используется только для области репликации site. Почему именно так – сказать не могу. Для Secondary-сайта также используются функции формата fnGet<имя статьи>ChangesSec. В этих функциях происходит фильтрация данных, реплицируемых на вторичный сайт или со вторичного сайта. Также на вторичном сайте перед формированием данных из репликации исключаются некоторые статьи (типа global_proxy) (ArticleData.OptionalFlag & 0x2 = 0x2).
    13) [spDRSSendChangesForGroup]: Далее отправляется сообщение типа DRS_StartSync сервису ConfigMgrDRS_Site<код целевого сайта> или ConfigMgrDRSSite_Site<Код целевого сайта> (из процедуры spDRSSendStartMsg). ConfigMgrDRSSite_Site<Код целевого сайта> используется для данных типа site.
    14) [spDRSSendChangesForGroup]: Если есть данные (отличные от данных типа site) для репликации, то далее изменения формируются в сообщения и отправляются с помощью процедуры spDRSSendDataMsg. Если сжатие для группы репликации (ReplicationData.Flags & 1 = 1, в моем случае везде NULL, то есть сжатие не используется) включено и размер сообщения > 2КБ, то происходит сжатие даннных с помощью функции fnCompressData.  Если сжатые данные больше чем изначальные, то сжатие не используется. Если используется сжатие, то тип сообщения DRS_SyncDataCompressed, иначе тип сообщения DRS_SyncData. Служба для отправки
    ConfigMgrDRS_Site<код-целевого-сайта>.
    Вот так выглядит сообщение DRS_SyncData:
    <DRS_SyncData BuildNumber="7711" LastSyncVersionToSource="1221127" ThisVersion="77819" SyncID="1B102B82-71B2-4051-8B2A-15C41E430354" ReplicationGroupID="3" MessageID="4D06DD9F-CBE0-4907-8139-C06955926D4B">
    <Operation Type="I" TableName="BoundaryEx" Context="">
    <row BoundaryID="8" Name="" CreatedBy="CM12\Administrator" CreatedOn="2012-11-18T20:46:20" ModifiedBy="CM12\Administrator" ModifiedOn="2012-11-18T20:46:20" BoundaryType="0" Flags="0" Value="192.168.59.0"/>
    </Operation>
    </DRS_SyncData>
    15) [spDRSSentDataMsg или spDRSSentBinaryDataMsg]: Длягрупп2 и 3 сообщениялогируютсяпроцедуройspDRSInsertSentMessage втаблицуDRSSentMessage. Можно конечно попробовать изменить текст функции fnISLogDrsMessageDataOn(в тестовой среде конечно) для изучения репликации, но Microsoft позаботился об этом и каждую минуту запускается код, который изменяет текст некоторых объектов на исходный. Если хотите посмотреть на содержимое сообщений, то лучше убрать проверку непосредственно в хранимых процедурах spDRSSentDataMsg и spDRSSentBinaryDataMsg. Также можно вставить некий код логирования в процедуры spDRSSentStartMsg и SpDRSSentEndMsg.
    16) [spDRSSendChangesForGroup]: Если есть данные сайта (sitescope) для репликации, то используется отправка бинарных данных. Этот тип данных и тип сообщения используется только для репликации данных сайта и измененные данные извлекаются с помощью процедуры SCCM_DRS.spGet<имя статьи>Changes. Отправка данных происходит в отдельной процедуре spDRSSentBinaryDataMsg.
    17) [spDRSSentBinaryDataMsg]: Отправка бинарных данных происходит по тому же принципу. Проверяется
    необходимость сжатия для группы данных и отправка сообщения DRS_SyncBinaryDataCompressed или DRS_SyncBinaryData. Теми же самыми механизмами определяется необходимость логирования данных. Сервис
    используется другой –
    ConfigMgrDRSSite_Site<код сайта>. Secondary-сайт не реплицирует данные с областью site, поэтому такой сервис отсутствует на сервере баз данных вторичного сайта. В бинарном виде сообщение не очень презентабельно, а вот после десериализации выглядит как обычная таблица:
    Это таблица Summarizer_Components.
    18)  [spDRSSendChangesForGroup]: Диалог репликации завершается вызовом процедуры spDRSSentEndMsg, в которой отправляется сообщение типа DRS_SyncEnd.
    19) [spDRSSendChangesForGroup]: Далее происходит очистка различных временных таблиц и обновление статуса репликации в таблице DRS_MessageActivity_Sent. Эта таблица постоянно используется для определения текущего статуса и для обновления статуса по ходу выполнения процесса.
     
    На другой стороне.
     
    Что же происходит на принимающей стороне?
    С принимающей стороной немного сложнее, поскольку используется в основном код CRL. Это несколько усложняет анализ.
    1)      [SMS_REPLICATION_CONFIGURATION_MONITOR]: На стороне приема для обработки используется CRLхранимая процедура – spDRSActivation, которая определена в сборке messagehandlerservice.dll (можно найти в binкаталоге SCCM). Метод для вызова процедуры– ServiceProcedure из класса Microsoft.ConfigurationManager.DataReplicationService.MessageHandlerService.
    2) [messagehandlerservice.dll]: В этой же сборке определены дополнительные классы и их методы для работы с сообщениями репликации.
    3) [messagehandlerservice.dll]: Извлекается сообщение, парсится, определяется его тип, метод кодирования. Из сообщения извлекаются данные для изменения, определяется зависимость данных и выполняется соответствующая хранимая процедура для внесения изменений в целевые таблицы. Для операции Delete вызывается процедура SCCM_DRS.spDelete<имя таблицы>. Для операций Insert или Update вызывается хранимая
    процедура
    SCCM_DRS.spUpsert<имя таблицы>.
    4) [spDRSDelete|spDRSUpsert]: В этих процедурах определены дополнительные проверки и методы обнаружения конфликтов. Обнаруженные конфликты логируются в таблицу DRSConflictInfo. Данные для изменения вносятся в целевые таблицы.
    5) [messagehandlerservice.dll]: Из дополнительных полезностей можно отметить логирование сообщений процедурой  spDRSInsertReceivedMessage. Необходимость логирования определяется все той же функцией fnIsLogDrsMessageDataOn (логируются группы 2 и 3). Сообщения на этот раз сохраняются в таблице DRSReceivedMessages.
     
    Вместо заключения.
    Вместо заключения хотелось бы перечислить ряд дополнительных методов,  с помощью которых можно  получить сведения о репликации баз данных в SCCM 2012:
    1) Область Monitoring консоли управления ConfigManager. С помощью узла DatabaseReplication(и его контекстных команд) можно получить сведения о статуе репликации, запустить диагностику.
    2) ТаблицыDRS_MessageActivity, DRS_MessageActivity_Send, DRS_MessageActivity_Receive. Эти таблицы используются в процессе репликации для отслеживания статуса, а также для внесения сведений о ресультатах репликации. В таблицах есть поле для ошибок, возникающих в ходе репликации. Расшифровку этих ошибок можно поискать в соответствующих процедурах или функциях, запускаемых во время репликации. Большую часть сведений из этих таблиц можно получить с помощью консоли управления.
    3) Процедура spDiagDRS. Эта процедура запрашивает данные с разных таблиц (в том числе и с DRS_MessageActivity*) и отображает информацию о статусе (DRS_MessageActivity*), статьях (ArticleData), группах репликации (ReplicationData) и т.д.. Также отображаются сведения о ServiceBroker.
    4) Стандартный отчет ServiceBroker. В SQLManagementStudioдоступен отчет, отображающий статистику ServiceBroker. Для запуска необходимо открыть контекстное меню папочкиService Broker (вManagement Studio) ивыбратьReports > Standard Reports > Service Broker Statistics. Данный отчет отображает различные диаграммы,
    состояние и статистику сервисов и очередей. Также отображаются базовые сведения о производительности
    Service Broker.

Комментарии

  1. […] Как проходит процесс репликации данных в SCCM2012, какие службы и процедуры в нем участвуют, неплохо написано тут. […]

  2. Продам базу почтовых ящиков по теме “Игры”.
    Количество – 1,200,000 штук.
    Дата сбора – декабрь 2014 г. Дубли удалены.
    Цена – 1$/5000 штук. Для проверки вышлю кусок базы.
    ICQ – 658548888.