В практике администрирования крупных информационных систем на платформе 1С:Предприятие иногда возникает соблазн решить проблему производительности "простым" путем. Например, когда тяжелый обмен данными (по правилам конвертации КД 2.0) сильно замедляет работу пользователей, возникает идея: "А не подключить ли для этого обмена второй, более мощный сервер 1С к той же самой рабочей базе данных MS SQL?".
В этой статье мы подробно проанализируем, почему такая схема является критической архитектурной ошибкой, к каким скрытым и явным разрушениям данных она приводит, а также детально рассмотрим два единственно верных и безопасных способа решения этой задачи.
Для начала проанализируем внутренние механизмы взаимодействия платформы 1С с базой данных. Фирма "1С" официально заявляет, что к одной базе данных SQL в каждый момент времени должен быть подключен только один кластер серверов 1С. Если вы запускаете две независимые службы 1С (два разных кластера) на разных физических серверах или даже на одном, но под разными портами, и настраиваете их на одну базу MS SQL, вы гарантированно получите проблемы со стабильностью данных. Выясним конкретные причины этого поведения.
Сервер приложений 1С активно использует кэширование в оперативной памяти (процессах rphost) для оптимизации повторных обращений к часто используемым данным. В кэш попадают:
Рассмотрим ситуацию: пользователь на сервере "А" изменяет значение важной константы. Изменение успешно записывается в таблицу СУБД MS SQL. Однако сервер "Б" ничего об этом не знает, так как между независимыми серверами приложений нет канала связи для сброса и актуализации кэша. В результате пользователи на сервере "Б" будут продолжать читать устаревшее значение из своей оперативной памяти. При попытке проведения документов на сервере "Б" на основе неактуальных данных возникнет логическая коллизия, которая приведет к незаметному, но неотвратимому искажению аналитики и учета.
Это одна из самых опасных проблем, упомянутых в обсуждении. Платформа 1С реализует двухфазную систему блокировок данных:
rmngr). Они предотвращают параллельное изменение одних и тех же регистров разными сеансами.Заблокировать().Поскольку у нас запущены два независимых сервера, у каждого из них будет свой собственный, изолированный менеджер блокировок. Сервер "А" не имеет ни малейшего представления о том, какие данные заблокировал сервер "Б".
В результате СУБД MS SQL начнет выполнять параллельные транзакции на запись данных, которые по логике конфигурации 1С должны выполняться строго последовательно. Это приведет к следующим последствиям:
Платформа 1С гарантирует строгий порядок проведения документов секунда в секунду за счет механизма оперативной отметки времени. За генерацию этой отметки отвечает менеджер кластера. Если два сервера работают параллельно и независимо, они начнут выдавать оперативную отметку времени несогласованно.
Это моментально разрушит логику партионного учета, списания себестоимости по FIFO/LIFO и корректность расчета остатков на момент проведения документов. Документы могут получить идентичное время проведения вплоть до миллисекунд, нарушая базовые принципы бизнес-логики 1С.
Выясним причину сбоев в нумерации документов, о которых справедливо шла речь на форуме. Выдачей новых номеров документов и кодов справочников управляет служба нумерации сервера приложений 1С. Для оптимизации сервер запрашивает у СУБД диапазоны номеров и кэширует их.
При одновременной работе на двух независимых серверах они начнут выдавать одинаковые номера разным документам в один и тот же момент времени. При попытке записи система выдаст критическую ошибку нарушения уникальности кода/номера, либо (если уникальность отключена) база наполнится дублями номеров документов, что сделает сдачу отчетности невозможной.
Каждая служба 1С имеет собственный независимый планировщик заданий РегламентныеЗадания. Они будут пытаться запускать одни и те же процессы параллельно:
Одновременный запуск таких процедур вызовет колоссальную перегрузку MS SQL Server, зависание процессов и гарантированное задвоение записей в регистрах или повторную отправку писем и файлов контрагентам.
При создании новых объектов (документов, справочников) платформа генерирует уникальные идентификаторы. Алгоритм генерации последовательных GUID (UUID v1) опирается на системное время и уникальный MAC-адрес сетевой карты сервера приложений.
При переносе базы или одновременной записи с разных серверов пулы генерируемых GUID начнут резко отличаться по диапазону. Это приводит к двум проблемам:
INSERT в середину страниц индекса), что критически снижает общую скорость работы всей базы.Если перед нами стоит задача задействовать ресурсы мощного сервера (например, Сервера №2) для выполнения тяжелых обменов КД 2.0, но сохранить работу пользователей на текущем Сервере №1, мы должны объединить их в один кластер.
Проанализируем по шагам процесс настройки требований назначения функциональности:
Выполним интеграцию серверов через консоль администрирования кластера 1С:
rphost на новом сервере и включит его в общую балансировку нагрузки.Теперь нам нужно сделать так, чтобы обычные пользователи работали на медленном сервере, а все тяжелые фоновые задания (включая наши обмены) выполнялись исключительно на быстром сервере. Для этого настроим Требования назначения функциональности.
Перейдем в свойства медленного Сервера №1 в консоли администрирования и добавим следующие правила:
Клиентское соединение или Фоновое задание;Регламентные задания;Не назначать.Перейдем в свойства быстрого Сервера №2 и настроим требования противоположным образом:
Фоновое задание;Регламентные задания или конкретное фоновое задание по имени;Назначать (или Преимущественно назначать).Преимущества данного решения: Все сервисы (блокировки, кэш, нумерация) работают абсолютно согласованно в рамках единого кластера, при этом тяжелые вычисления физически перенесены на быстрый сервер без малейшего риска разрушения базы данных.
Если объединить серверы в один кластер по каким-то причинам невозможно (например, серверы находятся в разных подсетях или имеют разные версии операционных систем), рассмотрим классическое и максимально надежное решение — Распределенную Информационную Базу (РИБ).
Проанализируем архитектуру этого решения:
КД 2.0. Поскольку пользователи здесь не работают, обмену никто не мешает, и он выполняется на максимальной скорости.Рассмотрим пример кода для программной регистрации изменений при миграции данных в РИБ:
// Пример регистрации изменений для узла плана обмена перед отправкой данных
ПланОбменаСсылка = ПланыОбмена.СинхронизацияДанных.НайтиПоКоду("БЫСТРЫЙ_ОБМЕН");
Если Не ПланОбменаСсылка.Пустая() Тогда
// Регистрируем изменения для конкретного документа
ПланыОбмена.ЗарегистрироватьИзменения(ПланОбменаСсылка, ВыборкаДокументов.Ссылка);
КонецЕсли;
Преимущества данного решения: Полная изоляция пользовательских сеансов от тяжелых транзакций обмена. Отсутствие рисков взаимных блокировок. Гарантия целостности обеих баз данных.
Подключение двух независимых серверов приложений 1С к одной СУБД — это мина замедленного действия. Рано или поздно это приведет к потере уникальности номеров, логическому разрушению итогов и регистров, а также к "фантомным" ошибкам, которые невозможно локализовать.
Для решения задачи распределения нагрузки всегда используйте либо единый кластер серверов 1С с требованиями назначения функциональности, либо архитектуру Распределенных Информационных Баз (РИБ).