В связи с обострением вопросов импортозамещения многие задумываются о переходе на системы, позволяющие заменить зарубежные аналоги, или уже его начали. Мы решили поделиться с вами 7-летним опытом установки и эксплуатации системы Linux + PostgreSQL + «1C» на 300 онлайн-пользователей.          Авторы статьи:          Стрижевский Александр – начальник ИТ-отдела АО «123 авиаремонтный завод»* («123 АРЗ»)          Малышев Дмитрий – разработчик в ВЦ «Раздолье», «1С»-эксперт по технологическим вопросам  *АО «123 АРЗ» - одно из ведущих предприятий по ремонту и техническому обслуживанию транспортных самолётов военной и гражданской авиации России. Широкий спектр услуг с применением передовых технологий, тесное сотрудничество с разработчиками авиационной техники, адекватность потребительскому спросу и высокое качество ремонта – главные приоритеты предоставляемых услуг. Нам доверяют ремонт авиационной техники не только российские, но и зарубежные авиакомпании, расположенные на трёх континентах.          Начнём с опыта установки и эксплуатации системы Linux.          Сегодня использование альтернатив Microsoft не имеет каких-то нерешаемых проблем или серьёзных рисков. Комбинация Linux + PostgreSQL является хорошей платформой для информационной системы на базе программных продуктов «1С», но так было не всегда.          К 2015 году предприятие работало с базами на платформе «1С» 7.7 по складскому учёту. Базы работали на MS SQL 6.5. Покупали тогда бандлом «1С» + SQL под конфигурацию «ЗиК». Затем приобрели программу «1С:Бухгалтерия 8». Поскольку её использовали онлайн всего 10 пользователей, ставить под такую задачу сервер MS SQL было неоправданно дорого. Это послужило тестированием работы «1С:Бухгалтерии 8» на Linux + PostgreSQL. Тесты прошли успешно – всё работало хорошо.          В 2016 году предприятие запустило проект внедрения «1С:ERP», и в этот момент ребром встал вопрос выбора – на каком системном программном обеспечении запускать такую большую и нагруженную систему. Уже тогда наш завод посчитал, что стоимость лицензий SQL и пользовательских лицензий на доступ от Microsoft слишком высока. Учитывая успешный опыт использования PostgreSQL и Linux для работы «1С:Бухгалтерии 8», решили использовать это бесплатное ПО и для запуска «1С:ERP». Как показывает опыт и текущая ситуация, решение было верным, т.к. в настоящий момент благодаря ему нас не заботит решение вопросов импортозамещения в авральном режиме.          С самого начала проекта внедрения «1С:ERP» сразу запускался в комбинации: сервер «1C» + Linux + PostgreSQL. Вначале в системе работало до 40 пользователей и всё было хорошо – время отклика соответствовало ожиданиям. Но когда количество активных пользователей превысило 50, система начала тормозить. Беглый анализ показал, что причиной проблемы стало использование старого «железа» и виртуализации. Тогда было принято решение приобретать новые сервера, которые выбрали по рекомендации интегратора [ВЦ «Раздолье»].          Были приобретены 2 сервера HP со следующими характеристиками: 256 Гб оперативной памяти, диски 2х800 Гб NVME SSD, процессоры 2х12 ядер по 2 потока (48 потоков). Один «железный» сервер выделен под сервер «1С», другой – под PostgreSQL. Серверы соединены каналом в 10 Gb.          На новых серверах решили задействовать не виртуальные машины, а автономные контейнеры в локальной среде (docker'ы). В настоящий момент планируем в дальнейшем использовать системы Kubernetes [открытое программное обеспечение для «оркестровки» контейнеризированных приложений — автоматизации их развёртывания, масштабирования и координации в условиях кластера]. На системе докеров остановились в связи с тем, что она требует меньше дополнительных расходов аппаратных ресурсов и работает быстрее виртуализации. Докеры взаимодействуют друг с другом через индивидуальные ip-адреса и диапазоны портов.          На серверах использовали Centos 7, Postgres Pro, сервера «1С» х64.          «Железный» сервер разделен на 10 doker'ов:          1 докер используется для работы исторических баз: «1С:Бухгалтерия 8», «1С:Общепит», «Метрология».          3 doker'a используются для работы кластера из 3 серверов «1С» с резервированием для рабочей базы «1С:ERP» [сейчас онлайн – 250 пользователей].          1 докер используется для работы тестовой базы «1С:ERP».          2 doker'a используются для работы кластера из 2 серверов «1С» для рабочей базы «1С:Зарплата и управление персоналом 8» [35 пользователей онлайн].          1 докер используется для работы тестовой базы «1С:Зарплата и управление персоналом 8».          1 докер используется для работы базы «Казначейства» на «1С».          1 докер используется как СЛК-сервер для системы «1С:Общепит».          В докерах «1С» обычно используем самые последние платформы с сайта технической поддержки «1С».          Этот сервер также разбит на docker'ы. Под каждый кластер «1С» выделяем отдельный докер на втором сервере.          На сервере стоит версия PostgreSQL с cайта команды Postgres Professional, где есть сборки специалистов для «1С» (не с сайта «1С»). Здесь есть возможность скачать более свежие сборки и релизы «Постгрес».          На старых «железных» серверах продолжили использовать виртуальные машины Linux, на новых – сразу решили использовать doker'ы.          По статистике на разворачивание сервера Linux уходит примерно 1,5 часа.          Разворачивание подсистемы докеров из репозитария на серверах занимает пару минут (см. инструкцию). Сборка образа с использованием docker-файлов занимает 5-10 минут. Мы используем только 2 docker-файла: один – для серверов «1С», второй – для Postgres.          Построенный образ на остальные docker'ы просто копируется. Настроенные docker-файлы с описанием последовательности шагов установки [ставится образ «Линукса», пакеты ПО, пути к дистрибутивам «1С» и Postgres] можно посмотреть в «Приложении».          Если в дальнейшем потребуется разворачивать большое количество докеров, то можно будет использовать Ansible — систему управления конфигурациями, написанную на Python, с использованием декларативного языка разметки для описания конфигураций. Это позволит автоматизировать настройки и развертывание программного обеспечения.          Сопровождают 20 образов докер в нашем случае 2 администратора. Работаем с Docker в консоли. Также использовали GUI-/веб-интерфейс. Для помощи администратору в случае необходимости существуют и красивые «мышкадавы», которые сами работают в докере и помогают управлять другими докерами. Но, в основном, они полезны в случаях, если существует «зоопарк» из десятков или сотен разнонаполненных докеров.          В статье на «Хабре» представлен обзор наиболее заметных на сегодняшний день графических интерфейсов для обслуживания Docker: Portainer Kitematic (Docker Toolbox) Shipyard и т.д. Так как у нас используется всего 2 шаблона докера [один – под «1С», другой – под PostgreSQL] – их администрирование из стандартной консоли из поставки не представляет сложности.         PGAdmin, кстати, тоже запущен в контейнере docker.         Плюс используются утилиты мониторинга linux. Время работы системы 1857 дней.           Обслуживание для докеров с «1С» в основном сводится к перезапуску службы сервера «1С», что занимает 5 секунд. Также используем обрезание журналов регистрации «1С» [Раньше для экономии лицензий использовали отключение спящих сеансов, пока в конфигурации не задействовали настройку отключения спящих сеансов и не сменили её значение с 48 на 10 часов].         Для докеров с PostgreSQL используем обновление статистик, обновление индексов и резервное копирование. Резервное копирование идёт на отдельный «железный» сервер № 3, предназначенный для хранение резервных копий данных.         Ещё выполняется обслуживание Cron'ами (скриптами). Cron-программы [в системах класса UNIX], используются для периодического выполнения заданий в определённое время. Регулярные действия описываются инструкциями, помещёнными в файлы crontab и в специальные каталоги. Выполняются по расписанию.         В нашем случае стоят аппаратные лицензии «1С». Это исторически сложившаяся традиция со времени использования виртуальных машин.         Программные лицензии также могут успешно использоваться в докерах вместо аппаратных.         Сервер лицензирования и СЛК-сервер можно установить в отдельных докерах. И они будут видны в остальных докерах по отдельным IP [используется macvlan сетевой драйвер docker для назначения MAC адрес к виртуальному сетевому интерфейсу каждого контейнера, что делает его похожим на физический сетевой интерфейс, напрямую подключенный к физической сети].         Платформа «1С:Предприятие 8» и конфиугурации «1С:ERP» и «1С:ЗУП» в ходе эксплуатации потребовали оптимизации.         Расскажем о нескольких случаях из практики.         Сложилась ситуация: закрытие периода в «1С:ERP» в базе на MS SQL проходило за 1 час, при этом в базе на PostgreSQL — за 6 часов.         Проблема оказалась комплексной: алгоритмы закрытия месяца кешировали избыточное количество данных, что вело к сильным замедлениям; настройки PostgreSQL были неоптимальны; была ошибка в самой платформе «1С».         К решению приступали параллельно с поддержкой фирмы «1С».         По итогу от «1С» получили рекомендацию по изменению настроек PostgreSQL: «Поскольку в ускоренном расчёте себестоимости самый долгий этап – СкорректироватьСтоимостьСписанияНезавершенногоПроизводства, потому анализ начали с него. Большая часть времени этап выполняется на СУБД. Анализ планов запросов показал следующие проблемы: - Долгое выполнение ANALYZE для временных таблиц. Длительность ANALYZE не коррелирует с размером таблиц. maintenance_work_mem 2GB. Увеличение длительности происходит из-за default_statistics_target = 1000, согласно документации "Чем больше установленное значение, тем больше времени требуется для выполнения ANALYZE, но тем выше может быть качество оценок планировщика. Значение этого параметра по умолчанию — 100". Рекомендуем вернуть значение по умолчанию (100). - Нехватка work_mem. Чаще всего проявляется в случаях, когда необходимо выполнить сортировку или агрегацию для большого числа строк. Из-за нехватки work_mem postgres обращается к диску и выполняет действия на нём, что существенно сказывается на времени выполнения запросов. Текущее значение work_mem 256MB, рекомендуем его увеличить до 512MB или 1GB при наличии возможностей».          Своими силами для поиска проблем производительности мы настроили сбор данных технологического журнала «1С» + логирование в PostgreSQL. Далее – выполнили определение проблемных запросов и корректировку кода в программе «1С:ERP». В качестве навигатора действий поиска и отладки использовали статьи и инструменты с «Инфостарта», GitHub и «Тензор»: Пример пошагового решения проблемы производительности на базе PostgreSQL с картинками; Исправляем проблемы производительности в конфигурации ERP - 7 примеров. Инструменты лежат на GitHub; Визуализации планов запросов PostgreSQL.        Найденные решения заключались в следующем: При закрытии «1С» либо кешировало избыточное количество данных во временные таблицы, либо для них не было подходящих индексов. Исправление заключалось в преобразовании типовых временных таблиц в свои с меньшим объемом данных и создании подходящих индексов; Также была зарегистрирована ошибка в платформе «1С», связанная с отсутствием подходящего индекса для внутриплатформенного метода апдейта данных.         Ошибка 60001790 исправлена и уже опубликован релиз платформы, содержащий исправление.          В итоге мы достигли ускорения закрытия периода в «1С:ERP» с 6 до 1,5 часов.         В 8.3.19 столкнулись с падением фоновых заданий, в 8.3.20 – отладка не работала с фоновыми процессами, в 8.3.21 – падает сама «1С» при работе на старых машинах с ОС Windows XP (ошибка 60003943).         Несколько раз при обновлении падала конфигурация «1С». Не могла завершиться транзакция. Откатили её в таблице config [некоторые решения на форумах для MS SQL также подходят для PostgreSQL].         Реализации RLS [ограничение прав доступа в «1С» на уровне записей] под PostgreSQL была недостаточно производительной. Устранили эту проблему так же по рекомендациям фирмы «1С». Суть: выгрузка ролей в файлы и глобальной заменой запросов ограничений, затем загрузка файлов обратно. Делали так при каждом обновлении «1С:ЗУП», начиная с платформы 8.3.16.         В настоящий момент система RLS в платформе и конфигурации «1С:ЗУП» работает под PostgersSQL с нормальной производительностью. В текущих версиях платформы «1С:Предприятие 8» [начиная с 8.3.20] механизм RLS уже оптимизирован и замены в «1С:ЗУП» не требуется. Изменилась трансляция запросов, они стали быстрее обрабатываться в Postgres'е.        В настоящее время использование свободного ПО для работы «1С:ERP» – штатная ситуация. Платформа и программные продукты «1С» развиваются в сторону адаптации и стабильной работы со связкой Linux и PostgreSQL. Сейчас можно смело рекомендовать использовать это свободное программное обеспечение для работы «1С». Тем не менее есть некоторые направления, по которым от «1С» хотелось бы улучшения контента.        Ставим последнюю версию платформы «1С» PG main.conf: # Memory Settings shared_buffers = 32GB work_mem = 512MB maintenance_work_mem = 2GB effective_cache_size = 96GB PG stat.conf: default_statistics_target = 100 PG log.conf:auto_explain.log_min_duration = '20s'           В конфигурации мониторинга загружаем ТЖ:          Находим по временной метке запрос в логе PostgreSQL и через обработку КонверторЗапросовSQL_в_«1С» получаем красивый план: см. Explain PostgreSQL (tensor.ru)         Далее по строке ТЖ получаем:          В модуле Общий модуль РасчетСебестоимостиРешениеСЛУ: Функция ТекстДляРешенияСЛУ_ДополнительныеРасходы(ПараметрыРасчета = Неопределено) ... ТекстыЗапросов.Добавить(РасчетСебестоимостиКорректировкаСтоимости.ТекстСуммыПрочихРасходов()); ...  Далее ТекстСуммыПрочихРасходов() ищем похожее на:          И находим: ... |ПОМЕСТИТЬ СуммыРасходов |ИЗ | (ВЫБРАТЬ ... | | ОБЪЕДИНИТЬ ВСЕ | | ВЫБРАТЬ ... | ИЗ | ВТКэшРасчетныеОборотыПрочиеРасходы КАК ДД | | ЛЕВОЕ СОЕДИНЕНИЕ РассчитанныеДокументы КАК РассчитанныеДокументы | ПО РассчитанныеДокументы.Период = ДД.Период | И РассчитанныеДокументы.Регистратор = ДД.Регистратор ... | ЛЕВОЕ СОЕДИНЕНИЕ ВТКэшРасчетныеОборотыСебестоимостьТоваров КАК ДвиженияСебестоимости | ПО ДвиженияСебестоимости.Период = ДД.Период | И ДвиженияСебестоимости.Регистратор = ДД.Регистратор | И ДвиженияСебестоимости.ИдентификаторФинЗаписи = ДД.ИдентификаторФинЗаписи ...         В протоколе закрытия месяца: 35. Партионный учет: ПодготовкаДанныхДляРешенияСЛУ_ДополнительныеРасходы Начало этапа: 08.09.2022 11:16:17, длительность: 3 мин. 30,391 сек. (11,32%) Время от начала расчета до начала этапа: 10 мин. 55 сек. Сформированы временные таблицы (размер / время (% времени этапа) / уточнение / исходные таблицы): ... - СуммыРасходов: - 2 409 / 3 мин. 30,148 сек. (99,88%) ... 57. Партионный учет: ПодготовкаДанныхДляРешенияСЛУПостатейныеРасходы Начало этапа: 08.09.2022 11:23:19, длительность: 3 мин. 43,8 сек. (12,04%) Время от начала расчета до начала этапа: 17 мин. 57 сек. Сформированы временные таблицы (размер / время (% времени этапа) / уточнение / исходные таблицы): … - СуммыРасходов: - 2 409 / 3 мин. 36,445 сек. (96,71%) … Вот ОНО! Продолжение – в следующей серии... По плану – ссылка.           Есть рекомендация:         Создаём временную таблицу с индексацией по полям, по которым соединяются таблицы: |ВЫБРАТЬ | ДД.Период КАК Период, | ДД.Регистратор КАК Регистратор, | ДД.ИдентификаторФинЗаписи КАК ИдентификаторФинЗаписи, | ДД.НастройкаХозяйственнойОперации КАК НастройкаХозяйственнойОперации, | ДД.ХозяйственнаяОперация КАК ХозяйственнаяОперация, | ДД.АналитикаУчетаНоменклатуры КАК АналитикаУчетаНоменклатуры, | ДД.РазделУчета КАК РазделУчета, | ДД.ВидЗапасов КАК ВидЗапасов, | ДД.Организация КАК Организация, | ДД.Партия КАК Партия, | ДД.АналитикаУчетаПартий КАК АналитикаУчетаПартий, | ДД.АналитикаФинансовогоУчета КАК АналитикаФинансовогоУчета, | ДД.ВидДеятельностиНДС КАК ВидДеятельностиНДС | |ПОМЕСТИТЬ ВТРасчетныеОборотыСебестоимостьТоваров3557 | | ИЗ | ВТКэшРасчетныеОборотыСебестоимостьТоваров КАК ДД | |ИНДЕКСИРОВАТЬ ПО | Период, | Регистратор, | ИдентификаторФинЗаписи, | НастройкаХозяйственнойОперации, | ХозяйственнаяОперация   Результат – ссылка.            Итого: 209 721.150 / 8.420 = 24907,5, ускорение примерно в 25000 раз.  Dockerfile.21 # vim:set ft=dockerfile: FROM sav/basicsystem1c-7:build MAINTAINER sav ARG SERVER_1C_VERSION COPY ./distr/setup-full-${SERVER_1C_VERSION}-x86_64.run /tmp/ RUN ./tmp/setup-full-${SERVER_1C_VERSION}-x86_64.run --unattendedmodeui minimalWithDialogs --mode unattended --enable-components server,config_storage_server,ru \ && rm -rf /tmp/* VOLUME /home/usr1cv8 VOLUME /tmp/.aksusb # && echo "SystemLanguage=RU" > /opt/1cv8/conf/conf.cfg \ # && chown -R usr1cv8:grp1cv8 /opt/1cv8 \ #RUN mkdir -p /home/usr1cv8/.1cv8/1C/1cv8/conf/ #COPY logcfg.xml /home/usr1cv8/.1cv8/1C/1cv8/conf/ #RUN chown -R usr1cv8:grp1cv8 /home/usr1cv8 COPY docker-entrypoint.sh.18 /docker-entrypoint.sh ENTRYPOINT ["/docker-entrypoint.sh"] EXPOSE 1540-1541 1560-1591 CMD ["ragent"] Docker-compose.yml version: '2.2' networks: macvlan1: external: name: macvlan1 netcont0: external: name: netcont0 services: 1C: build: context: ../Docker/srv-1C dockerfile: Dockerfile args: - SERVER_1C_VERSION=${VERSION_1C} image: sav/srv-1c:${VERSION_1C} container_name: srv-1C-${ContainerName} hostname: srv-1C-${ContainerName} networks: macvlan1: ipv4_address: $srv1C_IP1 netcont0: ipv4_address: $srv1C_IP2 dns_opt: - ndots:1 volumes: - /etc/localtime:/etc/localtime:ro - /tmp/.aksusb:/tmp/.aksusb - /opt/1C/home/${ContainerName}:/home/usr1cv8 - /opt/1C/ХранилищеФайлов/N1:/home/usr1cv8/ХранилищеФайлов # - /etc/hasplm/nethasp.ini:/etc/nethasp.ini:ro mem_limit: $MEM_LIMIT # lscpu | grep node1 cpuset: $CPU_SET tmpfs: /tmp:rw,exec,strictatime extra_hosts: - srv-db1C-${ContainerName}:$srvDB_IP1 restart: always environment: - SERVER_1C_VERSION=${VERSION_1C} - DEBUG=-debug - TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES=${TCMALLOC_THREAD_CACHE}