Фоновые задания в OneScript и эксперименты с многопоточной выкачкой версий хранилища

09.01.22

Разработка - Групповая разработка (Git, хранилище)

Описываю использование фоновых заданий в OneScript.

Однажды передо мной встала задача выгрузить в гит многолетнюю историю версий хранилища - больше 3 тысяч версий. Решение в лоб - расчехляем старый добрый gitsync и натравливаем его на хранилище. Конфигурации уровня ERP скачиваются долго - и это большая проблема. Частично выгрузку можно ускорить, разделив выгрузку версий хранилища и обработку их для выгрузки в гит (как описано в моей статье Devops на коленке). Но все равно это очень долго.

Одно из возможных решений - распараллелить обработку версий хранилища, запустить выгрузку в разные ветки гита разных версий (например 1-1000, 1001-2000, 2001-3000 и тд), а потом сделать rebase силами git. Это тоже не очень быстрая операция. Параллельность обработки версий хранилища можно обеспечить вручную - запустив нужные команды в разных окошках консоли, а потом следить за их выполнением, не очень-то удобно.

А мы знаем, что с версии 1.6.0 в oscript появилась возможность использовать фоновые задания. Синтаксис работы с ними чуть отличается от 1С, но принцип схож - создаем массив с параметрами и вместе с именем выполняемой процедуры передаем его менеджеру фоновых заданий, затем можно ожидать завершения выполнения либо всех фоновых заданий, либо одного (оставлю ссылку на документацию, там все предельно понятно написано - Фоновое задание).

Попробую написать скрипт с фоновыми заданиями, который выгрузит версии хранилища в несколько потоков.

 

Скрипт многопоточной загрузки версий хранилища

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

Функция ТаблицаВерсийДляЗагрузки(НачальныйНомер, КонечныйНомер)

    ТаблицаВерсий = Новый ТаблицаЗначений;
    ТаблицаВерсий.Колонки.Добавить("НомерВерсии");
    ТаблицаВерсий.Колонки.Добавить("Статус");
    ТаблицаВерсий.Колонки.Добавить("ДатаНачалаЗагрузки");
    ТаблицаВерсий.Колонки.Добавить("ДатаЗавершенияЗагрузки");

    Счетчик = НачальныйНомер;
    Пока Счетчик <= КонечныйНомер Цикл
        НоваяСтрока = ТаблицаВерсий.Добавить();
        НоваяСтрока.НомерВерсии = Счетчик;
        НоваяСтрока.Статус = "Не обработана";
        Счетчик = Счетчик + 1;
    КонецЦикла;

    Возврат ТаблицаВерсий;

КонецФункции

Чуть не забыл, хранилище 1С под одним и тем же пользователем не может работать одновременно с несколькими базами - значит нам надо создать несколько пользователей в хранилище и передать в скрипт описание этих пользователей.

 

 

Здесь я создал пользователей без паролей и каких-либо прав с именем по шаблону "ЧтениеХранилищаНомер". В функции получения массива пользователей беру пользователя, начиная с нулевого (ну программист я, что поделаешь) и заканчивая нужным количеством (вынес количество пользователей хранилища в переменную - пригодится дальше, когда буду экспериментировать).

Функция МассивПользователейХранилища(КоличествоПользователейХранилища)

    Результат = Новый Массив;

    СчетчикПользователей = 0;
    
    Пока СчетчикПользователей <= КоличествоПользователейХранилища Цикл
        Результат.Добавить(СтрШаблон("%1%2", ИмяПользователяХранилища, СчетчикПользователей));
        СчетчикПользователей = СчетчикПользователей + 1;
    КонецЦикла;

    Возврат Результат;

Конецфункции

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

ТаблицаВерсий = ТаблицаВерсийДляЗагрузки(1, 15);

МассивТекущихЗаданий = Новый Массив;

КоличествоПользователейХранилища = 8;
СвободныеПользователи = МассивПользователейХранилища(КоличествоПользователейХранилища);

