Работа с распределенными информационными базами (РИБ) при наличии большого количества узлов (от 10 и выше) часто сопряжена с проблемой критических блокировок в центральной базе (ЦБ). Ситуация обостряется, когда объем передаваемых данных исчисляется сотнями тысяч объектов, а стандартные механизмы платформы начинают тратить часы на обработку одного сообщения обмена. Рассмотрим подробнее, почему возникают эти проблемы и как их решить программными и архитектурными методами.
Проанализируем ситуацию: при получении данных в ЦБ система не просто записывает объекты, но и выполняет механизмы регистрации этих изменений для других узлов. Одной из самых ресурсоемких операций является вызов функции ДанныеСоответствуютФильтруПравилРегистрации. Разберем по шагам, что происходит в этот момент:
Как показывает практика, отключение или оптимизация этой проверки позволяет сократить время обмена в несколько раз. Например, выгрузка, занимавшая 6 часов, после оптимизации может сократиться до 40 минут.
Выясним причину избыточной нагрузки. В типовых конфигурациях (таких как УТ 10 или современные решения на БСП) часто заложена логика проверки соответствия данных правилам обмена прямо в момент загрузки. Чтобы победить блокировки, мы можем использовать свойство ОбменДанными.Загрузка = Истина.
Проверим код в модулях наборов записей и объектов. Нам необходимо убедиться, что при загрузке данных не инициируются тяжелые дополнительные проверки. Рассмотрим пример модификации логики:
Функция ДанныеСоответствуютФильтруПравилРегистрации(ЭлементДанных, Знач Получатель)
// Если идет процесс загрузки из другого узла,
// можно применить упрощенную логику или пропустить проверку,
// если мы уверены в целостности данных
Если ЭлементДанных.ОбменДанными.Загрузка Тогда
Возвращать Истина;
КонецЕсли;
// Стандартная логика проверки фильтров
...
КонецФункции
Также важно обратить внимание на количество объектов в одной транзакции. Если параметр КоличествоОбъектовВТранзакции в настройках обмена установлен в значение 0 (означает одну огромную транзакцию на весь файл), это гарантированно приведет к эскалации блокировок на уровне SQL-сервера. Рекомендуется устанавливать это значение в диапазоне 1000–5000 объектов.
Если 10 узлов одновременно пытаются загрузить данные в ЦБ, они начинают конкурировать за таблицы регистрации изменений (_ChngR) и таблицу регистрации номеров сообщений. Проанализируем способы решения этой проблемы:
Рассмотрим ситуацию, когда один документ тянет за собой в обмен тысячи связанных объектов (характеристики, единицы измерения, цены). Это происходит из-за настройки автоматической регистрации связанных данных. Если документ содержит 300 позиций, и для каждой регистрируется характеристика, объем сообщения растет лавинообразно.
Рекомендация: Пересмотрим правила регистрации. Справочники, которые меняются редко (например, характеристики или номенклатура), лучше регистрировать только при их непосредственном изменении, а не "прицепом" к документам. Это позволит избежать передачи 1.5к объектов на один документ.
Посмотрим на проблему с точки зрения системного администратора. При массовой загрузке MS SQL Server может блокировать всю таблицу целиком (эскалация блокировки), если количество заблокированных строк превышает 5000 в одной транзакции. Для высоконагруженных РИБ-систем полезно:
_ChngR.READ_COMMITTED_SNAPSHOT для уменьшения конфликтов между читающими и записывающими процессами.В современных конфигурациях эффективным методом является разделение загрузки данных и их проведения. При загрузке сообщения обмена документы просто записываются в базу без выполнения движений по регистрам. Это снимает основную нагрузку с таблиц итогов и регистров сведений в момент обмена. После завершения загрузки фоновое задание в ЦБ постепенно проводит документы, не блокируя процессы обмена с другими узлами.
Подводя итог, можно сказать: победить блокировки в РИБ на 10 узлах можно только комплексным подходом — оптимизацией кода фильтров регистрации, дроблением транзакций и строгим контролем объема передаваемых данных.