При построении распределенных систем, например, связки "Центральный офис" (1С:Управление Торговлей) и "Магазин" (1С:Розница), часто возникает задача синхронизации мультимедийного контента. Карточки товаров создаются в центре, к ним прикрепляются фотографии, и эти данные должны попасть на кассы или рабочие места продавцов. В данной статье мы разберем основные подходы к решению этой задачи, проанализируем их недостатки и выделим наиболее оптимальные архитектурные решения.
Рассмотрим ситуацию: есть база-источник (УТ), где хранятся эталонные фотографии номенклатуры, и база-приемник (Розница), где эти фото нужны для интерфейса кассира или прайс-чекеров. Автор вопроса изначально предложил использовать самописный механизм через COM-соединение. Давайте проанализируем этот и другие варианты, которые мы можем применить.
В ходе анализа мы выделим четыре основных стратегии:
Изначально предложенный вариант с использованием V83.COMConnector выглядит так:
// Пример логики, которую хотел реализовать автор
Коннектор = Новый COMОбъект("V83.COMConnector");
Соединение = Коннектор.Connect("File=""C:\BaseRetail"";Usr=""Admin"";");
// Далее выборка и передача данных
Хотя этот метод кажется простым для программиста, мы настоятельно не рекомендуем использовать его для передачи двоичных данных по следующим причинам:
comcntr.dll на клиенте и сервере совпадали бит в бит. При автоматическом обновлении одной из баз обмен неминуемо "упадет" с ошибкой "Class not registered".rphost или клиентского приложения, так как 1С не всегда корректно освобождает ресурсы после разрыва соединения.Давайте посмотрим на стандартные возможности платформы. Механизм синхронизации данных (КД 3.0, формат EnterpriseData) умеет передавать присоединенные файлы "из коробки".
Преимущества:
Недостатки и нюансы:
При передаче файлов через XML или JSON (EnterpriseData) двоичные данные кодируются в формат Base64. Это увеличивает объем передаваемого трафика примерно на 33%. Если у вас база объемом в сотни гигабайт картинок, файл выгрузки сообщения обмена может стать гигантским, что приведет к ошибке Недостаточно памяти при попытке его прочитать.
Если мы выбираем этот путь, необходимо убедиться, что в настройках синхронизации (в режиме Предприятия) включена опция "Выгружать файлы" (часто она выключена по умолчанию для экономии трафика).
Более грамотным подходом с точки зрения производительности базы данных является хранение файлов не внутри базы (в таблицах SQL), а в томах на диске. Давайте разберем, как это работает.
В настройках "Работа с файлами" мы создаем том (путь к папке на сервере). 1С автоматически раскладывает файлы по подпапкам, используя дату или хэш, чтобы избежать переполнения одной директории (проблема производительности NTFS/ext4 при наличии >100 000 файлов в одной папке).
Если базы находятся в одной локальной сети, мы можем настроить обе базы на работу с одним и тем же сетевым каталогом (UNC-путь, например \\Server\Images).
Риски общего доступа:
Как справедливо заметили участники обсуждения, предоставление прямого доступа двум базам к одним и тем же файлам может привести к "бардаку":
Давайте проанализируем наиболее современный и масштабируемый подход, который решает проблемы производительности и объемов данных. Идея заключается в разделении слоя хранения данных и слоя метаданных.
Алгоритм реализации:
В этом случае база-приемник (Розница) получает строку вида http://server-ut/images/tovar123.jpg. Когда кассиру нужно увидеть фото, 1С просто скачивает его по HTTP или отображает в поле HTML-документа.
Это дает колоссальный выигрыш:
Если мы решим пойти по пути хранения файлов во внешнем хранилище или передачи через веб-сервис, нам пригодятся следующие приемы.
Если вы используете типовой план обмена, но хотите исключить передачу самих файлов (Справочник.НоменклатураПрисоединенныеФайлы), но оставить передачу ссылок на них, можно вмешаться в процедуру перед выгрузкой:
// Пример кода в обработчике "ПередВыгрузкой" или во внешней обработке
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, Метаданные.Справочники.НоменклатураПрисоединенныеФайлы);
Однако будьте осторожны: если в узле-приемнике разрешено редактирование, данные могут разойтись.
Прежде чем сохранять фото в хранилище, мы рекомендуем их обрабатывать. Фотографии со современных смартфонов могут весить 5-10 Мб и иметь разрешение 4000x3000, что избыточно для учетной системы.
Используйте средства платформы или внешние компоненты для:
Чтобы избежать дублей, полезно при загрузке вычислять хэш файла (MD5) и хранить его. В базе-приемнике мы будем искать картинку не по наименованию, а по уникальному идентификатору (GUID) или хэшу.
Давайте подведем итоги. Для настройки одностороннего обмена фотографиями:
ХранилищеЗначения внутри базы данных при больших объемах.