Для Каждого СтрокаВерсии Из ТаблицаВерсий Цикл
    
    Если МассивТекущихЗаданий.Количество() = КоличествоПользователейХранилища Тогда
        ОжидатьВыполненияЛюбогоЗаданияЗагрузки(МассивТекущихЗаданий, ТаблицаВерсий, СвободныеПользователи);    
    КонецЕсли;

    СтрокаВерсии.Статус = "Отправлена на загрузку";
    СтрокаВерсии.ДатаНачалаЗагрузки = ТекущаяДата();
    ДобавитьЗаданиеЗагрузки(СтрокаВерсии.НомерВерсии, МассивТекущихЗаданий, СвободныеПользователи);
   
КонецЦикла;

Добавление задания загрузки для лаконичности вынес в отдельную процедуру:

Процедура ДобавитьЗаданиеЗагрузки(НомерВерсии, МассивЗаданий, СвободныеПользователи)

    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(СвободныеПользователи[0]);
    МассивПараметров.Добавить(НомерВерсии);

    МассивЗаданий.Добавить(ФоновыеЗадания.Выполнить(ЭтотОбъект, "СохранитьВерсию", МассивПараметров));
    
    СвободныеПользователи.Удалить(0);
    
КонецПроцедуры

Ну и приведу листинг процедуры СохранитьВерсию, это простое использование библиотеки v8storage.

Процедура СохранитьВерсию(Пользователь, НомерВерсии) Экспорт

    ИмяФайлаКофигурации = СтрШаблон("%1\%2.cf", КаталогСохранения, НомерВерсии);
	ВременноеИмяФайлаКофигурации = СтрШаблон("%1\%2.tmp", КаталогСохранения, НомерВерсии);

    ХранилищеКонфигурации = Новый МенеджерХранилищаКонфигурации();
    ХранилищеКонфигурации.УстановитьПутьКХранилищу(ПутьКХранилищу);
    ХранилищеКонфигурации.УстановитьПараметрыАвторизации(Пользователь, "");
    
	ХранилищеКонфигурации.СохранитьВерсиюКонфигурацииВФайл(НомерВерсии, ВременноеИмяФайлаКофигурации);
	ПереместитьФайл(ВременноеИмяФайлаКофигурации, ИмяФайлаКофигурации);
	
КонецПроцедуры

В процедуре ОжидатьВыполненияЛюбогоЗаданияЗагрузки я ожидаю завершения любого фонового задания, возвращаю используемого там пользователя хранилища в пул свободных пользователей и дозаполняю таблицу версий - проставляю время завершения загрузки и ее результат.

Процедура ОжидатьВыполненияЛюбогоЗаданияЗагрузки(МассивТекущихЗаданий, ТаблицаВерсий, СвободныеПользователи)

        ИндексЗавершившегося = ФоновыеЗадания.ОжидатьЛюбое(МассивТекущихЗаданий);
        Задание = МассивТекущихЗаданий[ИндексЗавершившегося];
        ПараметрыЗадания = Задание.Параметры;
        Пользователь = ПараметрыЗадания[0];
        СвободныеПользователи.Добавить(Пользователь);
        НомерВерсии = ПараметрыЗадания[1];

        Если ЗначениеЗаполнено(Задание.ИнформацияОбОшибке) Тогда
            Загружена = "Ошибка";
            Сообщить(Задание.ИнформацияОбОшибке.ПодробноеОписаниеОшибки());
        Иначе
            Загружена = "Загружена";
        КонецЕсли;

        НайденныеСтроки = ТаблицаВерсий.НайтиСтроки(Новый Структура("НомерВерсии", НомерВерсии));
        Для Каждого СтрокаТаблицы Из НайденныеСтроки Цикл
            СтрокаТаблицы.Статус = Загружена;
            СтрокаТаблицы.ДатаЗавершенияЗагрузки = ТекущаяДата();
        КонецЦикла;
        МассивТекущихЗаданий.Удалить(ИндексЗавершившегося);

