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

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

Отказоустойчивость в MS SQL


Для начала вкратце рассмотрим существующие технологии высокой доступности баз данных Microsoft. Одним из решений по отказоустойчивости является использование Windows Server Failover Cluster (WSFC). Рассмотрим его на примере:



WSFC использует общее сетевое хранилище (SAN). При установке SQL в отказоустойчивом кластере на общем хранилище размещаются системные и пользовательские базы данных. На приведенной схеме два узла (SQLCLU01NODE01 и SQLCLU01NODE02) объединены в отказоустойчивый кластер SQLCLUSTER01A. При этом SQL установлен именованным экземпляром (instance), т.е. кластеризованный адрес подключения SQL-сервера выглядит так SQLCLUSTER01A\SQL. При штатной работе один из узлов кластера (сервер) является активным (в примере — SQLCLU01NODE01), а второй находится в горячем резерве. Когда происходит отказ активного сервера SQLCLU01NODE01, служба кластеров осуществляет переключение (прозрачное для пользователей) на резервный узел SQLCLU01NODE01.

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

Решение давно существует (по-моему, начиная с Windows Server 2000 и SQL Server 2000) и не должно вызывать сложностей при развертывании.

С выходом SQL2005SP1 появилась возможность зеркалирования (mirroring) баз данных. Основной принцип зеркалирования — создание горячей резервной копии базы данных на другом сервере (хранилище).



На основном сервере (Primary) располагается база данных (principal database), с которой в обычном режиме работают пользователи.
На резервном сервере (Mirror) располагается зеркальная копия базы данных (mirror database).

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

Преимущества зеркалирования: обеспечение отказоустойчивости дисковых массивов, возможность использования ресурсов резервного сервера, возможность создания географически распределенного кластера. Недостатки: высокая стоимость решения (необходим резервный сервер с дисковой подсистемой, а также следящий сервер).

Необходимо отметить, что подключение к зеркальной базе данных клиентским приложением, не получится в связи с тем, что эта база всегда находится в режиме восстановления. В этом случае можно использовать снимок (snapshot) зеркальной базы. Об этой и о других технологиях Microsoft можно прочитать, например, тут

Новые возможности MS SQL 2012


Помимо всего вышеописанного в SQL 2012 появилась новая функциональность — группы доступности AlwaysOn. Что нам пишет Microsoft:
Availability Groups is an enterprise-level high-availability and disaster recovery solution introduced in SQL Server 2012 to enable you to maximize availability for one or more user databases.

Интересно… Т.е. нам предоставляют новую технологию высокой доступности уровня предприятия и она, скорее всего, должна быть круче чем то, что уже есть.

Попробуем разобраться в особенностях. На первый взгляд группы доступности AlwaysOn – это развитие зеркалирования. В сети есть много инструкций по развертыванию и настройке AlwaysOn, поэтому я расскажу только о сути. Чтобы развернуть AlwaysOn, необходим отказоустойчивый кластер WSFC. Для включения поддержки AlwaysOn необходимо установить MS SQL на экземпляр отказоустойчивого кластера и в свойствах службы SQL (оснастка SQL Server Configuration Manager) включить высокий уровень доступности AlwaysOn. Естественно, что это необходимо сделать на всех серверах, которые планируем задействовать для AlwaysOn.

На следующем рисунке представлен кластер WSFC с узлами Node01-Node05. На каждом узле установлен экземпляр SQL сервера с поддержкой AlwaysOn. В рамках SQL-серверов создана группа доступности MyAg с максимально возможным количеством реплик (рабочая база – Primary Replica и 4-е копии – Secondary Replica).



Группа доступности — это совокупность реплик доступности, их режимы работы, совокупность баз данных и слушатель группы (listener). На рисунке ниже показан вид утилиты MS SQL Management Studio с группой доступности.



