- PVSM.RU - https://www.pvsm.ru -

Двунаправленная транзакционная репликация данных

«Распределение нагрузки MSSQL на 2 сервера»

Добрый день, читатели, вот решил написать про свою историю «Распределение нагрузки MSSQL на 2 сервера методом двунаправленной транзакционной репликации данных». Да не просто 2 сервера, а что бы работали они как зеркала. Кого заинтересовало, приглашаю к чтению.
Кто хочет перейти сразу к делу [1]
Ну и конечно, же в помощь пришла репликация данных. После обзора типов репликации, пошли рассмотрения архитектуры, которая нам больше подойдет.
В нашем случае мы гнались за распределением нагрузки между 2-мя серверами. Ну и прошлись по логической цепочке «распределение нагрузки – 2 сервера зеркала – минимальные задержки — транзакционная репликация ». А так как опыта было мало совсем не было, опять отправился в msdn. А там зашел в статью, начал читать одно, прошел по парочкам пояснений к терминам и уже совсем отвлекся. В прочим как и я от главной темы…
Сначала передо мной выпал тип транзакционной репликации как «Одноранговая репликация транзакций [2]». Не знаю как многие, но я часто сначала смотрю на топологию в виде схемы, ну а потом только вчитываюсь. В этот раз, опять, попался на своей же ошибке.
image
Посмотрел вот на эту топологию, ну и понравилось она мне, что слева «чтение-запись» в оба сервера, всё красиво, нагрузка распределена. В случае падения, некоторое время, один сервер справится.
Ну и на радостях принялся настраивать, а точнее вчитываться в настройку и пробовать на тестовых базах. Сначала побывал я на страничке этой [3] и очень понравилась мне фраза «При настройке топологии активных баз данных для добавления первого и второго узлов (узел A и узел B), используется следующая процедура. Для добавления узла C и всех последующих узлов затем используется очередная процедура». В особенности эти 2 словосочетания «следующая процедура» и «очередная процедура» и далее по тексту про трехузловую одноранговую топологию.
И тут по счастливой случайности решил я вернуться на страничку с которой начал и прочитать про эту топологию и попадается опять ключевая фраза «Слева операции обновления секционируются между двумя серверами. Если база данных содержит каталог продукции, можно, например, создать пользовательское приложение, направляющее обновления названий продуктов, начинающихся с букв от «А» до «М», на узел А, а обновления продуктов, начинающихся с букв от «Н» до «Я» — на узел Б. Затем обновления реплицируются на другой узел». Так это же совсем не то что я хотел, и значит при падении сервера «А», данных будет только часть.
И опять в грусти и печали долгий сёрф по просторам ссылок, хотя решение было под носом. Натыкаюсь я на статью «Двунаправленная репликация транзакций [4]». И снова улыбка на лице, и снова руки рвутся в бой. И когда читаю настройку [5]этой репликации, спадает немного улыбка, и я понимаю, что ничего не понимаю в настройке репликации. После нескольких часов чтения, проб и ошибок, начинается проясняться ситуация. В настройке двунаправленной репликации, большая часть описана в настройке через процедуры, покажу свой способ настройки, по которому у меня работает такая топология.

