Назрела тут тема про обмены между базами данных 1С. Даже сузим круг и поговорим об обменах между гомогенными базами данных или, другими словами, между базами данных с идентичными конфигурациями.
Для всякого рода обменов в 1С придуман, и очень давно, специальный механизм при помощи сущности (объекта конфигурации) «План обмена». Часто для обмена между гомогенными системами используется механизм РИБ, но он использует все те же Планы обмена с чёткой иерархической структурой узлов «Центральная база – Периферийные базы».
![Распределенная информационная база](https://habrastorage.org/getpro/habr/upload_files/22f/8d4/d80/22f8d4d80b61fa7810e161d543875817.png)
Но, в целом, распределенную систему можно построить и просто на планах обменах, не прибегая к опции РИБ. Тут все индивидуально и зависит от фантазии и желания.
Зачем используют РИБ (ну или просто обмен через механизм ПланыОбмена)?
Самый лаконичный ответ видится как – для разделения учета по разным базам данных, т.к. обычно кроме НСИ они почти ни в чём не пересекаются. Это типичная и распространенная картина распределенных информационных систем, например, по территориальному признаку. Есть центральный офис, есть множество филиалов в разных регионах нашей страны. Каждая система управляется на местах, но бизнес-процессы едины, конфигурация тоже одна, обновляется централизовано.
Кто-то скажет, что в эпоху глобального, повсеместного и доступного интернета – это всё блажь и можно замечательно работать с единой БД через тонких или web клиентов. Ну да, можно. Архитектура имеет право на жизнь и тоже распространена. Но, во-первых, каналы связи могут быть не везде стабильными/быстрыми, а простои на той же кассе магазина категорически недопустимы. Во-вторых, администрировать единую БД может оказаться гораздо сложнее и затратнее: большие потоки данных, большой размер базы + ее обслуживание, более сложное разграничение прав пользователей, более высокие требования к компетенциям админов и разработчиков, работа оборудования и поддержка пользователей на местах и т.д. и т.п. Ну и, в-третьих, отказоустойчивость. Это далеко не исчерпывающий список причин. Их гораздо больше и каждая компания, пользующая РИБ, может назвать свои уникальные. Поэтому картина, когда бизнес предпочитает распределенную систему баз данных централизованной – далеко не редкость. Всё считается, и обсуждать преимущества централизованной системы БД над распределенной или наоборот не будем, а поговорим о проблемах производительности типового обмена 1С.
Что-то нового про проблемы ПлановОбменов, чего не было в других публикациях, я не напишу. Но, тем не менее, до сих пор далеко не все специалисты докапываются до причин просадки скорости типового обмена. Обмен частенько тормозит, и все привыкли к этому. Причины этого могут быть разные: транспорт/инфраструктура, архитектура, и пр. Но сейчас мы рассмотрим одну из наиболее распространенных проблем – блокировки на фиксации изменений.
Для каждого объекта метаданных, который участвует в обменах ведется отдельная таблица регистрации изменений, где хранится список измененных объектов для ПлановОбмена. Наименование таблиц на стороне SQL имеет характерный суффикс ChngR (в старых версиях платформы 1С – ChangeRec): _DocumentChngRXXXXX, _InfoRgChngRХХХХХ, _ReferenceChngRХХХХХ и т.д.
Рассмотрим пример не самой интенсивной в части обмена базы данных, которая взаимодействует лишь с одной периферийной базой. Все скрины ниже сделаны в программе мониторинга Perfexpert.
В системе в течение каждого рабочего дня постоянно фиксируются sql-блокировки (см. нижний график на рисунке ниже с блокировками за одну неделю).
![](https://habrastorage.org/getpro/habr/upload_files/256/fea/7a7/256fea7a7c7a35cfef5b9690ff76ac98.png)
Если в Perfexpert построить за этот же период трассу Locks, то картина по блокировкам следующая:
![](https://habrastorage.org/getpro/habr/upload_files/4b4/7a5/806/4b47a5806788c01e5abd015acdfd689d.png)
Схлопнем статистику по видам блокировок:
![](https://habrastorage.org/getpro/habr/upload_files/3ea/33b/219/3ea33b219137af8b0cfe55f9cf86a1b7.png)
Табличные блокировки занимают 25% всего времени и к обменам отношения не имеют (как с ними бороться см. в этой статье), а вот ключевые блокировки занимают 75% времени, и все они на таблицах обмена. Вот типичные тексты запросов, которые сталкиваются с ожиданиями на таких блокировках:
![](https://habrastorage.org/getpro/habr/upload_files/d97/07a/a4b/d9707aa4b8d138c3e190c7c75c102b24.png)
Укрупненно процесс выгрузки состоит из регистрации изменений и выгрузки изменений. Преимущественно блокировки происходят на втором этапе, когда происходит выборка изменений для их выгрузки. Но и на первом этапе тоже встречаются.
Все эти блокировки связаны с объектами (справочники, документы, записи регистров и т.д.), которые часто меняются, поэтому, повторюсь, вся эта проблематика касается только крупных и нагруженных систем.
Механика блокировки, следующая:
1. На этапе "Регистрация изменений"
Пользователь 1 регистрирует изменения по объекту методом ЗарегистрироватьИзменения(). На уровне SQL сразу открывается транзакция и выполняется команда UPDATE:
![](https://habrastorage.org/getpro/habr/upload_files/a15/56d/e93/a1556de9313371a5ba182e00a427a80a.png)
Т.е. в таблице регистрации изменений сразу меняется номер сообщения «_MessageNo» на новый - NULL, тем самым помечая его готовым к выгрузке. А потом следующим запросом в этой же транзакции пойдет уже SELECT, чтобы проверить, а есть ли вообще такая строка с «_MessageNo IS NULL». Если есть, то отрабатывает UPDATE, а если нет, то делается INSERT.
И вот в этом UPDATE вся суть блокировки. Такая последовательность (сначала UPDATE, а потом SELECT) сделаны для того, чтобы какой-либо другой пользователь не успел обновить эту же строчку. Иначе (сначала SELECT, а потом UPDATE) во время выполнения SELECT другой пользователь может успеть изменить запись, и логика регистрации изменений нарушится.
То есть, если в это же время Пользователь 2 пытается изменить тот же объект, то попадёт на блокировку первого Пользователя. На рисунке ниже эта ситуация видна в виде дерева блокировок пользователей со SPID 134 и 61, которые пытаются изменить элемент справочника номенклатуры:
![](https://habrastorage.org/getpro/habr/upload_files/141/8ad/4bd/1418ad4bd9520ce1d465df5a26e69941.png)
2. На этапе "Выгрузка изменений"
Пользователь 1 выбирает данные для выгрузки при помощи метода ВыбратьИзменения(). Схема аналогичная предыдущей – выполняется операция в транзакции, запуская сначала UPDATE и устанавливая _MessageNo новый номер, больший предыдущего на единицу:
![](https://habrastorage.org/getpro/habr/upload_files/7b6/af4/e21/7b6af4e2182f9b6ffe4cbb8325b0bbe4.png)
Выбираются строки с пустым номером сообщения, то есть строки, которые еще никуда не отправлялись, но были зарегистрированы к обмену. И таких строк может быть очень много. Чем больше строк, тем больше вероятность блокировки: как из-за количества самих по себе блокируемых строк, так и из-за увеличения длительности UPDATE по мере увеличения обрабатываемых строк.
Таким способом каждый объект метаданных обрабатывается в отдельной транзакции.
Допустим, Пользователь 2 открывает тоже транзакцию и меняет объект, который недавно уже менялся (и попал в таблицу регистрации изменений), но еще не был отправлен (то есть, у этого объекта пустой номер сообщения). В процессе изменения в таблице регистрации происходит попытка изменить запись объекта – заново «обнулить» номер сообщения. Но он попадает на блокировку первого пользователя, который выполняет UPDATE для установи очередного номера _MessageNo.
Или, допустим, есть еще один процесс обмена, который уже завершает выгрузку и выполняет запрос UPDATE, чтобы обновить номер у всех объектов, у кого он не установлен, и опять же попадает на блокировку Пользователя 1.
Ниже представлены несколько случаев, когда процессы обмена конкурируют с пользовательскими сессиями или между собой.
![](https://habrastorage.org/getpro/habr/upload_files/155/906/1e2/1559061e24d0c65968140700cd7a3c1e.png)
Кстати, может быть более интересный вариант блокировки. Не простая блокировка, а распределенная взаимоблокировка (deadlock) – на стороне SQL одновременно с 1С-блокировкой:
![](https://habrastorage.org/getpro/habr/upload_files/1f3/565/95a/1f356595ad72a5fdbb3686b815adfcdc.png)
На уровне СУБД пользователь s.smirnova (spid 132) ожидает завершения операции пользователя Админ… (spid 107) - см. верхнее окно «Сессии SQL». А на уровне 1С картина выглядит в точности наоборот, пользователь Админ… ожидает завершения операции пользователя s.smirnova. Это и есть распределенный deadlock.
Важно отметить и тот факт, что на уровне СУБД за пользователем Админ… скопилась очередь из других ожидающих (заблокированных) пользователей. Но, фактически, они ждут не завершения операции пользователя Админ…, а её прерывания по таймауту, так как он тоже является заблокированным, но на уровне 1С.
Такие распределенные блокировки вообще мало кто идентифицирует. Специалисты 1С смотрят на управляемые блокировки, а админы БД – на sql-блокировки. Картина же целиком не видна никому. Подробнее про распределенные взаимоблокировки расписывал ранее здесь: Записки оптимизатора 1С (часть 3). Распределенные взаимоблокировки в 1С системах.
Теперь «Что делать?»
Блокировки на таблицах обмена можно попытаться обойти следующими методами:
1) Стандартный механизм обмена 1С
Постараться оптимизировать процесс стандартного обмена в следующих направлениях:
Уменьшение порции выгрузки данных. В том числе путем подбора оптимальных параметров метода ВыбратьИзменения().
Подбор расписания выгрузки так, чтобы минимизировать взаимное влияние процессов обмена и оперативной работы пользователей.
Использование не одного ПланаОбмена, а нескольких с разбиением объектов в них по приоритетам и требованиям к периодичности обмена.
2) Сервис QProcessing
Модифицировать запрос на чтение изменений путем добавления хинта READPAST, который заставляет читающий запрос игнорировать заблокированные записи. Для робота обмена такое поведение как раз подходит: не прочитали запись в этот раз — выгрузим в следующей итерации обмена, зато не будем ждать на блокировке. Такой манёвр не является панацеей, но он позволяет снять значительную часть тех конфликтных ситуаций при выгрузке изменений, которые описаны выше. В каких-то случаях этого может оказаться достаточно.
Стандартные средства 1С не позволяют добавлять хинты к тексту запроса. Но это можно сделать при помощи решения Softpoint QProcessing. Это специальный «прокси», который пропускает через себя запросы и может модифицировать их «на лету» согласно предопределенным правилам.
3) Репликация Softpoint
Отказаться от стандартного обмена 1С и использовать другие механизмы обмена, например, решение Softpoint – DB Replication, позволяющее практически в онлайн-режиме обеспечивать полную синхронизацию данными между базами данных.
Первые два метода – это все же полумеры, но количество блокировок снизиться, скорость обмена несколько возрастет.
Если рассматривать действительно качественное ускорение, то стоит смотреть в сторону репликационных механизмов. Я буду, естественно, топить за наш продукт DB Replication. Не хочется здесь дублировать маркетинговое описание, поэтому буквально несколько ключевых тезисов, за счёт чего достигается высокая скорость обмена и гарантированная доставка получателям.
Главные особенности DBREPLICATION:
Это транзакционная репликация, каждое изменение начинает передаваться сразу же после фиксации транзакции.
Строгое соблюдение транзакционной целостности и последовательности при передаче изменений.
Механизм регистрации и чтения изменений данных организован на совершенно иных принципах, чем в типовом обмене 1С. DBREPLICATION использует триггеры + очереди обмена. За счет этого в DBREPLICATION отсутствует проблема с блокировками на таблицах 1С.
Важно, что механизм репликации не вносит изменений в структуру таблиц 1С (триггеры не в счёт), тем самым появление репликации не мешает обычному функционированию конфигурации 1С.
Во внутренней архитектуре транспортной подсистемы применяются такие решения как многопоточная параллельная обработка очередей, конвейерный подход, потоковое сжатие, пакетная обработка транзакций, использование «Bulk Insert» и другие.
Транспорт реализован на основе служб Windows, оснащен множеством функций обеспечения бесперебойности работы: автоматическое восстановление обмена после обрывов связи, работа на слабых неустойчивых каналах связи, автоматическая обработка конфликтов версионности (для двустороннего обмена), автоматическая адаптация в случае изменений в структуре таблиц бизнес-приложения, и другие.
Централизованное обновление конфигурации 1С с помощью специальной подсистемы в составе программного комплекса DBREPLICATION.
Остальное лучше почитать на страничке продукта.
Примеры использования DBReplication на замену РИБ
Здесь приведу консолидированный список наиболее распространенных задач и проблем, с которыми к нам приходят заказчики, использующие типовой механизмом обмена 1С, который перестал удовлетворять их требованиям.
Дабы не плодить в комментариях фраз типа «Да нужно было просто правильно настроить РИБ…», сразу сделаю оговорку. Мы не настраиваем РИБ, не работаем с РИБ и не даем консультаций по работе штатного обмена 1С, потому что наша компетенция в другом – мы переносим механизм обмена на абсолютно другой качественный уровень и снимаем этим сразу множество болей. При этом, сам по себе РИБ (и вообще механизм планов обмена 1С) – это отличный инструмент, но он, как и любая технология, имеет свои слабые стороны и объективные пределы возможностей. А наша технология DBReplication «выходит на сцену» и как бы «подхватывает эстафету» в тех случаях, когда РИБ перестаёт удовлетворять владельца.
Типичные проблемы и задачи, связанные с типовым обменом между ИБ 1С:
Серьёзные помехи пользователям со стороны механизма обмена – массовые блокировки при загрузке и выгрузке данных.
В тех случаях, когда обмен работает в специально отведенном регламентном окне, часто бывает такая проблема, что он не укладывается в это окно и «наползает» на время активной работы пользователей, сильно мешая им (блокировками и нагрузкой). Этот «перехлест» приводит к снижению эффективности работы пользователей часы, страдают бизнес-процессы.
Недостаточная надёжность обмена. Постоянно сбои, нарушения консистентности данных, длительные простои обмена из-за сбоев. Например, при очередном сеансе обмена происходит сбой, из-за чего обмен с тем или иным узлом не выполнен, приходится повторять его. А возможность повтора может быть, например, только через сутки. Когда у вас в системе много узлов (десятки), из-за таких сбоев некоторое количество узлов может находится в состоянии сильно большего отставания – до нескольких суток.
Повышенная нагрузка на аппаратные ресурсы в время выгрузки данных на источнике и их применения на приёмнике.
Проблемы с установкой обновлений конфигурации 1С: процесс накатки очередного релиза на все узлы может растягиваться на дни и даже недели.
Недостаточная скорость синхронизации баз, и это не удовлетворяет бизнес-заказчика. Скорость обмена не позволяет реализовывать перспективные бизнес-процессы, повышать эффективность производственных процессов и т.п. В этом смысле очевидно, что, когда у вас базы синхронизируются, например, один раз в сутки, и когда базы синхронны постоянно с задержкой, допустим, всего 15 секунд – это, как говорится, две большие разницы.
Невозможность создания централизованной консолидированной базы (ЦБ) данных с оперативно обновляемой информацией (причины всё те же – не хватает возможностей типового обмена, чтобы оперативно подгружать изменения по всем потребным объектам). А значит затруднено получение централизованной отчетности, аналитики, затруднены создание и синхронная работа корпоративных интернет-порталов, интернет-магазинов и т.п.
Невозможность организовать постоянно актуальную «горячую» копию базы данных, в которой можно было бы запускать 1С:Предприятие (т.е. она должна быть постоянно доступна «на запись») для таких задач как:
Тестирования и разработки функционала конфигурации 1С. Причем эта копия может быть обрезанной (уменьшенной в объёме), но при этом всегда наполнена самыми оперативными данными.
Балансировки нагрузки. Отчетность, аналитические выборки, тяжёлые регламентные операции и т.п. – это можно вынести в отдельный экземпляр информационной системы, и тем самым исключить конкуренцию за ресурсы между этими нагрузками и пользователями.
Использования базы-копии для выгрузки оперативных изменений во внешние хранилища, BI системы, корпоративное «озеро/витрину данных».
Отказоустойчивости – когда горячая копия является страховкой на случай отказа основной базы. А в обычное время, чтобы аппаратные ресурсы не простаивали, база-копия может использоваться для балансировки нагрузи – в ней можно строить отчеты, аналитические выборки и т.п.
Понятно, что все упомянутые проблемы так или иначе, напрямую или косвенно приводят, во-первых, к дополнительным издержкам для бизнеса (сопровождение механизма обмена, преодоление последствий регулярных его сбоев, снижение эффективности работы пользователей и т.д.), во-вторых, могут стать технической помехой на пути развития бизнеса.
Заключение
Проблемы с просадкой производительности, вызванные блокировками на таблицах типового обмена 1С, присущи, конечно, в основном высоконагруженным базам данных. Поэтому, если блокировки не мешают работе пользователей, не тормозят обмен, не тормозят бизнес-процессы, и вам не критична высокая скорость обмена, близкая к онлайну, то искать альтернативы смысла нет. Пока!
Если вы пошли по пути оптимизации работы типовых механизмов на основе планов обмена 1С, то этот путь имеет свой потолок. Либо на стороне выгрузки, либо на стороне загрузки. И если вы в него уперлись или прогнозируете, что скоро упретесь, то добро пожаловать в мир репликации. Благодаря DB Replication вы получите довольно много вкусных возможностей:
Отсутствие блокировок на фиксации изменений – все транзакции становятся в очередь.
Отсутствие проблемных выгрузок – все изменения считываются последовательно/хронологически из очереди.
Потеря данных и неконсистентность исключены – четкая транзакционная целостность и последовательность.
Автоматическое разрешение конфликтов – нет несогласованных состояний при одновременном изменении данных в двух БД.
Время доставки отдельной небольшой транзакции – практически онлайн. На практике средняя задержка на обычном трафике (не пиковом) – 5-15 секунд.
Возможность проводить обрезку баз данных без остановки пользователей.
Возможность иметь «горячие архивы» продуктивной системы.
Возможность восстановить базу данных на любой момент времени, используя очередь репликации сервера дистрибуции. Очередь хранится на сервере дистрибутора с любой заданной глубиной (обычно от 3 недель до 3 месяцев, это настраивается параметрически). Об этой возможности, кстати, у нас есть отдельная статья «Бэкап, бэкап и еще раз бэкап».
Возможность добавлять к своей распределенной ИС 1С узлы, у которых базы данных лежат на PostgreSQL. Такая возможность может быть полезна для разных задач, одна из них рассмотрена в другой нашей статье – «Гетерогенная распределенная система как способ миграции больших и не очень баз данных с MSSQL Server на PostgreSQL».
Как у любой технологии есть и обратная сторона, поэтому озвучу ограничения или, если угодно, минусы:
DBREPLICATION работает только с гомогенными системами, в терминах 1С – это системы с идентичными конфигурациями. Но учитывая, что есть тренд перехода MS SQL > PostgreSQL, то конфигурации-то может и будут идентичными, а вот базы данных уже не гомогенные. В этом году DBREPLICATION сделала большой шаг вперед и обзавелась функционалом репликации 1С-систем MS SQL > PostgreSQL и обратно.
Есть определенная избыточность с точки зрения записей на диски: при каждом изменении строки таблицы 1С происходит запись целиком всей строки в очередь, то есть в очередь попадает вся цепочка состояний строки. И вся эта цепочка затем передаётся по маршруту и последовательно применяется в базах-получателях (для сравнения – в типовом обмене 1С вся цепочка не передаётся, берется только состояние строки на момент выгрузки обмена). Однако, с точки зрения общей нагрузки на диски вклад этой «избыточности» принципиального значения не имеет, особенно с учетом эволюции дисковых систем в последние годы. Зато приобретается целый ряд полезностей, о которых и говорится в статье.