Тут мы видим подключение к экземпляру SQL-сервера с именем ARSHAD-PC. На этом сервере создана группа доступности AlwaysOnDemo-AG, в которую добавлены две реплики (сервера, на которых располагаются реплики) ARSHAD-PC и ARSHAD-LP. Причем, в данный момент, основная реплика группы доступности расположена на сервере ARSHAD-PC и с этого же сервера происходит управление данной группой. Так же в группу доступности включены две базы данных AdventureWorks и AdventureWorksDW. У данной группы доступности есть слушатель (listener) с именем AlwaysOnDemo-L. По сути это отказоустойчивый адрес подключения к виртуальному серверу группы доступности.

Групп доступности может быть создано неограниченное количество, и баз данных в одной группе может быть много. Создание группы сопровождается простым и понятным мастером и не должно вызвать особых проблем. Стоит обратить внимание на две особенности.
При добавлении базы текущего сервера в группу доступности необходимо прежде сделать архив этой базы (модель восстановления должна быть Полная). Для создания слушателя при создании группы доступности потребуются полномочия администратора домена.
А при добавлении баз данных в существующую группу доступности достаточно будет полномочий админа SQL сервера.

Необходимо еще упомянуть о том, что вся остальная «обвязка» (пользователи, планы обслуживания, задания агента и т.д.), которая не входит в группу доступности, остается локальной для сервера. О синхронизации между серверами и согласовании между собой этой «обвязки» следует позаботиться самостоятельно.

Преимущества и недостатки у AlwaysOn в основном такие же как у зеркалирования, но есть и особенности. Как я понял, основные отличия AlwaysOn от mirroring – возможность создания реплик read-only, возможность создания более одной копии, простота настройки, большая гибкость, отсутствие Whitness-сервера (вместо этого listener в группе доступности).

По причине наличия некоторого опыта с 1С возникло желание проверить работу AlwaysOn совместно с 1С: Предприятие. Тем более что при построении WSFC для 1С не должно возникнуть каких-либо проблем или особенностей. По сути, AlwaysOn должен обеспечить отказоустойчивость выше, чем WSFC (если использовать разные хранилища), при этом появится возможность разгрузить основную базу от пользователей отчетов (реплика ReadOnly) и еще мы сможем распределить нагрузку по серверам путем создания нескольких рабочих групп.

Работа 1С: Предприятие и MS SQL 2012


Платформа 1С: Предприятие, начиная с версии 8.2.17, официально поддерживает работу с MSSQL 2012 (до этого необходимо было переносить с SQL2008 хранимую процедуру sp_dboption).

В связи с появлением AlwaysOn в SQL дополнился синтаксис строки подключения ODBC, появились параметры: ApplicationIntent — позволяет определить тип рабочей нагрузки (ReadOnly / ReadWrite), MultiSubnetFailover — ускоренное обнаружение активного сервера и др. Эти новые возможности 1С не поддерживает. Есть выход — указывать при подключении к рабочей базе адрес listener-а, а к базе данных в режиме чтения подключаться напрямую к серверу реплики ReadOnly (более подробно см. в эксперименте).

Работа с базой на чтение. Как известно, при работе с 1С, даже если пользователь не собирается ничего изменять в базе, существуют алгоритмы, которые пытаются вызвать insert-ы и update-ы в базе данных. Самый простой способ — переписать конфигурацию 1С, в которой убрать (закомментировать) части кода, приводящие к изменениям. Если этого не сделать, то пользователь не сможет работать с базой ReadOnly — 1С будет отваливаться с ошибкой о невозможности изменить базу данных. Ниже приведены примеры для типовых конфигураций.
  • Регламентные задания, очевидно для базы ReadOnly их нужно отключить
  • Обработка «Панель функций», при открытии всегда пытается установить значение параметра «ОткрыватьПриЗапускеПанельФункций» регистра сведений «НастройкиПользователей» в значение «Истина». Пути обхода — отключить настройку «ОткрыватьПриЗапускеПанельФункций» для пользователей, закомментировать код или добавить специальную роль ReadOnly, а код выполнять, если роль другая
  • Обработка «Панель функций», при закрытии записывает значение параметра «ТекущаяСтраницаПанелиФункций» регистра сведений «НастройкиПользователей». Пути обхода — отключить настройку «ОткрыватьПриЗапускеПанельФункций» для пользователя, добавить специальную роль ReadOnly, а код выполнять, если роль другая
  • Интернет поддержка пользователей (общая форма «ИнтернетПоддержкаПользователейОшибкаДоступаКИнтернету»). При старте конфигурации 1С предлагает соединиться с сервером 1С и при наличии соединения устанавливает настройку в хранилище общих настроек. Пути обхода – сбросить настройки автоподключения к интернет-поддержке путем создания внешней обработки со следующим кодом кнопки:
  • При закрытии отчета (например, оборотно-сальдовая ведомость) происходит запись настроек отчета в справочник «СохраненныеНастройки». Пути обхода: добавить специальную роль ReadOnly и в процедуре СохранитьНастройку общего модуля СтандартныеОтчеты вставить проверку сохраниеня настроек, если роль другая

