Кэширование в 1С или уменьшаем нагрузку на сервер

04.02.13

База данных - HighLoad оптимизация

О том как несложными алгоритмами можно уменьшить время отклика системы в целом.

Ничего нового не расскажу, но возможно кому-то поможет.

Ситуация

Пользователей > 100, конфигурация на базе 1С:Торговля+Склад. Загрузка на основном сервере ниже 80% практически не опускается в течении рабочего дня. После кэширования нагрузка стала держаться в среднем около 40%. Конечно сказок не бывает и "хорошие" отчеты быстро исправляют ситуацию.

Решение

Найти часто используемые справочники, константы, пути к файлам и создать для них кэш из СпискаЗначений или ТаблицыЗначений. Смысл в том что бы при  обращении к элементу сначала посмотреть если ли от в списке и если нет, то получить обычным путем (из базы и т.д.) и запомнить в списке (кэше). 

Недостатки

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

Пример 1 Константы: 

Так как константы в процессе работы меняются не часто, то есть смысл их кэшировать.
ГлМодуль

Перем глКэшКонстант Экспорт; // Список значений констант

....

// получение константы если она есть то из кэша, иначе из базы
Функция глКонстанта(Имя) Экспорт
    Значение = глКэшКонстант.Получить(Имя);
    Если ПустоеЗначение(Значение) = 1 Тогда
        Значение = Константа.ПолучитьАтрибут(Имя);
        глКэшКонстант.Установить(Имя,Значение);
    КонецЕсли;
    Возврат Значение;
КонецФункции

глКэшКонстант = СоздатьОбъект("СписокЗначений");
глКэшКонстант.Установить("РежимОграниченияКолваОкон",Константа.РежимОграниченияКолваОкон);
глКэшКонстант.Установить("КэшироватьТочкиДоступа",Константа.КэшироватьТочкиДоступа);
глКэшКонстант.Установить("ДатаЗапретаРедактирования",Константа.ДатаЗапретаРедактирования);

В документах вместо Константа.ДатаЗапретаРедактирования использую глКонстанта("ДатаЗапретаРедактирования").

Пример 2 Внешние печатные формы:

В глобальном модуле есть функция
Функция глУстановкаКнопкиПечать(Конт, ВидОбъекта, ТаблицаПечФорм) Экспорт
При каждом открытии документа в ней выполняется поиск по папке PrnForm всех файлов *.efd, их считывание и формирование списка доступных печатных форм.

Добавляю в ГлМодуль

Перем глКэшПечатныхФорм Экспорт; // таблица списка печ. форм.

....

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

В функции глУстановкаКнопкиПечать делаю проверку сначала в таблице и если ничего не найдено, то только тогда иду искать по файловой системе.

