WordPress под микроскопом

Monstrosa Inside™

Навеяло комментариями к статье «Трудности веб-разработки» и недавним копанием во внутренностях WordPress… Да, WordPress сама по себе хорошая система (особенно с точки зрения конечного пользователя): в ней можно настроить абсолютно всё (особенно, когда есть деньги и парочка толковых программистов). Но есть одно большое «но»: если вы — опытный программист и волею Фортуны вам пришлось копаться во внутренностях [...]

← Вернуться к полной версии записи «WordPress под микроскопом»…

Вложения:

Автор: ; опубликовано в: WordPress; метки: MySQL, WordPress, кэш, производительность
27
Ноя
2008

RSS Комментарии к статье «WordPress под микроскопом» (20)  »

  1. У меня немного другая статистика (наверное, сервер мощнее): 50 запросов, 0.05 сек.

    я бы сказал по другому – используют совсем разные плагины и различные фичи в “теме”. кстати после того теста я ставил разные новые бетаверсии 2ю7 и с каждой немного менялось – то было 37 запросов на главной, теперь стало 43. – имхо это более достоверные цифры, а с файловым кэшем (твой хак не пробовал, а другие аналогичного действия снижали запросы раз в 5, но реально было только хуже
    кстати откуда такая огромная цифра 1462? и как ПОЛНОСТЬЮ был отрублен кэш в современных версиях? а то что то уж много сверхподозрительных ОДИНАКОВЫХ строк в приведенном логе? например таких: SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes

    PS понравилась информация по ВП, занесу урл к себе в закладки.

    • и как ПОЛНОСТЬЮ был отрублен кэш в современных версиях?

      Есть два способа:

      1. Открыть файл wp-includes/cache.php и добавить return false; в процедуру wp_cache_get():
        [-]
        View Code PHP
        1. function wp_cache_get($id, $flag = '') {
        2. return false;
        3.     global $wp_object_cache;
        4.  
        5.     return $wp_object_cache->get($id, $flag);
        6. }
      2. Аналогичный первому, только с использованием плагина — я о нём сегодня-завтра напишу.

      кстати откуда такая огромная цифра 1462?

      Это к разработчикам :-) Если серьёзно, это самый большой недостаток в архитектуре проекта. В WordPress кэш занимает ключевую роль — разработчики не предполагали, что кому-то прийдёт в голову его отключать.

      например таких: SELECT option_name, option_value FROM wp_options WHERE autoload = ‘yes’

      Так get_option() устроен:

      [-]
      View Code PHP
      function get_option( $setting, $default = false ) {
          global $wpdb;

      //...пропущено

          // prevent non-existent options from triggering multiple queries
          $notoptions = wp_cache_get( 'notoptions', 'options' );
          if ( isset( $notoptions[$setting] ) )
              return $default;

          $alloptions = wp_load_alloptions();
          if ( isset( $alloptions[$setting] ) ) {
              $value = $alloptions[$setting];
          } else {
      //...пропущено
          }
      }

      function wp_load_alloptions() {
          global $wpdb;

          $alloptions = wp_cache_get( 'alloptions', 'options' );

          if ( !$alloptions ) {
              $suppress = $wpdb->suppress_errors();
              if ( !$alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE autoload = 'yes'" ) )
                  $alloptions_db = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options" );
              $wpdb->suppress_errors($suppress);
      //...пропущено
          }
          return $alloptions;
      }

      То есть при выключенном кэше для каждого вызова get_option() будут загружаться все опции из БД.

      Так как кэш никто не выключает, в повседневной жизни это уродство незаметно. Но при реализации persistent caching с сохранением данных в разделяемой (shared) памяти (в PHP есть соответствующее расширение, по-моему, shm) оно может появиться: размер отводимой памяти ограничен (у меня кэш довольно быстро перешагивает черту 10 мегабайт) и при определённых обстоятельствах кэширующий модуль может просто отказывать в помещении объекта в кэш (плагины имеют тенденцию не подчищать настройки в таблице wp_options при сносе; так в таблице скапливается мусор, а WP его добросовестно грузит, хотя он не нужен).

  2. Если движок универсальный, да еще расширяемый, то приходится жертвовать в пользу оптимизации “сверху”, к сожалению. Тем более, что он отдается на растерзание разработчикам, которые, например, забывают подчищать таблицу (которая и так забита – теми же рсс из дашборда) – хотя это простое действие.

    • которая и так забита – теми же рсс из дашборда

      Те же RSS из dashboard было бы разумнее хранить в файле — не вижу смысла захламлять базу данных. Одна лента весит где-то 50К, 4 ленты будут весить порядка 200К. Плюс излишки на сериализацию. Как часто среднестатистический блоггер посещает dashboard? Не получается ли так, что закэшированный RSS в таблице успевает состариться? Ну грохнет его WordPress, но и создаст лишнюю фрагментацию в таблице. Часто ли блоггеры делают OPTIMIZE TABLE? Сомневаюсь.

      В любом случае, обращение к файлу (в случае RSS) займёт меньше времени, чем обращение к базе.

      то приходится жертвовать в пользу оптимизации “сверху”

      Но при грамотном проектировании жертв меньше! Взять тот же кэш: на самом деле, очень тяжело написать кэширующий движок с высокой производительностью, учитывая архитектуру WordPress. WP всё время что-то кэширует, но ведь память-то не резиновая! У меня за одно обращение к главной странице в кэш почти 6 мегабайт попадает! Если использовать shm и хранить кэш в разделяемой памяти, рано или поздно (скорее, рано) встанет вопрос о том, что память нужно освобождать. Я уже не говорю о фрагментации и т.п. Для освобождения памяти будет использоваться какой-нибудь простенький алгоритм, и тут получается такая вещь: выпнул из памяти какой-нибудь блок, а WordPress он понадобился! А при использовании хорошего алгоритма приходится идти на дополнительные издержки, что выливается в ту же производительность: проверять в цикле тысяч по десять элементов с целью нахождения кандидата на вылет будет не всегда быстро. Да, это быстрее, чем лезть в БД при хорошей нагрузке, но медленнее, чем стандартный кэш WordPress (!) при низкой нагрузке. Я не тестировал акселераторы, может быть, там что-то изменится.

      А что мешало разработчикам спроектировать нормальную систему классов и использовать несколько уровней кэширования? Те же опции: читаем их в локальный protected array один раз и используем в течение всей сессии. Нужно — отдаём кэширующему модулю, если он не возьмёт данные — а и хрен с ними, у нас есть их локальная копия, и в базу мы не полезем. Вот тогда можно было бы использовать более простой алгоритм в кэширующем движке, не переживая, что WordPress полезет несколько раз в базу за одними и теми же данными. С опциями это простой пример, но идея понятна.

      Или еще пример: когда я разбирал запросы в get_calendar(), я нашел способ оптимизировать запрос: если бы мы убрали ORDER BY, MySQL не пришлось бы делать файловую сортировку. GROUP BY отсортировал данные в одном порядке, а ORDER BY сортировал их в другом. Не помню деталей, но EXPLAIN показывал, что без ORDER BY не было бы Using filesort. Просто WordPress пришлось бы просматривать массив в обратном порядке. Мелочь, согласен. Но когда таких мелочей много, то на их исправлении можно выиграть существенный прирост в производительности.

      Я вводил избыточность в тестовую БД и переписывал запросы; в результате на большой базе производительность поднялась в 10 раз!

    • У меня дошли руки до очень простого доказательства :-)

      Я за 20-30 минут переписал один из модулей WordPress, а именно, Options. Переписал в “нашем родном, мудром, объектно-ориентированном, офигительном” стиле.

      Код не production-ready (ближе к бете, я бы сказал), но результат на лицо: с выключенным кэшем имеем 382 запроса и 0.6354 секунды. Это гораздо более вменяемый результат, нежели “1462 запроса и 2.02 секунды”.

      Кому интересно потестировать локально (что очень приветствуется, ибо это, я надеюсь, потом пойдет патчем к WordPress), файл wp-includes/functions.php приаттачен к комментарию.

      functions.zip

  3. [...] плагин хранит свои настройки непосредственно в коде (в файле wp-content/object-cache.php). Это связано с проблемой курицы и яйца, а также с архитектурными особенностями WordPress. [...]

  4. Vladimir а вы пытались донести о своих находках, изысканиях до разработчиков WordPress, думаю что если всё так замечательно, то в новых версиях мы бы могли это увидеть. Было бы всем хорошо.

    • Блин начал читать ваш блог с конца, углубившись увидел что вы сотрудничаете с разработчиками. Прошу прощения за беспокойство. Если даже разработчики не поправят, то можно самостоятельно с вашей помощью облегчить, улучшить себе жизнь. :)

    • Пытался… Кое-что должно появиться в 2.7.1. Проблемы производительности уже неоднократно обсуждались в рассылке wp-hackers. Проблема вся в архитектуре WordPress. Для того, чтобы устранить многие недостатки, нужно переписывать большое количество кода.

  5. Владимир, добрый день!

    Спасибо за прекраное исследование и дотошную работу. :)

    Так добавили разработчики это решение в WP или нет ?

  6. Дмитрий

    Супер, долго искал, большое спасибо автору!

  7. [...] мусора. За кадром осталась очистка инсулинового кэша WordPress, но идея понятна. Вот только жаль, что оно увидит свет [...]

  8. Domain Industry

    да, ужасы.
    я как-то написал к одному сайту функционал работы сайта без вордпресс, а чисто своим кодом, так у меня свой код просто “летал”. админку использовал WordPress. вообще я думаю, что Wordpress надо уходить на другие движки, где есть встроенный функционал форума, блога, новостей, статей, опросов, галерее и прочее, такая CMS, которая даже без кеша “летает”.

  9. Владимир, я хотел бы связаться с вами удобным для вас способом, чтобы обсудить возможность и стоимость работы над моим ресурсом.
    Сейчас использую WP 3.01, стоит форум SMF 2.0 RC1.2
    Хочу превратить в мультисайт, решить вопрос с единой регистрацией на сайте (дочерних блогах) и форуме (есть желание перенести дамп SMF с пользователями в таблицы встроенного в страницы WP форума Simple:Press), сделать человеческую систему интерактивного заполнения форм каталога НКО на основном сайте, возможность фильтрации каталога по разным параметрам.

    Ну и оптимизировать все это хозяйство для быстродействия. Выслушать практические советы по редизайну и поисковой оптимизации.

    Более детальное тз могу сформулировать конкретнее письмом. К сожалению, не нашел на вашем сайте контактных данных для связи, решил воспользоваться письмом через комментарии.

    Организация у нас некоммерческая, свободных денег на услуги пока нет, однако если озадачите стоимостью, то поищем силами своих активистов.

    С уважением, Олег

Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.

Оставить комментарий к записи «WordPress под микроскопом»

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Оставляя комментарий, вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя

गते गते पारगते पारसंगते बोधि स्वाहा