Эксперимент


Итак, сам эксперимент. Ранее мы договорились, что будем исследовать AlwaysOn SQL 2012 применительно к 1С. Для начала опишу конфигурацию серверов.

В нашем распоряжении 4-е сервера: один сервер приложения 1С и три сервера SQL в кластере.



Эксперимент будем проводить в два этапа. На первом этапе опробуем возможность работы информационной базы 1С с использованием AlwaysOn SQL 2012 и проверим отработку отказа. На втором этапе исследуем работу реплики ReadOnly. Для простоты ограничимся двумя базами данных.

В качестве информационной базы 1С возьмем типовую кофигурацию «1С: Бухгалтерия предприятия». Проведем подготовительную работу и выполним настройку серверов, групп доступности и баз данных. Итак, создаем на сервере ServerSQL2 базу данных Dbtest2, затем на этом же сервере создаем группу доступности AG_test2, куда помещаем эту же базу:



Аналогично поступаем с базой данных Dbtest1 на сервере ServerSQL1. Теперь на сервере приложений «Server1C» регистрируем две информационные базы:





Ну и приступем к самому эксперименту, подключившись с клиентского компьютера с помощью 1С: Передприятия к обеим информационным базам. Запустим в обоих сеансах 1С: Предприятие формирование какого-либо долгоиграющего отчета, и не дожидаясь заверешния его формирования промоделируем отказ сервера в группе доступности AGtest2:



И тут же получаем ошибку в информационной базе, которая размещена в группе доступности, где моделировали отказ:



Подключение к другой информационной базе (по понятным причинам) остается работающим. Перезапускаем на клиенте приложение 1С «аварийной» информационной базы, программа работает корректно. При этом в SQL Management Studio можем наблюдать, что теперь основоной репликой в этой группе доступности становится сервер ServerSQL1.ё

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

Теперь попробуем работу с базой ReadOnly. Для того, чтобы подключиться из 1С к такой базе необходимо сделать две вещи: доработать конфигурацию 1С таким образим, чтобы из нее не выполнялась запись в базу данных во время работы, и настроить подключение информационной базы.

Примеры доработки конфигурации 1С приведены выше. Что касается подключения к базе SQL, то тут все гораздо проще. Т.к. платформа 1С: Предприятие не поддерживает новый синтаксис строки подключения к MSSQL 2012, пропишем подключение к базе данных в режиме ReadOnly напрямую:



Так же необходимо указать возможность подключения к ReadOnly реплике для всех клиентов. Для этого в SQL Management Studio открываем свойства группы доступности и для реплики меняем свойство «Вторичная реплика для чтения» со значения «Только для чтения» на «Да»:



После этого подключаемся с клиентского компьютера приложением 1С: Предприятие к информационной базе ReadOnly. Подключение происходит без проблем, отчеты формирируются. Но при попытке, что-либо изменить, SQL возвращает ошибку о невозможности изменений и сеанс 1С закрывается.