КонецПроцедуры

Полный текст скрипта вы можете найти на гитхабе RepoToCFBackgroundTask.

Запускаю его:

oscript .\toCF\RepoToCFBackgroundTask.os

Работает! Процесс oscript породил кучу процессов 1С. Вот скрин из ProcessExplorer от Sysinternals

 

 

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

 

Эксперименты с многопоточной загрузкой версий хранилища

Ну и теперь самое интересное - эксперименты!

Эксперименты проводил на отдельной виртуальной машине, не загруженной больше ничем. Хранилище находится рядом в локальной сети, подключение по TCP. Я скачивал первые 50 версий нашей основной рабочей конфигурации - ERP. На тот момент это была версия 2.4.5.83, размер CF - в районе 1.3 Гб.

Выгрузка одной версии занимает в среднем 5 минут. Я очищал каталог загрузки и запускал загрузку в n потоков, от 1 до 14, так три раза. Усредненное время загрузки вывел в таблицу. Прошу ознакомиться с моими результатами.

 

Потоков Общее время, минут На 1 версию абсолютное, сек На 1 версию в потоке, мин
1 225,3 270,4 4,5
2 175,1 210,1 7,0
3 122,5 147,0 7,4
4 104,8 125,8 8,4
5 88,6 106,3 8,9
6 80,7 96,8 9,7
7 75,5 90,6 10,6
8 70,9 85,1 11,3
9 67,9 81,5 12,2
10 65,9 79,1 13,2
11 64,6 77,5 14,2
12 63,9 76,7 15,3
13 62,3 74,8 16,2
14 61,6 73,9

17,2

 

 

Если не хочется смотреть в таблицу и график, опишу результат словами - чуда не случилось. Если 50 версий в один поток загружаются чуть меньше 4 часов, то в 10 потоков они загружаются за чуть больше часа, а хотелось бы за 20 минут. Да, ускорение загрузки есть, но оно нелинейное. После 6-7 потоков уменьшение общего времени загрузки незначительно.

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

 

 

Что тут можно сделать? Поставить более быстрый диск, подсыпать еще ресурсов компьютеру, перенести хранилище еще ближе (да хоть на этот же компьютер). Возможности для улучшений еще есть.

Еще, приглашаю вас, мои читатели, воспользоваться этим скриптом и выложить в комментарии свои результаты.

В скрипте нужно указать свои данные - имя пользователя хранилища, путь к нему, место для складывания выгруженных cf. Интересно, что будет у вас.

Итоги

Я научился работать с фоновыми заданиями в oscript. Написал скрипт, позволяющий загружать версии хранилища в несколько потоков.

В итоге с перерывами в течение недели сделал выгрузку всей истории хранилища. Команда git rev-list --count HEAD в репо покажет сколько версий было выгружено:

 

 

3578 версий.

Неплохо, да?

Вступайте в нашу телеграмм-группу Инфостарт

oscript многопоточность v8storage хранилище

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Разработка Инструментарий разработчика Групповая разработка (Git, хранилище) Программист Платные (руб)

Практический курс по работе с AI-агентами для разработчиков 1С уровня middle и senior, а также тимлидов команд: от постановки задач и передачи контекста до создания расширений, интеграций, MCP-инструментов, тестов и проверки готового решения.

50000 руб.

10.09.2026    1627    14    0    

6

DevOps и автоматизация разработки Администрирование СУБД Групповая разработка (Git, хранилище) Системный администратор Программист Руководитель проекта Стажер 1С 8.3 1С:Бухгалтерия государственного учреждения 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1C:ERP Беларусь Россия Казахстан Абонемент ($m)

