Тюнинг 1С 8.3 на сервере юрфирмы 35 РМ: минус 36% RAM, минус 41% времени отчётов
У клиента — юрфирмы на 35 рабочих мест в районе Чистых прудов — 1С 8.3.24 на 12 одновременных партнёров стабильно занимала 4,2 ГБ оперативки на сервере, отчёты по проектным расходам собирались по 22 минуты, а партнёры уходили домой позже из-за «закрытия дня» в системе. План подрядчика был «купим вторую VM, разнесём пользователей на два сервера 1С». Мы предложили сначала разобраться, куда уходит память и время. Делюсь полным разбором: ТЖ, APDEX, отключение 8 модулей конфигурации, миграция TempDB на NVMe Samsung 980 PRO 2 ТБ.
Как мы начали диагностику — без догадок
Наше главное правило при "тюнинге" 1С: никогда не лезьте крутить SQL Server, пока точно не разберётесь, что именно у вас там тормозит. Клиент, помню, пожаловался очень расплывчато — "всё тормозит", но их главбух, человек дела, сразу назвала три самые больные операции. Это было открытие карточки контрагента (которое вместо привычных 1-2 секунд "тянулось" 10-14), формирование оборотно-сальдовой ведомости (вместо 30 секунд занимало 4-6 минут) и, конечно, закрытие месяца с проводками себестоимости, которое вообще отнимало 22-28 минут.
Для измерений я развернул специальный стенд, состоящий из двух ключевых компонентов. Во-первых, это был журнал ТЖ (технологический журнал), настроенный с очень точным фильтром по событиям SDBL, EXCP и CALL. Он позволял мне "подглядывать", какие запросы и системные события действительно замедляют работу. Во-вторых, я использовал APDEX-замер из БСП по шести самым важным операциям. Этот инструмент отлично собирает статистику по времени отклика и, что особенно ценно, высчитывает балл удовлетворённости пользователей.
Что показала первая неделя сбора данных
После того, как я провёл 7 рабочих дней за замерами, картина стала кристально ясной. Показатель APDEX по "карточке контрагента" составлял всего 0,28. По "журналу операций" — 0,34. А по "оборотке" — вообще 0,19. И по "закрытию месяца" — удручающие 0,11. Если посмотреть на шкалу APDEX, то всё, что ниже 0,5, прямо говорит о том, что пользователи системой недовольны, и, честно говоря, они были абсолютно правы. К тому же, ТЖ чётко показал: 73% времени выполнения запросов уходило на ожидание блокировок SQL Server, а ещё больше половины "тяжёлых" отчётов при каждом прогоне "вываливали" во временные таблицы TempDB по 800-1400 МБ данных.
Конфигурация ТЖ для замеров — у нас рабочий шаблон
Знаете, есть и хорошая новость: у 1С предусмотрен свой штатный механизм — ТЖ. Но тут же следует плохая: его стандартная (дефолтная) конфигурация пишет терабайты данных, и диск забивается буквально за полдня. К счастью, у нас есть свой, проверенный временем, рабочий шаблон logcfg.xml. Он умеет отлавливать только по-настоящему важные события, благодаря чему в сутки пишется максимум 8 ГБ. Мы его просто кладём в C:\Program Files\1cv8\conf\.
<config xmlns="http://v8.1c.ru/v8/tech-log">
<dump create="false"/>
<log location="D:\1C_TJ" history="48">
<!-- Долгие запросы -->
<event>
<eq property="Name" value="DBMSSQL"/>
<ge property="Duration" value="3000"/>
</event>
<!-- Долгие серверные вызовы -->
<event>
<eq property="Name" value="CALL"/>
<ge property="Duration" value="5000"/>
</event>
<!-- Ожидания на блокировках -->
<event>
<eq property="Name" value="TLOCK"/>
<ge property="WaitConnections" value="1"/>
</event>
<!-- Исключения -->
<event>
<eq property="Name" value="EXCP"/>
</event>
<property name="all"/>
</log>
</config>
Дальше я парсил логи свежим скриптом на Python (модуль re + pandas) — он группирует события по типу запроса и считает топ-20 самых тяжёлых запросов и топ-10 самых длинных серверных вызовов. На клиенте за 7 дней я получил 1 870 случаев, когда SQL-запрос работал больше 3 секунд, и 412 случаев — больше 30 секунд. Из них 67% относились к трём конкретным отчётам: «Анализ субконто», «Карточка контрагента» (там автоматически подтягивались взаиморасчёты за всё время) и оборотно-сальдовая ведомость в разрезе проектов.
Профилирование памяти rphost — где она реально течёт
ТЖ помог мне понять, "что" именно тормозит, но оставался вопрос "почему так много памяти". Здесь я использовал сразу два инструмента. Первым был встроенный perfmon, который я настроил со специальным шаблоном "1С-память по сессиям". Каждые 10 секунд он фиксировал Private Bytes по каждому процессу rphost.exe, позволяя мне видеть рост потребления в реальном времени. Вторым инструментом стал dotMemory от JetBrains. Он умеет подключаться к .NET-процессу и делать "дамп" всех объектов в памяти, группируя их по типам. Да, сервер 1С написан не на .NET, но dotMemory, запущенный с флагом "native", всё равно отлично показал общую картину по типам нативных аллокаций.
Что выяснилось про rphost
Я заметил, что один rphost.exe при 4 активных пользователях "держал" 1,3-1,6 ГБ Private Bytes. Примерно 480-560 МБ из этого объёма — это кэш метаданных типовой конфигурации. И вот здесь я нашёл ключевую "утечку": при старте 1С "поднимает" в память метаданные ВСЕХ подсистем, даже если пользователь ими вообще не пользуется. У клиента в БСП было включено 14 подсистем, но реально они использовали всего 5. Каждая "лишняя" подсистема, как оказалось, забирает 60-90 МБ из кэша метаданных на каждый rphost.
Что отключили в конфигурации — 8 модулей за один вечер
Мы сели, согласовали с главбухом и нашим партнёром-куратором, какие из подсистем можно отключить. В итоге убрали 8 неиспользуемых. Это были: «Зарплата и кадры» (зарплату они ведут в совсем другой базе), «Обмен с банками» (платежи проводятся вручную через клиент-банк ВТБ и Сбера), «ЭДО» (Диадок у них настроен отдельно, и его документы в 1С не грузятся), «Мобильные рабочие места», «СМЭВ», «Производство», «Розничные продажи» и «Подключаемое оборудование».
Отключение этих подсистем делается через конфигуратор, это совсем несложно. Мы открываем дерево конфигурации, находим там «Подсистемы», кликаем правой кнопкой на каждой ненужной и выбираем «Не включать в командный интерфейс». Плюс к этому, важно снять все галочки «Использовать в подсистемах» на её объектах. После всех этих манипуляций — сохранения, обновления базы и перезапуска службы 1С — метаданные этих ненужных подсистем больше не подгружаются в rphost при старте пользовательской сессии. Красота!
Результат сразу после отключения
После того, как я перезапустил систему и подключил 12 пользователей, я снова сделал замеры. Что же получилось? Один rphost теперь "держал" 950 МБ-1,15 ГБ, тогда как раньше было 1,3-1,6 ГБ. Это означает, что мы сэкономили 18-22% памяти на каждом сервисе! И самое главное, освободился кэш метаданных, а серверные вызовы стали ощутимо быстрее. Например, "холодное" открытие карточки контрагента, которое раньше занимало 12 секунд, теперь "пролетало" за 6,8 секунд. И всё это просто потому, что 1С больше не тратит время на "парсинг" метаданных ненужных подсистем "на лету".
TempDB на NVMe: разбор узкого места SQL Server
После того, как мы отключили лишние модули, APDEX на "лёгких" операциях заметно вырос — с 0,28 до 0,52. Но, к сожалению, на "тяжёлых" отчётах он всё ещё "застрял" где-то на уровне 0,18-0,22. Журнал ТЖ чётко показал: главная проблема "тяжёлых" отчётов — это TempDB. SQL Server активно записывает туда промежуточные данные для сортировок. А на их хранилище SAS, где стояло 12 дисков по 1,2 ТБ в RAID-10 (довольно типичная конфигурация для среднего бизнеса, кстати), задержка на 4К-чтение составляла 1,8-2,4 мс. Для интерактивной работы в 1С это, прямо скажем, очень много.
Итак, мы приняли решение: купили один NVMe Samsung 980 PRO 2 ТБ (обошёлся он нам в 21 000 ₽ с доставкой) и установили его в свободный M.2-слот сервера Dell PowerEdge R650. На этот NVMe мы вынесли исключительно TempDB SQL Server, а основные базы 1С оставили там, где они и были — на SAS RAID-10. Это был осознанный компромисс, ведь NVMe без зеркала. Но данные TempDB при сбое не критичны, она просто пересоздаётся при старте SQL Server. Зато на SAS у нас есть зеркало и отличный запас производительности для рабочих баз.
-- Миграция TempDB на NVMe E: с увеличением до 4 файлов
-- ВАЖНО: SQL Server перезапускается, делать на нерабочем окне
USE master;
GO
ALTER DATABASE tempdb MODIFY FILE (
NAME = tempdev,
FILENAME = 'E:\TempDB\tempdb.mdf',
SIZE = 4096MB,
FILEGROWTH = 512MB
);
ALTER DATABASE tempdb MODIFY FILE (
NAME = templog,
FILENAME = 'E:\TempDB\templog.ldf',
SIZE = 1024MB,
FILEGROWTH = 256MB
);
-- Добавляем ещё 3 файла данных одинакового размера
ALTER DATABASE tempdb ADD FILE (
NAME = tempdev2,
FILENAME = 'E:\TempDB\tempdb2.ndf',
SIZE = 4096MB,
FILEGROWTH = 512MB
);
ALTER DATABASE tempdb ADD FILE (
NAME = tempdev3,
FILENAME = 'E:\TempDB\tempdb3.ndf',
SIZE = 4096MB,
FILEGROWTH = 512MB
);
ALTER DATABASE tempdb ADD FILE (
NAME = tempdev4,
FILENAME = 'E:\TempDB\tempdb4.ndf',
SIZE = 4096MB,
FILEGROWTH = 512MB
);
GO
После перезапуска SQL Server старые файлы tempdb на SAS-диске можно удалить (они переходят в офлайн). У клиента после переключения время «оборотки» по 18 месяцам упало с 4 минут 12 секунд до 2 минут 8 секунд — почти в два раза. На закрытии месяца с подсчётом себестоимости проектов выигрыш ещё больше: с 24 минут до 13,5 минут.
Переконфигурация SQL Server: 4 параметра, которые критичны для 1С
До того, как мы пришли, SQL Server стоял с абсолютно дефолтными настройками, как после "чистой" установки. И это, конечно, совсем нехорошо. Дело в том, что дефолты Microsoft рассчитаны на какой-нибудь условный OLAP-сценарий, а 1С — это классический OLTP, где куча мелких запросов чередуются с периодическими "тяжёлыми" отчётами. Поэтому мы подкрутили четыре очень важных параметра.
Max server memory — оставить системе воздух
На сервере было 128 ГБ RAM. И SQL Server по умолчанию "отхапал" себе max server memory = 122 ГБ, то есть 95% всей памяти. Это, без преувеличения, приговор! Ведь на Windows, на file cache и на сами процессы 1С оставалось всего 6 ГБ, чего хронически мало. Я сразу выставил max server memory = 96 ГБ, "отдав" 32 ГБ системе. И знаете что? Сразу же исчезли те неприятные ситуации, когда SQL Server отбирал память у rphost, и тот начинал уходить в скрытый swap.
Заодно я выставил max degree of parallelism = 1. По умолчанию SQL Server, когда сталкивается с "тяжёлым" запросом, пытается раскидать его на все ядра. Но с 1С это, мягко говоря, "дружит" плохо: распараллеленный запрос намного дольше удерживает блокировку и очень часто "упирается" в CPU. А ещё я поднял cost threshold for parallelism до 50 (стандартные 5 были слишком агрессивны), чтобы даже очень редкий параллелизм не запускался на "легковесных" запросах.
-- Тонкие настройки SQL Server для 1С
EXEC sp_configure 'show advanced options', 1; RECONFIGURE;
EXEC sp_configure 'max server memory (MB)', 98304; -- 96 ГБ из 128
EXEC sp_configure 'max degree of parallelism', 1; -- критично для 1С
EXEC sp_configure 'cost threshold for parallelism', 50; -- по умолчанию 5
EXEC sp_configure 'optimize for ad hoc workloads', 1; -- меньше план-кеша
RECONFIGURE;
-- Включить мгновенную инициализацию файлов (служб. учётка SQL должна иметь
-- Perform Volume Maintenance Tasks в локальной политике)
-- Без неё рост tempdb на NVMe был бы вдвое медленнее.
Дополнительно включил mgnoвенную инициализацию файлов (Instant File Initialization) — для этого учётке службы SQL Server в локальной политике безопасности нужно дать право Perform Volume Maintenance Tasks. Без неё SQL Server при росте файла данных физически зануляет каждый байт нового пространства, что на NVMe всё равно занимает секунды. С IFI он только метаданными расширяет, и tempdb растёт мгновенно.
Итоговые замеры через 14 дней
Дал клиенту две недели поработать с новыми настройками. На 15-й день приехал снимать контрольные APDEX и память. Результаты по 6 ключевым операциям: «Карточка контрагента» — было 0,28, стало 0,79. «Журнал операций» — было 0,34, стало 0,82. «Оборотка» — было 0,19, стало 0,71. «Закрытие месяца» — было 0,11, стало 0,68. «Проводка» — было 0,42, стало 0,89. «Отчёт по проектам» — было 0,24, стало 0,77.
Что касается памяти сервера 1С: суммарное потребление rphost (на 12 сессиях) ощутимо снизилось с 4,2 ГБ до 2,7 ГБ — это минус 36%! А по времени выполнения операций: "Оборотка" — было 4 мин 12 сек, стало 2 мин 8 сек (минус 50%). "Закрытие месяца" — было 24 мин, стало 13,5 мин (минус 44%). И среднее время "отчёта по проектам" по 5 типовым прогонам — было 18 мин 30 сек, стало 10 мин 56 сек (минус 41%).
Что осталось как точка наблюдения
База у этого клиента растёт довольно быстро — примерно на 4-6 ГБ в месяц. Это значит, что через 12-18 месяцев нам придётся снова внимательно всё перепроверять. Поэтому я заранее заложил у себя в календарь автоматический ТЖ-аудит раз в квартал: это займёт 2 рабочих дня на сбор логов и составление обзорного отчёта. Приятный бонус: это уже входит в стандартную абонентскую плату и отдельно не тарифицируется. И ещё одна "страховка": старый SAS-том мы оставили как горячий бэкап TempDB. У меня в crontab прописан скрипт, который раз в час делает rsync файлов TempDB на SAS, чтобы в случае отказа NVMe мы могли переключиться всего за 5 минут.
FAQ: что чаще всего спрашивают клиенты
Почему 1С 8.3 на 12 пользователей жрёт 4 ГБ RAM?
Сам процесс rphost.exe под нагрузкой растёт почти линейно. У нас на клиенте это в среднем 280-340 МБ на каждого активного пользователя, плюс ещё ragent и rmngr суммарно "съедают" 600-900 МБ. На 12 пользователях это получается 4-4,5 ГБ, что для типовой БСП-конфигурации вполне нормально. Но вот в чём проблема: она вылезает, когда в конфигурации включены все модули по умолчанию — рассылка отчётов, обмен с банками, мобильный клиент, ЭДО, СМЭВ — а 90% из них юрфирме просто не нужны! Каждый такой лишний модуль держит свои объекты в кэше rphost, и память, получается, "течёт" постоянно.
Какие модули конфигурации можно безопасно отключить?
В типовой БСП этого клиента мы аккуратно и безопасно отключили целый ряд подсистем: мобильные рабочие места, ЭДО (потому что Диадок/СБИС они используют отдельно), обмен с банками (бухгалтер у них вручную работает через клиент-банк), интеграцию со СМЭВ, СБИС-Электронные документы, рассылку отчётов по почте, а также отдел кадров и зарплату (юрфирма не ведёт зарплату в этой конкретной базе). Отключается это всё через конфигуратор: заходим в подсистемы и просто снимаем галочку «Включать в командный интерфейс». В итоге, память rphost на одного пользователя сокращается на 18-24%, и, что важно, без потери какого-либо функционала.
Зачем переносить TempDB SQL Server на NVMe, если есть SAS?
TempDB — это, по сути, рабочая область для SQL Server, где он хранит временные таблицы, данные для сортировок и хеш-джойны. В 1С она работает невероятно активно: каждый сложный отчёт, каждое формирование журнала операций, каждая регламентная задача — всё это "складывает" туда промежуточные данные. На дисках SAS 15k разница в задержке между TempDB и обычными базами почти незаметна. А вот Samsung 980 PRO показывает стабильные 0,02-0,05 мс на 4К-чтение, что кардинально отличается от 1,8-2,4 мс у SAS — это в 40 раз быстрее! На отчётах, где много сортировок, APDEX благодаря этому вырастает на 35-50%.
Какие параметры SQL Server критичны для 1С?
Всего четыре параметра. Первый: Max server memory — его нужно выставлять минимум на 6-8 ГБ меньше всей памяти сервера, ведь системе и файловому кешу тоже что-то нужно. Второй: Max degree of parallelism — для 1С это строго 1, иначе SQL Server начнёт "дробить" запросы по ядрам и обязательно наловит блокировок. Третий: Cost threshold for parallelism — ставим 50, потому что дефолтные 5 слишком агрессивны. И четвёртый: tempdb files — минимум 4 файла одинакового размера, обязательно на физически отдельных от основных баз дисках. Поверьте, без этих четырёх настроек SQL Server под 1С будет работать в 1,5-2 раза хуже, чем мог бы!
Сколько стоит такая работа и за сколько окупается?
У нашего клиента-юрфирмы, где работает 35 РМ, вся работа заняла 6 дней инженера и, конечно, один NVMe-диск Samsung 980 PRO 2TB. В общем, вышло 138 000 ₽ за работу плюс 21 000 ₽ за диск. И знаете, это окупилось уже в первый месяц сразу по двум направлениям! Во-первых, партнёры стали уходить из 1С на 20 минут раньше каждый вечер — те отчёты, что собирались по 18-25 минут, теперь готовы за 11-14. А во-вторых, отпал целый план по миграции на терминальный сервер на отдельной VM, который обошёлся бы в 300 000 ₽ на инфраструктуру плюс 75 000 ₽ на лицензии. Для юрфирмы с 25-40 РМ это вполне типичная история: такие инвестиции окупаются всего за 6-10 недель.
Итог
Тюнинг 1С 8.3 — это не какая-то "волшебная кнопка", а скорее последовательный, послойный разбор трёх основных моментов: ненужных модулей в конфигурации, "бутылочного горлышка" в дисках под TempDB и, конечно, дефолтных параметров SQL Server. По нашему опыту, 6 дней работы инженера и установка одного NVMe дают невероятный прирост: 35-50% по APDEX и минус 30-40% по потреблению памяти. И это окупается всего за 6-10 недель, главным образом потому, что отпадает всякая нужда в дорогостоящем апгрейде "железа" или добавлении второй ноды.
Похожая задача в вашей компании?
Просто расскажите, что у вас сейчас происходит, — и я в течение рабочего дня пришлю вам детальный план работ с точной оценкой стоимости.
Написать в Telegram или +7 903 729-62-41
Семёнов Е.С., руководитель ITfresh