Дополнительно отмечу, что в больших базах абсолютно точно можно выделить значительную категорию пользователей для работы с отчетами (как раз этот случай). Выделив под них отдельные сервера (1С и SQL), можно распределить нагрузку по аппаратным ресурсам. Это работает.

Обновление информации в базе ReadOnly происходит «практически мгновенно». Только значительное изменение данных в основной реплике, может привести к задержке обновления в базе для чтения.

Так же был замечен любопытный эффект. В основной базе измененяем структуру (например, добавим новый справочник), выгнав предварительно пользователей. Из базы для чтения пользователей при этом не выгоняем, пользователи отчетов спокойно продолжают работать. Одновременно с этим основная база меняет структуру, в ней начинают работать полноценные пользователи, наполняют новый справочник. Изменение структуры базы и наполнение базы новой информацией перегружается в реплику для чтения. При этом, пользователи отчетов (реплики для чтения), в текущем сеансе не увидят изменений структуры, т.е. нового справочника (т.к. клиент 1С прочитал старые метаданные). Но они будут иметь всегда обновленную информацию из «известных» объектов. Как только пользователи отчетов перезапустят у себя 1С (перечитают метаданные), они увидят изменение структуры (в нашем примере новый справочник).

Понятно, что у такого поведения есть и отрицательный момент — это контроль целостности получения информации (например, пользователь может сформировать отчет по устаревшему алгоритму).

Выводы


К сожалению, в СУБД Microsoft отказоустойчивость есть, а балансировки по-прежнему нет. Огорчает так же отработка отказа в AlwaysOn: активные соединения с базой отваливаются. Ожидания, исходя из общего описания технологии на ресурсах Microsoft и по выступлениям на различных конференциях, были несколько другими. Но порывшись на ресурсах Microsoft, нашел вот что.

Все честно сказано, но в общих описаниях такой важной особенности нет, да и очевидно становится только после эксперимента.
Но вместе с тем, порадовала гибкость и простота настройки и управления AlwaysOn.

Также порадовала «прозрачная» для 1С работа реплики ReadOnly, правда при этом необходимо немного «допилить» конфигурации 1С.
Ну и стоит сказать, что текущая реализация отказоустойчивости AlwaysOn вполне может использоваться, если для бизнеса некритична потеря незавершенных транзакций и отключение активных сеансов в момент переключения.

Полезные ссылки



P.S.: Статья из доклада, которому 2,5 года, но мне показалось, что она актуальна и сейчас (несмотря на выход SQL2014 и 1С 8.3).
P.P.S.: И еще — не забывайте делать BackUp-ы, AlwaysOn их не заменяет.