В четвёртой части серии SRE-Suite-for-1C-platform мы переходим к практической автоматизации развёртывания отказоустойчивого кластера PostgreSQL для высоконагруженных систем 1С на Linux. В материале подробно разбирается инженерное решение без HAProxy — с использованием виртуального IP-адреса и vip-manager от CYBERTEC, обеспечивающего прямое подключение к активному мастеру без лишних задержек и точек отказа. Показана структура Ansible-модуля: подготовка ОС, развёртывание etcd, настройка Patroni с параметрами для больших нагрузок 1С. В конфигурационный шаблон Patroni автоматически закладываются параметры, критически важные для высоконагруженных баз данных, запуск vip-manager и полная автоматизация создания трёхнодового кластера. В конце — пошаговый Quick Start и планы развития модуля, включая резервное копирование, оптимизацию ОС Linux и rolling updates PostgreSQL.

1 стартмани

11.09.2026    553    Ninel_S    0    

0

DevOps и автоматизация разработки Администрирование СУБД Групповая разработка (Git, хранилище) Системный администратор Программист Руководитель проекта Стажер 1С 8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Управление холдингом 1С:Зарплата и Управление Персоналом 3.x 1С:Предприятие 8. Транспортная логистика, экспедирование и управление автотранспортом КОРП 1C:ERP Беларусь Россия Казахстан Абонемент ($m)

В корпоративных инсталляциях «1С:Предприятие 8.3» под управлением PostgreSQL всё чаще проявляются архитектурные пределы масштабирования: рост числа пользователей, обязательная маркировка, плотный поток API-интеграций и высокая стоимость простоя. Вводная часть цикла разбирает ключевые факторы современной эксплуатационной нагрузки и формирует инженерную методологию эволюционной модернизации без остановки продуктивного контура. Материал основан на практическом кейсе «Торговый контур» и показывает, как определить целевые метрики (p95, MTTR, APDEX), выстроить наблюдаемость, стабилизировать работу кластера и подготовить инфраструктуру к дальнейшему масштабированию. Публикация задаёт фундамент для последующих частей, посвящённых телеметрии, оптимизации PostgreSQL, CI/CD и архитектурному росту.

1 стартмани

10.09.2026    627    Ninel_S    0    

5

DevOps и автоматизация разработки Linux HighLoad оптимизация Групповая разработка (Git, хранилище) Системный администратор Программист Руководитель проекта 1С:Предприятие 8 1С 8.3 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Управление холдингом 1С:Комплексная автоматизация 2.х Беларусь Россия Казахстан Абонемент ($m)

Системный анализ архитектурных границ масштабирования учетных систем «1С:Предприятие 8.3» под управлением PostgreSQL в ОС Linux. Формулирование инженерной методологии сквозного проекта «Торговый контур», определение измеримых целевых показателей (p95, MTTR, APDEX) и стратегии поэтапной модернизации эксплуатационного контура без остановки промышленных учетных процессов.

1 стартмани

07.09.2026    906    Ninel_S    10    

1

Linux Групповая разработка (Git, хранилище) Администрирование СУБД Системный администратор Программист 1С 8.3 Абонемент ($m)

