1С-Битрикс: Управление сайтом .NET

Пример оптимизации "живого" проекта на платформе Битрикс


Оптимизация веб-проектов

Тема: Производительность
Описание: Группа по вопросам производительности веб-проектов.

Пример оптимизации "живого" проекта на платформе Битрикс

Активно развивающийся проект на платформе Битрикс 7.0 (Oracle версии 10.2.0.1, размер более 50 ГБ, Linux i386, выделенный сервер).
Предварительное замечание: этот сервер изначально был не совсем подготовлен для быстрой работы: 32-разрядная ОС на оборудовании x86_64, 32-битный Oracle, RAID-6 для файлов БД, 2 не самых быстрых (1.5 ГГц), зато 4-х ядерных процессора и 16 ГБ ОЗУ.
В связи с ростом нагрузки более чем в 2 раза с начала года - более 400,000 хитов в сутки, до 60,000 посетителей в сутки и после недавнего обновления на версию Битрикс 7.0 сайт стал испытывать определённые проблемы:

При load average 60 сайт удовлетворительно работал(что само по себе удивительно, Максим Смирнов искренне порадовался стабильности работы Linux+Oracle), при нагрузке 75 чувствовались проблемы.
Поскольку основную нагрузку создавали процессы Oracle, первым делом анализируем его.
Из отчётов AWR/statspack виясняем, что основное время пользовательские процессы вели активную "умственную" деятельность (CPU time):
Код
Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~                                        wait   Call
Event                                 Waits    Time (s)   (ms)   Time
------------------------------ ------------ ----------- ------ ------
CPU time                                          8,511         73.6
db file scattered read            2,836,881       1,012      0   8.7
db file sequential read           2,452,163         606      0   5.2
log file sync                        24,138         463     19   4.0
log file parallel write              26,075         283     11   2.4
---------------------------------------------------------------------
Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            Buffer Nowait %:   99.98       Redo NoWait %:  100.00
            Buffer  Hit   %:   94.95    In-memory Sort %:  100.00
            Library Hit   %:   98.75        Soft Parse %:   98.75
         Execute to Parse %:    7.35         Latch Hit %:   99.90
Parse CPU to Parse Elapsd %:   86.79     % Non-Parse CPU:   96.29

Ну и поскольку мы видим, что на разбор SQL тратится совсем немного времени, менее 4% (%Non-Parse CPU: 96.29), а думать пользовательским процессам вообще говоря не о чем, кроме разбора и выполнения - ищем неэффективные запросы - с помощью тех же родных оракловских инструментов AWR/statspack выявляем самые ресурсоёмкие (по критериям SQL ordered by Elapsed Time, SQL ordered by CPU Time, SQL ordered by Gets) запросы и проверяем инилизационные параметры.
Проверяем ключевые параметры Oracle:

    optimizer_features_enable = 10.2.0.1 [Ок]
    optimizer_mode = ALL_ROWS [Ок, для версии 10.2.0.1]
    optimizer_index_cost_adj = 100 [Ок]
    optimizer_index_caching = 0 [Значение по умолчанию, предполагает, что для получения ЛЮБОГО индексного блока придётся выполнить операцию физического чтения с диска, не способствует индексному доступу к данным, увеличим до 90(%), для активизации использования индексов]
    cursor_space_for_time = FALSE [Ок, в условиях ограниченной памяти для SGA]
    session_cached_cursors = 50 [Мало, но некритически, рекомендуем увеличить до 150]
    cursor_sharing = FORCE [Ок]
    open_cursors = 300 [Ок]

Анализирум-оптимизируем явно "медленные" запросы, достраиваем недостающие индексы на таблицах B_FORUM_PRIVATE_MESSAGE, B_IBLOCK_ELEMENTB_IBLOCK_SECTION_ELEMENT, B_STAT_* - скрипты для создания индексов отправляем разработчикам для включения в будущие релизы Битрикса.
Проверяем системную статистику Oracle - никогда не собиралась, в этом случае это оправдано, т.к. используется 32-битный Oracle с ограничением SGA ~ 2,7 GB, т.е. наша БД активно использует кеш файловой системы и для неё операции физического чтения это чтение из кэша - в общем, "правды нет" и системная статистика тут вряд ли поможет.
Load_average ~ от 10 до 15
Проверяем httpd сервер:
    apache.MaxRequestsPerChild = 500 - мало, процессы apache живут не более 3-5 минут, рекомендуем увеличить до 2500
    apache.MaxClients = 100 - много для 8-ядерной машины, постоянно запущены от 50 до 60 процессов, рекомендует уменьшить до 30

Load_average ~ от 8 до 12
Уже удовлетворительно, пробуем копнуть глубже, используем модуль Битрикс "Монитор производительности":

    1. Настройки -> Производительность -> Очистка - удаляем старые данные
    2. Настройки -> Производительность -> Включить - запускаем процедуру сбора данных на 1 минуту - процедура достаточно "тяжелая" для системы, желательно проверять загрузку системы во время выполнения.
    3. Настройки -> Производительность -> Хиты с группировкой - с помощью фильтров можно выявить самые ресурсоёмкие страницы нашего Битрикс приложения, самые медленные запросы и планы выполнения запросов(!) - сам был приятно удивлён

Таким образом с помощью "Монитора производительности" удалось выяснить основную причину проблем - неэффективные постраничные запросы, с выборкой и обработкой всего массива строк на стороне PHP, характерные для "старых" компонентов 1.0. Компоненты 2.0 формируют более оптимальный SQL код - в PHP возвращается из БД точно необходимое для отображения запрошенной станицы количество строк. Обновлённые запросы компонентов 2.0 также более эффективны с точки зрения производительности БД.
Что в результате?