Ну приступим. Советую сначала проделать это на тестовых базах. В основном буду кидать ссылки, ну и описывать «подводные камни» которые могут встретиться на пути
image

  • 1. Настройка распространения [6]. Выполнять на обоих серверах (распространитель(издатель) и подписчик). В этой части проблем особых не встретил, сервер распространения и издатель, в моем случае один и тот же. При установке папки для моментальных снимков необходимо указать локальную папку(указать ссылку на расшареную папку, к которой будет доступ для обоих серверов). Далее, так как издатель и распространитель один и тот же сервер, оставляем без изменений. И последнее это вводим пароль между распространителем и издателем (в нашем случае пароль не будем использовать дальше).
  • 2. Далее добавляем публикации и статьи (на обоих серверах). «Репликация – Локальные публикации – Создать публикацию». Выбираем базу, тип публикации «Публикация транзакций», и выбираем доступные объекты, настройку агента можно пропустить, безопасность агента заполняем.
    Камушек

    Одно из условий статьи это Primary Key в таблице.
    При создании Primary key советую проверить, чтобы не было индекса кластерного по ключевому полю, а если есть то удалить его. При создании ключа этот индекс будет создан, и если не удалить то уже будет не кластерный и будет увеличена обработка данных из за присутствия 2-х одинаковых индексов.
  • 3. На этапе создания подписок я в начале путался, но постараюсь объяснить доходчиво.
    Начнем последовательно:

    1. На сервере А:
      (1) Создаем подписку процедурой

      EXEC sp_addsubscription
      	@publication = 'А_ Base_repl_1', --Имя публикации на текущем сервере созданной на шаге 2.
      	@article = N'all', 
      	@subscriber = 'B', -- Имя сервера подписки
      	@destination_db = N'Base_repl_2', --Имя базы на сервере B
      	@sync_type = N'none',
      	@status = N'active', 
      	@update_mode = N'read only',
      	@loopback_detection = 'true'; -- параметр двунаправленной публикации.
      (2) Включаем агент

      
      	EXEC sp_addpushsubscription_agent 
      	@publication = 'А_ Base_repl_1',  -- Имя публикации на текущем сервере созданной на шаге 2.
      	@subscriber = 'B', --Имя сервера подписки A
      	@subscriber_db = N'Base_repl_2', --Имя базы на сервера подписки
      	@job_login = 'domainuser', --логин домена
      	@job_password = 'pass'; --пароль домена
      	
    2. На сервере B:
      (1) Создаем подписку процедурой

      
      	EXEC sp_addsubscription 
      	@publication = 'B_ Base_repl_2', --Имя публикации на текущем сервере созданной на шаге 2.
      	@article = N'all', 
      	@subscriber = 'A', -- Имя сервера подписки
      	@destination_db = N'Base_repl_1', --Имя базы на сервере B
      	@sync_type = N'none', 
      	@status = N'active', 
      	@update_mode = N'read only', 
      	@loopback_detection = 'true'; -- параметр двунаправленной публикации.
      (2) Включаем агент

      
      	EXEC sp_addpushsubscription_agent
      	@publication = 'B_ Base_repl_2',  -- Имя публикации на текущем сервере созданной на шаге 2.
      	@subscriber = 'A', --Имя сервера подписки A
      	@subscriber_db = N'Base_repl_1', --Имя базы на сервера подписки
      	@job_login = 'domainuser', --логин домена
      	@job_password = 'pass'; --пароль домена
      	

  • 4. Для создания хранимых процедур используемых для статей можно воспользоваться статьей [7]. Я считаю её не востребованной, так как для каждой таблицы создавать вручную по 3 процедуры (ins, upd, del) уж очень накладно. Поэтому я воспользовался следующей процедурой sp_scriptpublicationcustomprocs [8]
    На сервере А:

    
    sp_scriptpublicationcustomprocs @publication ='А_ Base_repl_1' -- Имя публикации на текущем сервере
    

    далее копируем результат процедуры и выполняем его на сервере «B» в базе «Base_repl_2»
    На сервере B:

    
    sp_scriptpublicationcustomprocs @publication ='B_ Base_repl_2' -- Имя публикации на текущем сервере
    

    далее копируем результат процедуры и выполняем его на сервере «A» в базе «Base_repl_1»

Ну вот вроде и всё. Буду рад любым советам и критике.

Автор: viper4u

Источник [9]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/sql/27699

Ссылки в тексте:

[1] Кто хочет перейти сразу к делу: #Example1

[2] «Одноранговая репликация транзакций: http://technet.microsoft.com/ru-ru/library/ms151196.aspx

[3] этой : http://msdn.microsoft.com/ru-ru/library/ms146914(v=sql.100).aspx

[4] Двунаправленная репликация транзакций: http://msdn.microsoft.com/ru-ru/library/ms151855(v=sql.90).aspx

[5] настройку : http://msdn.microsoft.com/ru-ru/library/ms147929(v=sql.105).aspx

[6] Настройка распространения: http://msdn.microsoft.com/ru-ru/library/ms151192(v=sql.105).aspx

[7] статьей: http://msdn.microsoft.com/ru-ru/library/ms147880(v=sql.100).aspx

[8] sp_scriptpublicationcustomprocs: http://msdn.microsoft.com/ru-ru/library/ms187946.aspx

[9] Источник: http://habrahabr.ru/post/170213/