Декларативный pipeline в GitHub Actions, тонкости лицензирования в Docker (--net=host), изоляция RUN_ID и интеграция со сборочным конвейером SRE-Suite-for-1C-platform. Вторая часть практического руководства (https://infostart.ru/public/2779597): от первого коммита до детерминированного синтаксического гейта на headless-раннере Linux

1 стартмани

03.09.2026    1172    Ninel_S    0    

3

DevOps и автоматизация разработки Тестирование QA Групповая разработка (Git, хранилище) Программист 1С:Предприятие 8 Бесплатно (free)

Четыре года в интеграторе я работал с git и EDT. Git после хранилища полюбил сразу: видно, кто и что менял. С EDT сложнее: тормозит, ошибки при обновлении ERP, автономный сервер внутри него работает только с файловой базой. На новой работе команда захотела перейти на git, я развернул EDT, и оно на второй день разрушило проект при загрузке расширения. Тогда я решил дать команде git с привычным Конфигуратором и инструмент, который за минуту доносит коммит до базы через ibcmd, вместо получасовой загрузки из файлов. На новой работе разрешили ИИ, и я написал это приложение с его помощью: от чтения документации и первого ТЗ до идей в электричке. Впервые за годы снова почувствовал себя творцом, а не закрывателем задач. По дороге приросли выгрузка, объединение и проверка конфигурации по коммитам, YAxUnit и режим MCP-сервера. В статье: схемы, скриншоты, грабли и честный список ограничений. Ссылки пока нет: хочу понять, нужно ли это кому-то, кроме меня.

03.09.2026    10544    KatanaDragon511    28    

39

Linux Групповая разработка (Git, хранилище) Администрирование СУБД Системный администратор Программист 1С 8.3 Бесплатно (free)

Пакетный запуск Конфигуратора 1С на Linux таит опасную ловушку: при критических ошибках утилита DESIGNER завершается с кодом возврата 0 - «всё хорошо». Дефект уходит на продуктив. Мы открываем проект SRE-Suite-for-1C-platform - набор специализированных инструментов для надёжной эксплуатации 1С на Linux: • пятислойный сборочный скрипт с защитой от False Success (BOM, кодировки, lock-файлы, diff с Git) • Мягкая ротация процессов "rphost" через RAS API без обрыва сеансов • EDT ; Конфигуратор: CLI-мост для CI/CD на Node.js • Готовые конфиги logcfg.xml и nethasp.ini для боевого сервера • systemd-шаблоны для фонового мониторинга кластера Проект в активной разработке, лицензия MIT. Ждём ваших тест-репортов и PR.

03.09.2026    1147    Ninel_S    0    

1

Групповая разработка (Git, хранилище) EDT Программист 1С:Предприятие 8 Россия Бесплатно (free)

Синхронизируйте свой проект EDT с хранилищем конфигурации так же легко, как в git клиенте. По кнопке Pull в проект EDT подтягиваются изменения из хранилища, по кнопке Push ваш коммит из git репозитория проекта EDT улетает в хранилище конфигурации.

09.07.2026    6873    DmitryShehovtsev    14    

26
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Brawler 466 10.01.22 00:41 Сейчас в теме
Зачем вам такие большие хранилища? Какая цель у всего этого?
2. pavlov_dv 10.01.22 07:20 Сейчас в теме
Идея интересная, надо попробовать.

У меня похожая задача - залить в git-репозиторий всю историю продуктивного хранилища.
Конфигурация на треть меньше, чем у Вас, но все равно долго. Несколько тысяч коммитов выгружались около месяца :-)
В однопоточном режиме, конечно.
3. artbear 1589 10.01.22 10:48 Сейчас в теме
(0) Интересный набор статей, спасибо.

Насколько я понимаю, остались два вопроса
1 - как же слить все эти выгрузки в одну ветку средствами гита?
2 - есть планы в гитсинк добавить функционал из статей?
4. ardn 859 10.01.22 12:22 Сейчас в теме
(3)
1 - последовательная выгрузка версий в скриптом, ничего выдающегося
2 - сложно, подумаю
5. JohnyDeath 302 11.01.22 08:57 Сейчас в теме
Еще можно попробовать:
1. Использовать tool1CD. Тогда не нужно будет создавать пользователя под каждый поток. Но нужно обеспечить файловый доступ к каталогу хранилища.
2. Создать RAM-диск и выгружать CF на него. Скорее всего просадка в скорости обусловлена именно очередью записи на жесткий диск.

Короткое видео про многопоточную выгрузку в гит от 2016 года
http://xdd.silverbulleters.org/t/mnogopotochnyj-variant-sinhronizaczii-hranilishha-1s/685
6. kamisov 228 16.01.22 10:21 Сейчас в теме
Рекомендую подключиться к хранилищу по HTTP и попробовать сделать то же самое. Должно быть ещё быстрее, как ни странно :)
7. kamisov 228 18.08.22 22:26 Сейчас в теме
Плагин “increment” у гитсинка был включён?

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