Функция глУстановкаКнопкиПечать(Конт, ВидОбъекта, ТаблицаПечФорм) Экспорт
    Перем Название, Кнопка;
    стр = 0;
    Если глКэшПечатныхФорм.НайтиЗначение(ВидОбъекта,стр,"ВидДокумента") = 1 Тогда
        Для Ном = 1 По глКэшПечатныхФорм.КоличествоСтрок() Цикл
            глКэшПечатныхФорм.ПолучитьСтрокуПоНомеру(Ном);
            Если (ВидОбъекта = глКэшПечатныхФорм.ВидДокумента) И (глКэшПечатныхФорм.Название <> "") Тогда
                ТаблицаПечФорм.НоваяСтрока();
                ТаблицаПечФорм.Название     = глКэшПечатныхФорм.Название;
                ТаблицаПечФорм.Кнопка       = глКэшПечатныхФорм.Кнопка;
                ТаблицаПечФорм.Файл         = глКэшПечатныхФорм.Файл;
                ТаблицаПечФорм.ФайлОписания = глКэшПечатныхФорм.ФайлОписания;
            КонецЕсли;
        КонецЦикла;
    Иначе
        // Дополним таблицу печатных форм внешними обработками из предопределенного
        // каталога ExtForms\PrnForms
        // одна запись нужна как флаг что эту запись уже искали
        глКэшПечатныхФорм.НоваяСтрока();
        глКэшПечатныхФорм.ВидДокумента = ВидОбъекта;
        глКэшПечатныхФорм.Название = "";

        Текст = СоздатьОбъект("Текст");
        ФайлОписания = ФС.НайтиПервыйФайл(глКаталогПечФорм+"*.efd");
        Пока ПустаяСтрока(ФайлОписания)=Цикл
            Текст.Открыть(глКаталогПечФорм+ФайлОписания);
            // Устанавливаем расширение
            Файл = Лев(ФайлОписания,СтрДлина(ФайлОписания) - 4) + "." + "ert";
            Если ФС.СуществуетФайл(глКаталогПечФорм + Файл) = 1 Тогда
                // Внешний файл, соответствующий файлу описания, найден.
            // Проверим, в нем что есть запись про текущий объект
                Если глНайтиВнешнююПечФорму(Текст, """" + ВидОбъекта + """", Название, Кнопка) = 1 Тогда
                    // Добавляем строку в список внешних файлов
                    ТаблицаПечФорм.НоваяСтрока();
                    ТаблицаПечФорм.Название     = Название;
                    ТаблицаПечФорм.Кнопка       = Кнопка;
                    ТаблицаПечФорм.Файл         = Файл;
                    ТаблицаПечФорм.ФайлОписания = (ФайлОписания);

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

    Возврат НомерСтроки;

КонецФункции // глУстановкаКнопкиПечать()

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

См. также

HighLoad оптимизация Программист 1C:ERP Бесплатно (free)

Использование оператора «В» для полей или данных составного типа (например, Регистратор) может приводить к неочевидным проблемам.

10.11.2025    4707    ivanov660    48    

50

HighLoad оптимизация Программист 1С:Предприятие 8 1C:ERP Бесплатно (free)

Приведем примеры использования различных в динамических списках и посмотрим, почему это плохо.

18.02.2025    7821    ivanov660    39    

61

HighLoad оптимизация Технологический журнал Системный администратор Программист Бесплатно (free)

Обсудим поиск и разбор причин длительных серверных вызовов CALL, SCALL.

24.06.2024    10240    ivanov660    13    

62

HighLoad оптимизация Программист 1С:Предприятие 8 Бесплатно (free)

Метод очень медленно работает, когда параметр приемник содержит намного меньше свойств, чем источник.

06.06.2024    16176    Evg-Lylyk    73    

46

HighLoad оптимизация Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Анализ простого плана запроса. Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы.

13.03.2024    7916    spyke    29    

54

HighLoad оптимизация Программист 1С:Предприятие 8 Бесплатно (free)

Оказывается, в типовых конфигурациях 1С есть, что улучшить!

13.03.2024    11209    vasilev2015    22    

47
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. quick 585 22.01.10 14:53 Сейчас в теме
Поскажите как нормально код оформить?
2. JohnyDeath 302 22.01.10 15:13 Сейчас в теме
Не поверю, что кэшированием констант и путей к внешним. печ. формам ты добился двукратного снижения нагрузки на сервер.
Flextor74; FoxMara; +2 Ответить
3. Berrimor 198 22.01.10 15:31 Сейчас в теме
Мысль логичная, но..... нужно оптимизировать кэшированием на каждом этапе (связано с ГЛОБАЛЬНЫМ перелопачиванием кода) так что мысль здравая, но ни чего нового не несущая, если это несущая модификацию кода модификация, а с теоретической точки зрения ВЫ ПРАВЫ ОДНОЗНАЧНО!
4. Asdam 120 22.01.10 15:51 Сейчас в теме
Поскажите как нормально код оформить?

http://infostart.ru/public/19856/
6. quick 585 22.01.10 17:25 Сейчас в теме
Не поверю, что кэшированием констант и путей к внешним. печ. формам ты добился двукратного снижения нагрузки на сервер.

Сам до сих пор сомневаюсь :D, но эффект точно есть. У меня еще был закэширован один справочник опрашиваемый по нескольку раз при открытии форм и отвечающий за права доступа. В пример не вынес т.к. код идентичный. Он был самый "тяжелый".
7. echo77 1935 22.01.10 19:10 Сейчас в теме
Загрузка на основном сервере ниже 80%

- эта цифра по какому показателю? Из каких показателей складывается?
8. Valet 56 23.01.10 00:29 Сейчас в теме
Только нагрузка наверняка никуда не делась, а переползла с сервера на клиента (плюс на клиенте и память занимаемая 1С подрастет).
И про использование справочников интересно. От запросов совсем отказаться?
9. quick 585 23.01.10 23:32 Сейчас в теме
Зачем полностью отказываться от запросов :) Всему свое место, просто есть данные, которые меняются редко или почти не меняются, а используются очень часто. Таблица констант кстати очень большая, т.к. в ней еще все периодические реквизиты хранятся. С другой стороны, все равно эти справочники будут постоянно занимать память (если они часто используются), почему бы их тогда просто в памяти не держать? :)
10. Elisy 957 27.01.10 07:01 Сейчас в теме
Кэш на стороне клиента однозначно значительно помогает. Проблему вижу в том, что некоторые величины могут меняться, например, дата запрета редактирования. Кроме того кэширование, например, таблиц на стороне клиента приводит к затратам памяти. В 1С сложно организовать управление кешем. Как альтернативный вариант могу предложить класс Cache .Net из пространства имен System.Web.Caching. Он позволяет положить в кэш значение навсегда, на определенное время, на определенное время после последнего обращения. Таким образом частично снимает описанные мной проблемы.
11. nikakoy 43 27.01.10 09:52 Сейчас в теме
ТиС. Кешируются в таблицу курсы валют. Поскольку ГлПересчет(...) используется везде (и не по разу на одной форме!!!) при некоторых операциях скорость реально увеличивается на порядки...
12. Rebel2007 27.01.10 11:51 Сейчас в теме
на этой странице вирус Trojan.tempi
13. Ветер в поле 3 27.01.10 12:01 Сейчас в теме
Давно уже использую кэширование внешних печатных форм - давно заметил, что львиную долю времени открытия формы документа уходит на считывание файлов описаний внешних печ. форм. А когда в день открывается несколько тысяч документов, то это неплохо нагружает процессор. Но мой вариант оптимизации немного другой - при первом доступе к внешним формам я сразу заполняю глКэшПечатныхФорм по всем документам - все равно ведь приходится открывать все файлы.
14. wolfsoft 2421 27.01.10 14:45 Сейчас в теме
15. sumv1 7 28.01.10 12:22 Сейчас в теме
Идея отличная.
Её должны были в 1С на уровне платформы реализовать.
Тем более в 8-ке появились параметры сеанса - что-то подобное.