Load_average ~ от 3 до 7
Средний % Idle CPU ~ 40-60%
- это тот резерв, которого мы добивались!
С учётом появившегося резерва можно быть уверенным, что сайт выдержит планируемое 2-х кратное увеличение нагрузки.
P.S. Отражение результатов в статистике Oracle
Код
Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~                                        wait   Call
Event                                 Waits    Time (s)   (ms)   Time
------------------------------ ------------ ----------- ------ ------
CPU time                                          5,041         80.9
log file sync                        33,127         657     20  10.6
db file sequential read             482,404         379      1   6.1
log file parallel write              33,075         372     11   6.0
SQL*Net message to client        19,624,717          29      0   0.5
---------------------------------------------------------------------

Потребляемое нашей системой CPU time уменьшилось в 1,7 раза: с 8500 до 5000 секунд - система тратит меньше процессорных циклов вследствие оптимизации запросов
Количество операций чтения блоков (db file sequential read) уменьшилось более, чем в 5 раз
Многоблочное чтение (FULL SCAN'ы, db file scattered read) исчезли из TOP-5 - большая часть доступа к данным происходит по индексам
Операции, связанные с записью лог-файлов (log file sync, log file parallel write) незначительно увеличились количественно, что говорит о возросшем количестве транзакций (нагрузке), но продолжают быть достаточно медленными - 20 миллисекунд, это много, и является последствием использования RAID-6 для БД
20.11.2008 21:04:03
Цитата
Что в результате?
Load_average ~ от 3 до 7


А помести скрин с текущей нагрузкой, это будет наиболее наглядно.

Цитата
Таким образом с помощью "Монитора производительности" удалось выяснить основную причину проблем - неэффективные постраничные запросы, с выборкой и обработкой всего массива строк на стороне PHP,


Да, монитор полезная штука. Помогает именно работающим проектам под нагрузкой.
21.11.2008 07:27:08
Пользуясь случаем, хочу опять высказаться за то, чтобы давать сей полезный инструмент любому партнеру (:
21.11.2008 08:14:28
Идея понятна... (кстати партнерам NFR версия Портала и ББ дается). Но как тогда иначе стимулировать партнеров и клиентов покупать верхние редакции? А, кстати, покупать стали очень хорошо.

Ну это как с Ораклом. В Ентерпрайз версии, например, есть очень удобные для разработчиков инструменты безостановочной работы и перестройки данных на лету. Но использовать их можно только в верхней редакции.
21.11.2008 08:18:29
Цитата
Но как тогда иначе стимулировать партнеров и клиентов покупать верхние редакции?

А все просто - придумать новые фишки для верхних редакций. Я никоим образом не попрошайничаю. Просто неправильно это - урезать _разработчиков_ в инструменте. Представьте, если бы статистика запросов была доступна только в Бизнесе?
Я никак также и за то, чтобы немедленно дать всем этот модуль. Но надо к этому идти. Как было когда-то с модулем компрессии. С содроганием вспоминаю эти времена. Разве, Сергей, сейчас не дико вспоминать, что когда-то модуль компрессии был не во всех редакциях?
21.11.2008 08:19:13
Справедливости ради замечу, что и на Старте можно натворить такое, что приходится "привлекать" модуль производительности.
06.03.2009 21:41:41
А у меня "Эксперт", и 15 сайтов в многосайтовой системе с тысячной посещаемостью каждый, которые очень даже активно нагружают сервер.

Монитор производительности очень бы пригодится, а покупать ради него "Бизнес" где есть только дополнительный интернет-магазин (который нам не нужен) совсем не хочется.

Интересно, можно ли модуль монитора аккуратно установить на проекте, потестировать, а потом удалить?
21.11.2008 10:19:55
Монитор нужно включать во все редакции, не думаю что он несёт пользу администратору проекта и сыграет большую роль при выборе именно такой редакции, он нужен в основном разработчику проекта либо лицу технически его поддерживающему.
Не думаю что это станет причиной перехода с версии Бизнес на Большой бизнес т.к. для владельца проекта это очень накладно да и опять же толку для самого владельца это никакого не принесёт (в плане "что нового появится у меня на сайте для пользователей, либо какие то удобства для меня" - "ни фига" - "тогда забудь") - попросту он "попросит" разработчика использовать другие инструменты.
Цитата
Ну это как с Ораклом. В Ентерпрайз версии, например, есть очень удобные для разработчиков инструменты безостановочной работы и перестройки данных на лету. Но использовать их можно только в верхней редакции.

Что касается Оракла, опять же его поддержка есть только в версиях "дорогих" в которых уже есть монитор.
21.11.2008 12:01:25
Интересная статья.

Основные принципы описываемой оптимизации я понял, однако хочу отметить что такая оптимизация требует достаточно весомых знаний по теории баз данных.
21.11.2008 16:38:13
Включил монитор - скажите, как запретить вывод предупреждений в модулях и стандартных компонентах ? )))
21.11.2008 17:01:02
В настройках модуля есть галочка. Но она или включает все или ничего.
24.11.2008 21:00:16
ИМХО, RAID 6 на нормальном контроллере помедленнее, чем RAID 5, но не настолько, как вы говорите.
Я так понял, что вас спас именно переход на компоненты 2.0? Код компонентов вы не меняли?
25.11.2008 11:04:17
Я не сравниваю друг с другом RAID 6 и RAID 5, оба эти варианта для файлов БД не предназначены. Из уровней RAID для БД рекомендуется RAID 10, работающий предсказуемо быстро на любом оборудовании (контроллере).
В компонентах 2.0 используются оптимизированная обработка постраничных запросов и со стороны БД (более быстрые запросы), и со стороны PHP (обработка меньшего объёма данных). Снижается нагрузка и на БД, и на Веб - в посте просто приведён наглядный пример с точки зрения производительности системы.


Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».