Оглавление
- Снижение производительности 1С:Документооборот после обновления
- Инфраструктура
- Проблемы глазами пользователей
- Этапы работ
- Проведение экспертного аудита
- Решение обнаруженных проблем
- Оценка достаточности мощности оборудования
- RLS — решение задачи избыточных записей в регистре ключей ограничений. Спецразрешения — таблицы ДО/ПОСЛЕ
- Высокая загрузка 1С-сервера
- Достижение целевого показателя APDEX и расчёт экономической значимости ускорения работы персонала с 1С
Снижение производительности 1С:Документооборот после обновления
Наш клиент — крупное предприятие, выпускающее авиационные двигатели. Данное предприятие использует в работе программный продукт «1С:Документооборот» (далее ДО). Нашей первоначальной задачей было провести обновление данного программного продукта с релиза 2.1.19.22 до 2.1.28.14.
Существенными сложностями при обновлении были:
- Наличие большого количества незадокументированных доработок, причем часть дополнительного кода не имела никаких опознавательных комментариев.
- Предыдущее обновление было выполнено некорректно. Это заключалось в том, что в доставшемся нам релизе оставались строки кода из предыдущих релизов, т. е. однозначно сказать, что имеем дело именно с релизом 2.1.19.22 мы не могли.
Доработки клиента в первую очередь были связаны с наличием нестандартных бизнес-процессов работы с документами, которых не было в типовой функциональности ДО.
С задачей обновления мы справились успешно, хотя надо заметить, что процесс был нетривиальным за счет вышеуказанных сложностей в виде артефактов от некорректных предыдущих обновлений.
После обновления мы столкнулись с проблемой значительного снижения производительности информационной системы (далее ИС). Перед нами встала задача по оптимизации. Клиент попросил нас:
- Провести аудит производительности.
- Найти узкие места.
- Выдать рекомендации по настройке ИС для достижения показателей требуемых для нормального быстродействия.
Инфраструктура
Кластер 1С состоит из одного рабочего сервера, одновременно являющегося центральным.
Важно отметить, что часто обновления релиза типового решения требует также и обновления платформы «1С:Предприятие». В нашем случае релиз платформы был обновлен с 8.3.16.1973 до 8.3.20.1613.
Клиент использует отдельный сервер на базе Microsoft SQL 2016. В ходе работы мы рекомендовали скачать и установить все необходимые обновления для него, с чем Заказчик справился самостоятельно.
Отметим, что количество одновременно работающих пользователей на начало проекта в пике достигало 2 500. На этапе завершения проекта эта цифра увеличилась до 3 500.
Объем базы около 2 ТБ.
Количество операций, по которым собиралась информация по производительности, на начало проекта достигало более 50 тысяч в день. На момент завершения проекта происходило более 70 тыс операций в день.
В топ 3 операций входят:
- Выполнение команды «Ознакомился» — более 7 тысяч операций.
- Выполнение команды «Записать» в справочнике «Внутренний документ» — более 6,3 тысяч операций.
- Выполнение команды «Исполнено» — более 3,9 тысяч операций.
Дополнительную нагрузку на систему дает регламентная операция по обмену с ЭДО, которая происходит регулярно каждые 30 мин.
Сервера 1С и SQL являются физическими, виртуализация не используется.
По соглашению с Клиентом мы не можем описать модели и точные параметры рабочих серверов. Поэтому ограничимся только общими сведениями:
Назначение |
Процессор |
Память (ГБ) |
|
---|---|---|---|
Ядер |
ГГц |
||
Сервер приложений 1С | 2 × 18 |
3 |
128 |
Сервер СУБД | 2 × 18 |
3 |
128 |
Важно отметить что для достижения результата мы рекомендовали заказчику на первом этапе увеличить оперативную память на сервере 1С и на сервер SQL до 384 ГБ, что и было сделано Заказчиком. Остальные параметры оборудования в рамках проекта не менялись. Причины рекомендации по увеличению памяти будут рассмотрены ниже.
Дисковая подсистема: 2хNVMe SSD с интерфейсом PCIe3.0, скорость чтения до 3.5 GB/s, скорость записи до 3.2 GB/s, объединенных в RAID 1.
Проблемы глазами пользователей
Проблемы с быстродействием ИС были и до обновления 1С:ДО. Однако, после обновления они стали усиливаться.
До обновления пользователи жаловались на проблемы с производительностью в определенные часы: утром с 9:00 до 10:00, в обед с 12:00 до 13:00 и ближе к концу рабочего дня с 16:00 до 17:00.
После обновления со слов пользователей упала общая производительность, в нагруженные часы производительность падала до неприемлемого уровня. Особенно тяжело было работать со справочниками «Внутренние документы» и «Файлы», а также согласовывать и утверждать документы.
Этапы работ
Проект оптимизации выполнялся в два этапа.
На первом этапе мы работали своими силами и нам удалось частично снять проблему снижения общей производительности ИС.
На втором этапе был инициирован проект совместно с Центром Корпоративной Технической Поддержки (далее ЦКТП) для окончательного приведения производительности до уровня требуемого Заказчиком. В рамках проекта ЦКТП фирма «1С» осуществляла методологическую технологическую поддержку проводимых работ и контролировала правильность решений и полученных результатов.
Проведение экспертного аудита
Определение ключевых операций и определение целевых показателей производительности
На первом этапе проекта конкретные ключевые операции не рассматривались, так как не были известны и как было сказано выше система демонстрировала неприемлемый уровень производительности и работать с ней было невозможно. Поэтому необходимо было исследовать все, что происходило с системой и выделить тяжелые запросы, длительные вызовы, о чем будет рассказано ниже.
На втором этапе с помощью Заказчика выделили 4 ключевые операции, которые мы замеряли по системе APDEX, и постарались оптимизировать. Для начала напомним читателям, что такое APDEX.
APDEX (Application Performance Index) — индекс производительности приложений, который считается по формуле:
APDEX = (NS + NT / 2) / N
где:
N — общее количество выполнений данной операции;
NS — количество выполнений с временем отклика от 0 до Т;
NT — количество выполнений с временем отклика от T до 4T;
T — время операции, которое удовлетворяет клиента.
Ключевая операция | APDEX на начало 2-го этапа проекта (среднее за неделю) |
APDEX желаемый |
---|---|---|
Внутренние документы Открытие формы: Список с папками | 0,636 |
0,865 |
Файлы Выполнение команды: Записать | 0,618 |
0,75 |
Внутренние документы Выполнение команды: Создать | 0,727 |
0,8 |
Утверждение Выполнение команды: Утверждено | 0,751 |
0,929 |
Если посчитать APDEX по среднему (по больнице), то до обновления итоговый APDEX был равен 0,912, после обновления он стал равен 0,788.
После первого этапа оптимизации APDEX стал равен 0,88, после второго этапа 0,965.
Установка рекомендуемых параметров сервера 1С и SQL
Первым шагом практически любого проекта по оптимизации является проверка настройки параметров сервера 1С и SQL согласно чек-листу от компании «1С»:
- Для сервера 1С — its.1c.ru/db/metod8dev/content/5899/hdoc.
- Для SQL сервера — its.1c.ru/db/metod8dev/content/5904/hdoc.
Отклонения от рекомендованных настроек включали:
- Отсутствие сбора минимального Технологического журнала (далее ТЖ).
- Сеансовые данные не были вынесены на отдельный производительный диск.
- На MS SQL не были установлены все рекомендуемые обновления.
- Не были настроены Дефрагментация индексов и Реиндексация таблиц базы данных.
- Опция Database instant file initialization была отключена.
- Опция Lock pages in memory была отключена.
- Минимальный и максимальный объем доступной памяти MS SQL не были установлены.
- TEMPDB не был вынесен на отдельный производительный диск.
- SQL файлы данных и файлы журналов были расположены на одном диске.
Все найденные отклонения от рекомендованных настроек были откорректированы специалистами Заказчика.
Рекомендуем не пренебрегать этим пунктом работ, т. к. некоторые из настроек и рекомендаций существенно влияют на производительность ИС в целом.
Счетчики производительности
Следующим шагом работ было изучение нагрузки на оборудование серверов с помощью утилиты perfmon.
Чтобы не захламлять текст приведем только действительно полезные с нашей точки зрения графики:
- Доступная оперативная память (100% — свободная, 0% — полностью загружена):
Пилообразный профиль графика может говорить о проблемах с оперативной памятью:
- Утечки памяти: если минимумы графика со временем уменьшаются и не поднимаются до прежних уровней, это может указывать на утечку памяти в системе.
- Недостаточно памяти: если минимумы графика продолжают уменьшаться, а не растут вверх, это также может указывать на то, что в системе недостаточно оперативной памяти для удовлетворения требований запущенных программ.
В данном случае видно что пики памяти как раз продолжают расти (график перевёрнутый), что говорит о возможности наличия обеих проблем.
- Нагрузка на дисковую подсистему:
Такая картина нагрузки на диски была характерна для моментов, когда система сильно тормозила, что говорило об очевидных проблемах каких-то регламентных операций с записью на диск.
Проблем с нагрузкой на процессор или чрезмерной нагрузкой на сеть выявлено не было.
Анализ ТЖ
Прежде всего начинаем искать тяжелые запросы по времени исполнения.
Для анализа ТЖ для выявления тяжелых запросов по времени использовался отбор по event=DBMSSQL.
Мы производили анализ логов с помощью следующего регулярного выражения. Разберем его составные части:
cat “имя файла”.log | \
grep -P "DBMSSQL.*Sql" | \ - ищем ключевые слова DBMSSQL и Sql
perl -pe 's/^\d+:\d+.\d+-//g' | \ - удаляем время события
perl -pe 's/,DBMSSQL,.*Sql=/,Sql=/g' | \ - удаляем все от DBMSSQL до Sql
perl -pe 's/p_0:.*//g' | \ - удаляем все параметры запроса
perl -pe 's/,Context=.*//g' | \ - контекст тоже удаляем
perl -pe 's/\w+-\w+-\w+-\w+-\w+/{GUID}/g' | \ - заменяем строки типа …-...-...-...-... на {GUID}
perl -pe 's/\(\d+\)/({NUM})/g' | \ - заменяем (число) на ({NUM})
perl -pe 's/tt\d+/{TempTable}/g' | \ - заменяем названия временных таблиц вида ttчисло на {TempTable}
awk -F',Sql=' '{sum[$2]+=$1; count[$2]+=1;} END {for(i in sum) {print sum[i] " " sum[i]/count[i] " " count[i] " " i}}' | \ - суммируем время выполнения операции (по разделителю ‘,Sql=’)
sort -rnb -k1 | \ - сортируем по времени по убыванию
head -n 20 > top_20_queries.txt \ - выбираем топ 20
Естественно, что в ходе проекта получаемый список тяжелых запросов сильно менялся. Чуть позже в разделе про решение проблем мы расскажем о наиболее интересных случаях оптимизации.
После того, как мы выделили список самых тяжелых запросов, один из самых нагружающих систему был запрос из формы Справочник.ВнутренниеДокументы.ФормаСписка.
Беглый анализ этого запроса показал, что всего у 10 пользователей из 1711 активных на тот момент, этот запрос имел длительность более 10 сек.
Дополнительно мы проверили гипотезу: возможно, во время запросов данных пользователей система «тормозила» и была чем-то нагружена? Однако подтверждения этой гипотезе не нашли.
Далее мы проверили гипотезу что, возможно, у вышеуказанных пользователей установлены некорректные ограничения по RLS.
Мы посмотрели, есть ли запросы с одним и тем же контекстом, но с разным временем исполнения по Справочник.ВнутренниеДокументы.ФормаСписка.
Далее посмотрели, что за пользователь страдал от длительного открытия как один из типичных представителей.
Посмотрим на часть текста его запроса:
Профиль ограничений этого пользователя содержит несколько видов пересекающихся ограничений RLS, который можно определить наличием конструкций EXISTS, DUMMY.
Далее, мы нашли того, у кого эта же форма быстро открывается, и посмотрели его запрос.
Мы видим, что приписка RLS отсутствует — запрос намного более простой:
Таким образом, настройки профиля ограничений очень существенно влияют на быстродействие работы ПП у пользователей. Если посмотреть на время выполнения, то запрос с RLS занимает 18 сек, без RLS 7 сек.
Планы запросов
Еще один кейс, который может быть полезным при анализе проблем производительности — изучение планов запросов. Напомним, что для получения планов в ТЖ достаточно добавить строку <plansql/> в logcfg.xml.
Важно! Данную настройку следует включать кратковременно, только для анализа конкретного запроса, т.к. сбор планов запросов сильно увеличивает объем создаваемого ТЖ. Также отметим что, вместо этого предпочтительнее использовать Расширенные события в MS SQL.
Рассмотрим часть Плана запроса на открытие формы ФормаСпискаСПапками:
| | |--Nested Loops(Inner Join, OUTER REFERENCES:([T7].[_Fld9358RRef])) //<--1 1495490, 111061, 5.66, 0.00313, <0.000168>, 24, {2.86}, 1E+003, | | |--Clustered Index Seek(OBJECT:([docmng].[dbo].[_InfoRg9356].[_InfoRg9356_1] AS [T7]), SEEK:([T7].[_Fld13750]=[@P46] AND [T7].[_Fld9357_TYPE]=0x08 AND [T7].[_Fld9357_RTRef]=0x00000023 AND [T7].[_Fld9357_RRRef]=[docmng].[dbo].[_InfoRg6983].[_Fld7320RRef] AS [T1].[_Fld7320RRef]), WHERE:([docmng].[dbo].[_InfoRg9356].[_Fld9361] AS [T7].[_Fld9361]=0x00) ORDERED FORWARD) //-->1 //<--3 426, 1495490, 1, 0.00313, <0.000158>, 9, {1.03}, 5.81E+003, | | |--Index Seek(OBJECT:([docmng].[dbo].[_InfoRg9437].[_InfoRg9437_2] AS [T8]), SEEK:([T8].[_Fld13750]=[@P47] AND [T8].[_Fld9439RRef]=[@P48] AND [T8].[_Fld9438RRef]=[docmng].[dbo].[_InfoRg9356].[_Fld9358RRef] AS [T7].[_Fld9358RRef]) ORDERED FORWARD) //-->3
InfoRg9356 — это РегистрСведений.ДескрипторыДляОбъектов.
Мы видим, что вроде бы используется индексный поиск (Clustered Index Seek) однако все портит дополнительное условие по полю ДескрипторыДляОбъектов.Ресурс. Отключен (WHERE:([docmng].[dbo].[_InfoRg9356].[_Fld9361]), которое по сути является сканированием и тем тяжелее, чем больше значений выдает условие WHERE.
В нашем случае это поле имеет тип булево, поэтому является низкоселективным, что де-факто приводит к сканированию всей таблицы. В результате этого оператора получается ~ 1,5 млн записей (количество строк — первое число в строке 3 листинга выше). Этот результат далее соединяется вложенными циклами (Nested Loops) с таблицей ПраваПоДескрипторамДоступаОбъектов и т. к. в верхней таблице много записей, то вложенные циклы отрабатывают очень долго.
Предположительно, это может быть архитектурной недоработкой в системе, т. к. присутствие этого поля в регистре нам видится бессмысленным — вручную управлять этим полем в огромном массиве данных затруднительно, а групповых изменений этого поля мы не нашли.
Важно! Заметим, что в 1С:ДО 3.0 это поле в регистре ДескрипторыДляОбъектов отсутствует.
Решение обнаруженных проблем
Настройки программы ДО
Следует отметить, что огромное значение для производительности любой системы имеет настройка параметров конфигурации. В этом разделе мы скомпоновали самый важные из них для 1С:ДО 2.1. Хотя иногда кажется, что они очевидны, практически каждую из этих настроек мы так или иначе «ловили» в ходе нашего проекта.
Общие настройки конфигурации
- Версионирование — использовать минимально и предельно осторожно в нагруженных базах. Хранить данные нужно как можно меньше и точно не бессрочно. Причиной этого является то, что платформа 1С хранит версии не как список отличий, а как полноценную запись в справочнике со всеми полями. Поэтому размер таблицы с версионированием растет очень быстро. В нашем проекте версии основных документов хранились полгода/год, мы уменьшили эту границу до 1 и 3 месяцев.
- Оценка производительности — включать. Включение этого флага позволяет Эксперту в рамках проектов по оптимизации иметь базу для объективного сравнения показателей, понимать их динамику и приоритет улучшения. К сожалению, на субъективные показатели оценки производительности, которые дают пользователи в большинстве случаев положиться нельзя.
- Полнотекстовый поиск — стараться не включать. Если все-таки нужно включать, то необходимо явно ограничивать список объектов и полей, которые нужно включать в индекс полнотекстового поиска.
- Электронные подписи — без необходимости не включать. Электронные подписи по какой-то причине проверяются с этой настройкой даже если ни одна Электронная подпись не зарегистрирована и не настроена.
Настройки прав
- Разрезы доступа — использовать очень аккуратно.
Основное правило — чем меньше, тем лучше.
С другой стороны, при огромном количестве доступных документов начинается деградация, поэтому включение разрезов ограничивающих доступ, например, по Организации или Подразделению может сильно помочь. - Спец. разрешения — стараться не использовать.
Спец. разрешения в 1С:ДО накладываются поверх стандартных ограничений и по факту отменяют их. Неправильная их настройка у клиента была одним из основных факторов торможения RLS. - Протоколировать работу пользователей — стараться не использовать.
При включении эта настройка создает вполне ощутимую нагрузку на систему.
Настройка документов
- Ограничивать доступность полей по состоянию — стараться не включать вообще.
- Категории документов — рекомендуется использовать только небольшим компаниям. Крупным компаниям включать настоятельно не рекомендуем.
- Связи документов — без необходимости не включать.
- Резолюции — без необходимости не включать.
- Визы — без необходимости не включать.
Настройка работы с файлами
- Использование автошаблонов — без необходимости не включать.
При включенной настройке система каждый раз при создании новых документов вызывает компоненты MS Office, что конечно же замедляет открытие. - Автоматически очищать устаревшие версии — включать обязательно.
- Очищать данные для полнотекстового поиска — если полнотекстовый поиск включен, то необходимо включать этот параметр обязательно.
Настройка начальной страницы
- Все пункты настраивать под конкретного пользователя.
Особо нагружающие виджеты:- Текущие дела.
- Задачи мне.
- Рабочий стол руководителя — устанавливать минимальному количеству пользователей.
- Список последних — обновляется каждый раз после открытия любого документа (и много еще когда).
Рекомендуем в коде (в пользовательском режиме нельзя) ограничивать количество последних и вызов функции осуществлять в привилегированном режиме.
- Для всех форм рекомендуется либо вообще отключить автообновление либо сделать автообновление минимум через 300 сек (по умолчанию 60 сек).
Политики доступа
- На корневых элементах — использовать профиль «Все пользователи» запрещено.
- Далее по веткам — профиль «Все пользователи» нигде не рекомендуется оставлять.
- Все права должны быть максимально конкретными.
- Регламентное задание «Расчет прав длительный» рекомендуется выполнять в ночное время.
Дополнительные реквизиты и свойства
Каждый доп. реквизит или свойство — это небольшое, но торможение, поэтому необходимо использовать их очень разумно.
Документы с 10+ дополнительными реквизитами можно использовать только если их формируется совсем немного. Если доп. реквизиты нужны в часто используемые документы — добавление ТОЛЬКО через конфигуратор.
На проекте был вид документа с 50+ доп. реквизитами, который открывался очень долго (относительно других видов).
Тома хранения файлов
- Сильно не рекомендуется размещать тома документов на компьютере отличном от сервера (т. е. документы не должны «гулять» по сети).
- Под документы текущего года крайне рекомендуется выделять отдельный том и отдельный диск, быстрый на запись (на текущий момент желательно SSD NVME M.2). Под документы других лет рекомендуется использовать менее дорогие, быстрые на произвольное чтение диски.
Персональные настройки
- Настройки основного каталога:
Максимальный объем — минимум 1 000 (по умолчанию 100).
Удалять при завершении редактирования — ВЫКЛ.
Очищать через — 7 дней! (ну или любое другое небольшое число до 30). - Разное:
Интервал напоминаний — чем больше, тем лучше.
Список «Задачи мне» — если компьютер пользователя слабый, то использовать «Обычный».
Оценка достаточности мощности оборудования
Загрузка оперативной памяти
Рассмотрим собранные данные по Монитору ресурсов и обратим внимание на ситуацию с дисковой подсистемой на SQL-сервере.
На следующем изображении видно, что суммарная очередь обращений к tempdb на чтение 3 300 кбайт/с и на запись 9 400 кбайт/сек значительно выше, чем очередь обращений к основному файлу с данными — 2 000 кбайт/сек и 3 900 кбайт/сек соответственно:
Данная ситуация говорит о том, что tempdb сильно перегружен и SQL-сервер постоянно свопит информацию на диск. Причиной этого, как правило, является острая нехватка оперативной памяти.
На скриншоте ниже видно, что всю имеющуюся оперативную память занял процесс службы SQL-сервера. В чек-листе по настройке SQL-сервера указано, что следует установить ограничения на максимальный размер оперативной памяти, выделенной под SQL-сервер. Иначе мы увидим деградацию быстродействия операционной системы, страдающей от нехватки памяти, что, как видим, и происходит:
Рассмотрим состояние счетчика PLE (page life expectancy) на сервере SQL (techcommunity.microsoft.com/t5/sql-server-support/sql-server-page-life-expectancy-ple/ba-p/318572).
Этот счетчик показывает время жизни страницы в оперативной памяти (минимальное количество времени в секундах, в течение которого страница будет находиться в буферном пуле на этом узле NUMA без ссылок). Считается нормальным минимальное значение счетчика PLE, рассчитанное по формуле DataCacheSizeInGB / 4GB × 300, что для рассматриваемого сервера составляет 9 600 секунд. Его меньшие значения указывают, что серверу SQL недостаточно памяти:
По графику видно, что значение PLE в среднем 7 510, минимум 4 768. Адекватное же значение (9 600 и более) счетчик имеет не более трети от времени измерения.
Счетчик PLE подтверждает вышеприведенные выводы по страничному обмену. Из-за нехватки памяти происходит свопирование данных на диске, на графике — ступенька.
Аналогичная ситуация с чрезмерной утилизацией памяти происходила и на сервере 1С.
Мы рекомендовали клиенту увеличить объем оперативной памяти по следующей методике.
В рассматриваемый период времени количество активных сеансов пользователей системы составляло примерно 2 625.
Примерный расход оперативной памяти на сеанс был определен как 150 МБ. Таким образом, 150 × 2 625 = 394 ГБ — необходимый для этого количества активных пользователей объем памяти сервера SQL.
Отметим, что объем располагаемой оперативной памяти на серверах 1С и SQL системы изначально был — 128 ГБ.
Следовательно, для стабильной работы системы требовалось увеличение объема памяти сервера SQL и сервера 1С в 3 раза.
Клиент нарастил оперативную память в окончании первой фазы, что позволили поднять средний APDEX примерно на 5–10%.
Загрузка дисковой подсистемы сервера 1С
Согласно Мониторинга ресурсов основную нагрузку на диски создают сеансовые данные (которые прячутся под System и это видно на скриншоте ниже: процесс srvinfo) — в 3,25 раза выше (2 900 тыс./890 тыс.), чем работа самого сервера 1С. Также систему сильно замедляет и загрузка файлов в Документооборот в папку C:\StorageDocMng\:
Мы рекомендовали клиенту сеансовые данные вынести на отдельный диск (желательно RAM). Аналогичную рекомендацию мы дали и для tempdb для SQL сервера. Данные рекомендации применили в конце первого этапа оптимизации.
Также рассмотрим один примечательный кейс, связанный с дисками. На скриншоте ниже представлены счетчики «Обмен стр./с» (желтым) и «Средняя длина очереди к диску» (фиолетовым) на сервере 1С в один из дней с 12:58 по 13:16:
В аналогичное время на сервере SQL те же счетчики диска «Обмен стр./с» (голубым) и «Средняя длина очереди к диску» (желтым) показаны на следующем изображении:
В дополнении к этому в этот же период идет высокая нагрузка по сети:
И еще дополнительно идет запись на диск на сервере 1С:
После сопоставления всех фактов и интервьюирования администратора выяснилась следующая картина:
- В 12:10 начинает создаваться полный бэкап базы данных.
- Примерно к 13:00 регламентное задание заканчивает выполнение и созданный бэкап начинает копироваться по сети на диск E: сервера 1С.
- Далее этот файл копируется на сервер бэкапов.
Объективных причин зачем в рабочее время создается полный бэкап базы, а затем еще и копируется на сервер 1С не было, поэтому оставили только ночное создание бэкапа, а копирование на сервер 1С отменили.
Во время расследования была выявлена еще одна регламентная операция, нагружающая систему, от которой было рекомендовано отказаться в рабочее время — Обновление очереди прав доступа. Обновление прав было настроено с 15:38 и выполнялось до 17:34:
В это время APDEX падал на 15–20%.
Клиент перенес данную регламентную операцию на ночь в середине первого этапа, однако остался недоволен, по причине того, что это тормозило работу по заведению новых пользователей в 1С:ДО. К сожалению эти операции в 1С:ДО неразрывно связаны. Решение данной проблемы отложили на второй этап оптимизации и оно будет описано ниже.
Высокая загрузка SQL-сервера (решение задачи тяжелых запросов)
Как найти топ запросов с помощью регулярного выражения описано выше, но это, как говорится, только начало пути, ибо далее следует более сложная задача — нахождения контекстов этих запросов и нахождения причин не оптимальности. Рассмотрим пару примеров того, как это сделать:
- Первый запрос в топе:
51.837.094 2934 256.209 "SELECTT1._Fld9556RRef,<line>T1._Fld9559,<line>T1._Fld9561,<line>T2._OwnerIDRRef,<line>T2._Fld144,<line>T3._Code,<line>T3._Fld800_TYPE,<line>T3._Fld800_RTRef,<line>T3._Fld800_RRRef<line>FROM dbo._InfoRg9555 T1<line>LEFT OUTER JOIN dbo._Reference27 T2<line>ON (T1._Fld9556RRef = T2._IDRRef) AND (T2._Fld13750 = ?)<line>LEFT OUTER JOIN dbo._Reference70 T3<line>ON (T2._OwnerIDRRef = T3._IDRRef) AND (T3._Fld13750 = ?)<line>WHERE ((T1._Fld13750 = ?)) AND ((T1._Fld9563 = ?) AND (T1._Fld9557 = ?))<line>
Находим контекст этого запроса:
НайденныеСвойства = РаботаСФайламиСлужебныйВызовСервера.НайтиВРегистреПоПути(...);ОбщийМодуль.РаботаСФайламиСлужебныйВызовСервера.Модуль : 1997 : РезультатЗапроса = ЗапросВРегистр.Выполнить();
Восстанавливаем полную логику — зачем и откуда вызывается модуль: работа с кэшем файлов в рамках работы с файлами. Дальнейший разбор кейса смотри в разделе статьи «Временное хранилище файлов».
- Второй запрос в топе:
681.253.781 256.689 2.654 "SELECTT1._Fld11173_TYPE,<line>T1._Fld11173_S,<line>T1._Fld11173_RTRef,<line>T1._Fld11173_RRRef<line>FROM dbo._InfoRg11172 T1<line>WHERE ((T1._Fld13750 = ?)) AND ((T1._Fld11174 = ?) AND (T1._Fld11175 = ?))<line>
Находим контекст этого запроса:
НовоеЗначениеРеквизита = ПолучитьРеквизитИзТаблицыАСФЗД(СтрПЗ, ОбъектИС, ТаблицаРеквизФЗД, ТекИндексСтроки, МассОбщийМодуль.ФЗД_Сервер.Модуль : 1565 : РеквизитДанные = ПолучитьОбъектПоIdАСФЗД(СтрокаРеквизита.ValueIDType,
Восстанавливаем полную логику — зачем и откуда вызывается модуль: модуль вызывается в момент регламентного задания интеграции с АС ФЗД и выполняется каждые 5 мин. Дальнейший разбор кейса смотри в разделе статьи «Виджеты».
- Третий запрос в топе:
INSERT INTO #{TempTable} WITH(TABLOCK) (_Q_001_F_000RRef, _Q_001_F_001, _Q_001_F_002, _Q_001_F_003, _Q_001_F_004, _Q_001_F_005, _Q_001_F_006RRef, _Q_001_F_007_TYPE, _Q_001_F_007_RTRef, _Q_001_F_007_RRRef, … (T1._Marked = 0x00) AND (T1._Fld6315 = 0x00) AND (T1._Executed = 0x00))<line>
Находим контекст этого запроса:
Форма.Вызов: Задача.ЗадачаИсполнителя.Форма.ЗадачиМнеБезГруппировкиПоПредметам... СформироватьДеревоЗадачМне( Задача.ЗадачаИсполнителя.Форма.ЗадачиМнеБезГруппировкиПоПредметам.Форма : 6464 : Результат = Запрос.Выполн<line>ет();’
Восстанавливаем полную логику — зачем и откуда вызывается модуль: модуль вызывается в рамках работы формой Задачи мне. Дальнейший разбор кейса смотри в разделе статьи «Виджеты».
RLS — решение задачи избыточных записей в регистре ключей ограничений. Спецразрешения — таблицы ДО/ПОСЛЕ
Основной метод анализа RLS состоит из следующих шагов (на примере формы списка «Внутренние документы»):
- Работа с ненагруженной копией:
- Сбор ТЖ с планами запросов.
- Открытие формы под полными правами.
- Открытие формы под «быстрым» пользователем.
- Открытие формы под «медленным» пользователем.
- Работа с нагруженной копией (повторение a — d).
- Анализ планов запросов.
Сформированные выводы:
- RLS в худшем случае добавляет к стоимости запроса примерно 95%.
- Из регистра «Данные внутренних документов» и из регистра «Дескрипторы для объектов» выбирается большое количество записей: ~ 200 тысяч и ~ 100 тысяч соответственно (на момент анализа). При этом Хэш матч оставляет из них ~ 1 тысячу записей. Большую часть стоимости при этом занимает выборка из регистра «Дескрипторы для объектов».
- В итоге основная проблема была как раз в слишком большом количестве «Дескрипторов для объектов», что было связано со слишком большими правами для всех пользователей. В «Спецразрешениях» на Внутренние документы у профиля «Все пользователи» стоит Чтение/Редактирование почти на все виды внутренних документов.
Как итог — количество записей в регистрах росло слишком сильно и представлено в таблице:
Наименование таблицы данных |
Количество строк |
Рост за 9 мес, % |
||
---|---|---|---|---|
авг. 21 |
нояб. 21 |
май 2022 |
||
ДанныеВнутреннихДокументов | 1 млн |
1,4 млн |
1,7 млн |
70 |
ДескрипторыДляОбъектов | 20 млн |
27 млн |
60 млн |
200 |
ПраваПоДескрипторамДоступаОбъектов | 12 млн |
18 млн |
40 млн |
233 |
Дополнительно к исправлению настроек политики доступа мы сделали регламентное задание по Автоматизированному удалению записей в регистре «Дескрипторы для объектов» с полем «Отключено» = Истина, т. к. стандартного регламентного задания в 1С:ДО для этого нет. При этом на момент первого запуска этой обработки таких «мусорных» записей было примерно 10 млн записей (15% от всего количества).
Высокая загрузка 1С-сервера
Виджеты (Текущие дела, Задачи мне)
Заметим, что часто проблемы быстродействия берут не качеством, но количеством. Например, Форма.Вызов: Задача.ЗадачаИсполнителя.Форма.ЗадачиМне согласно ТЖ вызывалась за 2 часа 130.412 раза и заняла в совокупности 222.091.758 мксек. Длительность одного вызова всего 1.703 мксек, т. е. он очень быстрый. Но за счет количества нагрузку на систему он генерирует колоссальную.
В основном, это связано с тем, что у всех пользователей стоял параметр «Автообновление формы» по-умолчанию, т. е. 60 секунд (в пределе для 2 500 пользователей это 300 тысяч вызовов за 2 часа). Мы увеличили его обработкой для всех пользователей до 300 сек и сделали это минимальной границей настройки.
Аналогичная ситуация была и с формой «Текущие дела», которая формировала вызовы также каждые 60 секунд. В итоге вызов за 2 часа утилизировал 197.333.306 мксек, выполнялся 56.979 раз и имел среднюю длительность 3463 мксек.
Решение было таким же как и с формой «Задачи мне».
Упомянем еще несколько интересных случаев в контексте 1С:ДО, на которые, возможно, стоит обратить внимание и в вашем случае:
- «Интервал проверки напоминаний», который по-умолчанию установлен в 1 минуту.
- Модуль «УстановитьЦветЗначениямПоказателей», который довольно сильно тормозит отрисовку стандартных Виджетов.
- Отметим одну интересную настройку на уровне конфигуратора. У динамического списка есть свойство «Получение представлений для невидимых полей». Приведем его описание ИТС: Т. е. следуя совету от 1С, если не предполагается вынесение невидимых полей на форму, то галочку ставим в Ложь и радуемся ускорению (довольно приличному) запросов динамических списков. Естественно одновременно следует ограничить добавление этих полей на форму.
- Еще одна довольно частая ошибка, особенно в самописных модулях — отсутствие индексов для запросов. Как пример, в конфигурацию добавили РегистрСведений.ФЗД_Идентификаторы с полями ID и IDType, которые не были проиндексированы. Следовательно запрос:
"ВЫБРАТЬ | ФЗД_Идентификаторы.Объект |ИЗ | РегистрСведений.ФЗД_Идентификаторы КАК ФЗД_Идентификаторы |ГДЕ | ФЗД_Идентификаторы.ID = &ID | И ФЗД_Идентификаторы.IDType = &IDType");
Всегда уходил в скан на 500 тысяч записей, был довольно долгим сам по себе, что вкупе с большим количеством вызовов сильно нагружало систему.
Форма списка Внутренние документы
Работа состояла из следующих шагов:
- Настройка технологического журнала.
- Настройка сбора запросов и их планов на СУБД.
- Настройка сбора счетчиков оборудования с сервера 1С и сервера баз данных за период сбора данных.
- Запуск трассировки расширенных событий.
- Открытие/закрытие формы под несколькими пользователями.
- Анализ собранных данных.
Для анализ собранных данных могут пригодиться следующие регулярные выражения:
Группировка длительности по событиям ТЖ:
Пример вывода:
DBMSSQL - 5 458 577
SCALL - 204 241
TLOCK - 16 156
Максимальная разница между соседними событиями:
Пример вывода:
202996 : 45:23.446005,CALL, - 45:23.649001,VRSREQUEST,
188006 : 45:18.477000,CALL, - 45:18.665006,SCALL,
188000 : 45:19.774000,DBMSSQL, - 45:19.962000,DBMSSQL,
186997 : 45:24.243004,CALL, - 45:24.430001,VRSREQUEST,
172003 : 45:18.290003,DBMSSQL, - 45:18.462006,SCALL,
Самые долгие запросы:
Пример вывода:
140995,DBMSSQL,
125004,DBMSSQL,
Список итоговых рекомендаций после анализа был следующим:
- На форме в Динамическом списке «Список» необходимо включить «Динамическое считывание данных».
- Ограничили период выгрузки по-умолчанию до 3-х месяцев.
- Провели работу по оптимизации политик доступа (см. выше про RLS).
- Провели работу по оптимизации самой формы:
- удалили ненужные для бизнес-процесса Заказчика реквизиты;
- удалили условное оформление;
- удалили ненужные для бизнес-процесса Заказчика вызовы (почта, ЭДО, ЭЦП).
Создание нового Внутреннего документа
Алгоритм работы с формой элемента аналогичен работе с формой списка, однако в ходе анализа мы обнаружили, что в замер времени попадает процедура «ОбработкаОповещения».
Чтобы убедиться в этом можно выполнить следующее:
- Поставьте точку остановки в форме элемента справочника «Внутренние документы», процедура ОбработкаОповещения.
- Вторую точку остановки в ОценкаПроизводительностиГлобальный.ЗакончитьЗамерВремениАвто.
- Откройте форму внутреннего документа.
- Наблюдайте последовательность остановки в точках. Сначала сработает весь код в ОбработкаОповещения, а только потом ЗакончитьЗамерВремениАвто.
Проблема в данном случае заключается в том, что ОбработкаОповещения попадает в другой серверный вызов и если это не знать, то просто пытаясь анализировать вызов самого открытия вы получите когнитивный диссонанс: длительность серверного вызова и замер времени никогда не сойдутся.
Поэтому правильный алгоритм анализа будет следующим:
- находим нужный нам серверный вызов (CALL);
- ищем 1-й VRSREQUEST вверх от CALL;
- ищем слово «ОценкаПроизводительности» вниз от VRSREQUEST;
- ищем 1-й VRSREQUEST вниз от «ОценкаПроизводительности»;
- лишнее удаляем.
В нашем случае ОбработкаОповещения была связана с ОбщаяФорма.СписокПоследних.
Мы оптимизировали данную общую форму:
- Ограничили вывод 30-ю последними элементами.
- Удалили условное оформление.
- Выяснили, что Строка.Представление = Строка(Строка.Объект); представляет собой запрос, да еще и с RLS. Данная строка вызывается в цикле, поэтому получается запрос в цикле. Естественно, поправили код, получая представление непосредственно в исходном запросе.
- Поправили модуль ОбщийМодуль.Делопроизводство Функции ПолеДокументаДоступноПоСостоянию и ПолучитьНастройкиСостояний, т. к. по какой-то причине вместо Ссылки там использовался Объект.
- Выяснили, что очень много времени тратится на RLS в строке РегистрСведенийОбращенияКОбъектам.Объект.ПометкаУдаления, т. к. Объект — составной тип и получается много левых соединений, на каждое из которых добавляется RLS. Но т. к. нам надо получить всего лишь пометку удаления, то список пометок можно получить в привилегированном режиме и подставить их к ограниченному списку для пользователя.
- Добавили команду Обновить и сделали Автообновление формы.
После выполнения последнего пункта мы убрали вызов СписокПоследних из обработки оповещения для всех основных форм.
Естественно, что кроме доработки СпискаПоследних мы серьезно оптимизировали и саму форму Элемента по аналогии с формой списка. Так мы предложили клиенту избавиться от Категорий документов, т. к. они не использовались. И удалили все, что связано с категориями на форме элемента.
Также довольно много времени занимала функция ИспользватьРПЗПоСумме, в которой использовался RLS без необходимости. Мы поправили вызов:
ВестиУчетПоРПЗ = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Объект.ВидДокумента, "ВестиУчетПоРПЗ", ВыбратьРазрешенные = Ложь); //было Истина по-умолчанию
Далее мы выяснили, что ОбщегоНазначения.ЗначениеРеквизитаОбъекта вызывается довольно часто из разных мест, поэтому для всех реквизитов, где не требуется проверка RLS мы поменяли ВыбратьРазрешенные = Ложь.
Временное хранилище файлов
Анализ данных данного механизма позволил выяснить еще одну интересную особенность 1С:ДО. Для того чтобы не гонять каждый раз данные по сети на компьютере пользователя создается временная копия данного файла, который хранится некоторое время, пока не потеряет своей актуальности. Интерес здесь заключался в том, что:
- Механизм работы с Временным хранилищем файлов завязан на «Оповещения».
- Настройки уникальны для каждого пользователя.
- При нехватке в каталоге свободного места система пытается вначале удалить лишние файлы, освобождая 20% от максимального объема.
- Если места и после этого не хватает, система грузит нужный файл только в память и затем работает с ним по сети.
Поэтому для решения данной проблемы вначале мы экспериментировали с ограниченным количеством пользователей, а затем дополнительной обработкой установили предпочтительные параметры для всех.
По-умолчанию настройки следующие:
Рекомендуемые нами параметры «Настройки основного рабочего каталога»:
- Максимальный объем — минимум 1 Гб.
- Очищать через — 7 дней.
К сожалению, данная настройка помогла не всем пользователям, т. к. часть пользователей регулярно работает с большими файлами от 300 МБ. Поэтому пришлось выполнять принудительную очистку основного каталога при входе пользователя.
Определенную нагрузку на систему дает работа с «Автоматическими шаблонами документов». Поэтому нам пришлось оптимизировать процедуру АвтозаполнениеШаблоновФайловСервер.ПолучитьМассивАвтозаполненийШаблона.
Обновление прав доступа
Еще одним интересным кейсом для нас стала проблема регламентного задания «Обновление прав доступа (долгое)». Напомним, что мы переставили его выполнение на ночь, что не удовлетворило клиента. Разбор данного кейса мы начали с анализа замеров времени до и во время выполнения регламентного задания.
В итоге мы получили следующую картину: APDEX в периода запуск регламентного задания уменьшается на 8%, среднее время возрастает на 15%. Наиболее характерные операции:
- Внутренние документы, открытие формы Список с папками:
APDEX уменьшается на 19%, среднее время возрастает на 56%. - Внутренние документы, выполнение команды Создать:
APDEX уменьшается на 28%, среднее время возрастает на 65%. - Файлы, выполнение команды Записать:
APDEX уменьшается на 7%, среднее время возрастает на 27%.
Анализ ключевых операций показал, что основное время роста «съедают» запросы, следовательно проблемы скорее всего на стороне СУБД.
Анализ сервера СУБД показал, что в момент запуска регламентного задания:
- В 3 раза возрастает количество рекомпиляций SQL в секунду.
Перекомпиляция имеет место, когда существующий план выполнения в кэше отбрасывается во время исполнения запроса и заменяется новым планом. Очевидно, что пересчет дескрипторов приводит к значительному изменению данных с момента первой компиляции плана выполнения. Скорее всего пересчитывается статистика и за ней следует рекомпиляция. - В 1,75 раза возрастает количество пакетных запросов в секунду.
Пакетные запросы это собственно в основном запросы 1С. - В 1,75 раза возрастает количество запросов блокировки в секунду.
Очевидно, что запись новых данных в дескрипторы будет сопровождаться блокировками. - В 2 раза возрастает количество превышений времени ожидания блокировки.
Очевидно, что блокировки будут сопровождаться ожиданиями и превышениями. - Появляются сами ожидания на блокировках, в обычное время их почти нет.
Все это привело нас к мысли, что данное задание генерирует огромное число транзакций — 30 000 за 30 минут (16 транзакций в секунду), вследствие чего сервер БД перестает справляться с нагрузкой.
Для решения данной проблемы мы предложили сократить число транзакций. Для этого необходимо было функцию ОбработатьПорцию поместить в транзакцию и уменьшить размер порции:
Достижение целевого показателя APDEX и расчёт экономической значимости ускорения работы персонала с 1С
В результате выполнения проекта увеличена производительность системы и достигнуты заданные целевые технологические показатели качества проекта:
- До обновления 1С:ДО APDEX был равен 0,912.
- После обновления и реализации нестандартных бизнес-процессов показатель снизился до 0,788.
- Первый этап оптимизации поднял APDEX до 0,85.
- Второй этап оптимизации дал APDEX 0,965.
Ниже в таблице представлен расчёт времени и денежная оценка экономии от уменьшения времени ожидания пользователей выполнения типовых операций в информационной системе:
Если вам интересна оптимизация производительности решений 1С, следите за обновлениями в нашей рубрике «От экспертов 1С‑Рарус» .Также вы можете подписаться на уведомления о выходе новых статей в нашем телеграм-боте 1C-Rarus Bot
От экспертов «1С-Рарус»