В этом посте я хотел бы рассказать о своём опыте оптимизации работы Битрикса, работающего на Windows-платформе под MSSQL.
Начать разбираться с производительностью такой связки меня побудило исключительно появление версии 8.5 с переработанным модулем "Производительность". Именно возможность получить оценку своего хостинга и сравнить с другими площадками дала толчок этому исследованию. [spoiler] Итак, как только вышла версия 8.5, то я первым делом полез в панель производительности, чтобы увидеть заветные цифры. Радость обновления Битрикса сменилась горечью результата: где-то в районе 4-6 на не самом плохом оборудовании.
Оптимизация №1
При анализе и игре с настройками php и Битрикса я заметил упоминание про WinCache, о котором раньше не слышал. Немного поиска выдало хорошие рекомендации "лучших собаководов" и красивые графики роста производительности. Настройка и установка прошли легко и их итог хорошо виден тут: Более детально про Wincache можно прочитать тут
Радоваться можно было уже от этого результата, все показатели разом улучшились где-то в 2 раза, сайт и админка стали заметно быстрее загружаться. Однако было грустно от полученных значений БД, особенно чтения. 1000-1200 -- это совсем не то, что может выдавать выделенный MSSQL сервер, поэтому...
Оптимизация №2
Первым делом был разобран сам модуль производительности и из него был извлечён модуль оценки БД. Для него я подстроил имевшийся в запасниках мини класс для работы с базой данных, но через драйвер sqlsrv. Запуск в консоли показал интересный результат в 3200+ запросов на чтение, что было в 3(!) раза больше, чем в тесте Битрикса(скриншот выше). Использование аналогичного мини класса, но на odbc, показало значение около 1200.
Неужели драйвер odbc так сильно проигрывает драйверу от Microsoft? Возможно, но корень зла оказался немного в другом.
Получив такой неожиданный результат появился профессиональный азарт "перебрать двигатель" Битрикса, а именно его класс работы с БД в
/bitrix/modules/main/classes/mssql/database.php
и перевести его на рельсы sqlsrv. Эта задача не такая и сложная, все вызовы очень похожи, лишь немного переделан код получения данных:
При хранении сессий в базе данных нужно аналогично отредактировать /bitrix/modules/security/classes/mssql/session.php (других мест прямых вызов odbc найдено не было)
в dbconn.php нужно будет исправить $DBHost, чтобы он указывал сразу на сервер
Единственный тонкий момент, который возник, это постраничный забор данных(в NavQuery), который был решён использованием SQLSRV_CURSOR_STATIC. Всё казалось готовым к старту, ключ зажигания включен и вроде бы взлетели: сайт вёл себя адекватно, проблем вроде не замечено. Вот только особого ускорения не почувствовалось, что подтвердили тесты: общая производительность поднялась где-то на 1-2 балла, и количество чтений БД выросло лишь "в пределах погрешности измерений".
"Так не бывает и должно быть разумное объяснение" крутилось в голове и оно было найдено... после отключения SQLSRV_CURSOR_STATIC:
Корень зла оказался в курсорах. По умолчанию в odbc выбран статический курсор (SQL_CURSOR_STATIC), который позволяет произвольно перемещаться вперёд-назад по выборке. Драйвер sqlsrv наоборот по умолчанию задаёт тип последовательный курсор(SQLSRV_CURSOR_FORWARD), способный двигаться только вперёд. Во всём коде database.php есть лишь одно место, где реально используются переходы курсоров, а именно в NavQuery. Там пролистываются результаты до нужной страницы, если не установлен NavShowAll. Более того, записи листаются исключительно вперёд.
Возникает вопрос к разработчикам Битрикса: а так ли необходимо использовать *_CURSOR_STATIC, серьёзно терять в производительности, и всё ради мнимого удобства переключения на N-ую запись? Может лучше быстро сделать sqlsrv_fetch или odbc_fetch_row нужное количество раз?
Из тех 20-50+ запросов, что делает Битрикс, не более десяти реально будут использовать навигацию, в то время как остальные тратят драгоценные ресурсы на создание статических курсоров.
Итог
Достигнутый результат полностью удовлетворяет. Производительность поднялась кардинально, что отражает скачок оценки от ~5 до ~21, страницы стали загружаться ощутимо быстрее, время отклика упало с ~900мс до ~300мс.
P.S. Попытка сделать последовательный курсор в ODBC успехом не увенчалась, возможно я что-то делал не так, но желания копаться уже нет.
P.P.S. Применение второго метода оптимизации конечно же предлагается в варианте "As Is" без каких либо гарантий.
Видимо, здесь нужно разработчикам битрикс подумать над оптимизацией. У меня есть ощущение, что mysql нормально оптимизируется, а вот mssql и oracle не являются mainstream и, скорее всего, в них есть скрытые подводные камни.
Про ваши действия могу сказать наверное следующее: мне они показались интересными, но проблемными с точки зрения разработчика/саппорта. Во-первых, кардинального ускорения не получилось: вот пример моего офисного сервера (за примерно 10 т.р.), на котором просто поставлен mssql
Производительность конфигурации на 07.12.2009 14:16:55 составляет 13.16
Подсистема Оценка Эталон Примечание
Конфигурация Время создания страницы: 0.0798 сек. 13.16 30
Среднее время отклика 0.0760 0.0330 секунд
Процессор (CPU) 9.4 9.0 миллионов операций в секунду
Файловая система 1 494.8 10 000 файловых операций в секунду
Почтовая система 0.0686 0.0100 время отправки одного письма (в секундах)
Время старта сессии 0.0005 0.0002 секунд
Конфигурация PHP оптимально оптимально рекомендации
База данных MS SQL (запись) 1 982 5 600 количество запросов на запись в секунду
База данных MS SQL (чтение) 1 720 7 800 количество запросов на чтение в секунду
База данных MS SQL (изменение) 5 231 5 800 количество запросов на изменение в секунду
Атлон 5200, 2 Гб памяти, какой-то винчестер. Стоит MSSql 2005, Zend Server + работа через NGINX от линукса.
Результат сильно похож на ваш.
Возможно, разработчикам действительно стоит отказаться от того типа курсора, но, скорее всего, тюнинг MSSql даст больший эффект.
Версию mysql на такой конфигурации проверить пока не представляется возможным, но на аналогичном "железе" виртуальная машина v1.3 показывает где-то ~47 этих попугаев.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».