Комментарии (15)


  1. dstarcev
    22.07.2015 14:24

    Используем AlwaysOn на проекте в режиме Primary — Readable Secondary
    Поскольку реплики могут «отставать» в синхронизации, нельзя бездумно отправлять туда все запросы на чтение. Пришлось в приложении самим определять «безопасные» места, в которых можно использовать неактуальные данные. В этих местах запросы на чтение могут идти на реплику.


    1. BigD
      22.07.2015 14:31

      А синхронизация синхронная или асинхронная? Ведь при синхронной не отстают.


      1. dstarcev
        22.07.2015 16:35

        Синхронная. Печаль заключается в том, что таки отстают. stackoverflow.com/questions/21161085/sql-server-2012-alwayson-synchronous-replica-is-not-actually-synchronous-for-rea

        Кроме того, синхронная плохо подходит в случаях, когда много записей, а машина реплики пишет медленней, чем машина мастера. Тогда при пиковых нагрузках начинает тормозить запись в мастер.

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

        А вообще, всё это не очень годится для масштабирования. Для отказоустойчивости — да, а при постоянном росте нагрузки и объема данных придётся таки прийти к шардингу. Хотя, многое зависит от проекта…


        1. Alex1C Автор
          22.07.2015 19:23

          В нашем проекте запаса аппаратных ресурсов достаточно, а приложения не создают очень сильной нагрузки. Видимо поэтому значительного отставания не наблюдали.
          Как планируете реализовать механизм проверки отставания, полностью свой или есть какие-то механизмы в MS SQL?
          Согласен, что для масштабирования не очень годится, но мы решили у себя проблему тяжелых отчетов путем разведения пользователей по разным серверам.
          Отказоустойчивость гораздо лучше, но… пример из жизни:) Произошел физический сбой контроллера СХД и на одном из серверов кластера SQL, базы которого на этом СХД, посыпались базы. Служба SQL этого сервера осталась зависшей, отказа по AlwaysOn не было и автоматического аварийного переключения не произошло. Все базы, у которых группа доступности с основной репликой на этом сервере, были в состоянии: на аварийном сервере — «синхронизировано», но не открыть, на резервном (рабочем) сервере — «не сихронизировано». Т.е. на основном сервере (который аварийный) базу не прочитать по причине отказа хранилища, а на резервном копии тоже не доступны. Восстановили базы из архивов, благо случилось в выходной.


          1. dstarcev
            23.07.2015 18:06

            В MS SQL есть что-то вроде «даты последнего обновления индекса». Но это значение на реплике не соответствует реальности, сильно отстаёт и вообще не понятно в каких случаях обновляется.
            Потому я хочу попробовать сделать таблицу с одной строкой и одним столбцом. Туда с каким-то небольшим интервалом (например, 500мс) писать текущую дату. Потом приложение будет сравнивать значение в этой таблице на мастере и на реплике. Таким образом можно понять насколько по времени отстал лог транзакций на реплике. Чем меньше интервал обновления, тем меньше погрешность измерения. Нагрузки большой это создать не должно, но надо поэкспериментировать.


  1. komiller
    22.07.2015 14:42

    реализация полный гемор нужно поднимать домен и танцы с бубном провести еще, Вы когда нибудь в рабочее время очень быстро переключались на вторую ноду? Спасибо за статью


    1. nonname
      22.07.2015 17:27

      А как вообще без домена? А танцы там не такие уж и большие, вполне рабочее решение, но это высокая доступность, главное не думать об этом как о горизонтальном масштабировании.


    1. dstarcev
      22.07.2015 17:38

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


    1. Alex1C Автор
      22.07.2015 18:14

      Вот настройка зеркалирования в MS SQL 2005 — это действительно геморрой, а тут ИМХО не сложно.
      В рабочее время были переключения (не аварийные, сами инициировали): нагрузка на серверах несколько повышалась, но у нас значительный запас по мощностям для нашей нагрузки, поэтому серьезных затруднений не было.


      1. dstarcev
        22.07.2015 19:28

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


        1. Alex1C Автор
          23.07.2015 08:25

          Если оставить за скобками настройку самого кластера и домен, то мне понравилось в AlwaysOn наличие мастеров по добавлению баз в существующую группу (ну и создание группы тоже). При большом количестве баз, существенно упрощает работу и не требует большой квалификации от админов (вполне справится специалист техподдержки:)).


  1. blind_oracle
    22.07.2015 15:14
    +1

    Да, так себе отказоустойчивость.


    1. Alex1C Автор
      23.07.2015 08:44

      Напишите о лидере СУБД, где отказоустойчивость не так себе. Будет интересно многим:)


      1. blind_oracle
        23.07.2015 10:07

        Т.е. вы считаете, что создание двух записей в списке баз 1С у юзера — одну для мастер базы, другую для реплики — это правильно? Пользователь не должен, по-хорошему, вообще замечать процесс switchover-а, максимум — ненадолго залипнет работа.

        Реализуется это, обычно, просто — через кластерный менеджер и виртуальный IP адрес для БД, к которому подключаются клиенты — им не нужно знать, что серверов два-три-много.


        1. Alex1C Автор
          23.07.2015 12:43

          Если я Вас правильно понимаю, вопрос про две записи в списке баз 1С имеет отношение ко второй части эксперимента. Кластерный менеджер должен каким-то образом понимать, что конкретного клиента нужно переключить на реплику ReadOnly. Каким образом это сделать?