В приведенном примере с константами есть ошибка:
глКэшКонстант.Установить(Значение); - так мы потом не получим значение константы
а надо:
глКэшКонстант.Установить(Имя,Значение);

и периодическую константу не получишь методом: ПолучитьАтрибут()
её можно запомнить при входе

Может автор нас проверяет? ;)
16. ROM_1C 692 29.01.10 12:39 Сейчас в теме
Если нечиго делать - можна еще играться с кнопками, списками, и другим хламом, которое так или иначе повлеяет ли на производительность. ;)
А так идея хороша, но от того что кода станеть больше - никому не будет лучше :)
17. Alav 13 13.02.10 19:36 Сейчас в теме
А если внешние печатные формы сделать на справочнике?. Т.е. реквизит видДокумента (отбор), Наименование, кнПечать, Путь? И этот справочник еще и за кэшировать с помощью Индексированной таблице (в виде дерева), где на первом уровне вид документа, а в тзПотомки соответственно список печатных форм?
18. quick 585 14.02.10 01:46 Сейчас в теме
А если внешние печатные формы сделать на справочнике?. Т.е. реквизит видДокумента (отбор), Наименование, кнПечать, Путь? И этот справочник еще и за кэшировать с помощью Индексированной таблице (в виде дерева), где на первом уровне вид документа, а в тзПотомки соответственно список печатных форм?

Можно и так, только придется еще справочник поддерживать в актуальном состоянии, а так при добавлении новой печ. формы достаточно перезайти в 1С.
19. Alav 13 14.02.10 09:28 Сейчас в теме
А какая разница куда писать в efd или в справочник? ИМХО обработку не сложно поправить
20. пользователь 14.02.10 10:15
Сообщение было скрыто модератором.
...
21. quick 585 15.02.10 18:05 Сейчас в теме
Привет Жека :)) Еще живет, но свое отживает. По мелочи то там, то здесь подкручиваю... Занялся как видишь выносом "полезняшек" на всеобщее обозрение, что бы добро не пропало.
22. dwarkin 19.03.10 10:00 Сейчас в теме
Вопрос автору: а нагрузка снизится, если БД под SQLем крутится? Версия 1С Предприятия 7.7 SQL
23. quick 585 19.03.10 23:09 Сейчас в теме
Вопрос автору: а нагрузка снизится, если БД под SQLем крутится? Версия 1С Предприятия 7.7 SQL

Снизится за счет уменьшения кол-ва запросов. Но надо смотреть что оптимизировать. Мне помогло, кому может не помочь.
24. dwarkin 20.03.10 09:22 Сейчас в теме
(23) Вопрос как бы не праздный, сама же SQLка (2000 в моем случае) часто используемые данные пихает в свой собственный кэш, а это память. Вот и получается, SQL в кэш загрузила, да и мы еще их загрузили.
Будем попробовать....
25. Merlin12042009 11.09.14 11:17 Сейчас в теме
Замечательная статья
Для отправки сообщения требуется регистрация/авторизация