Ars Longa, Vita Brevis

Monstrosa Inside™

Навеяло комментариями к статье "Трудности веб-разработки" и недавним копанием во внутренностях WordPress

Да, WordPress сама по себе хорошая система (особенно с точки зрения конечного пользователя): в ней можно настроить абсолютно всё (особенно, когда есть деньги и парочка толковых программистов). Но есть одно большое "но": если Вы — опытный программист и волею Фортуны Вам пришлось копаться во внутренностях этого чуда, то неизбужно в скором времени начинаете ощущать себя проктологом-патологоанатомом.

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

А какое можно сделать «элегантное решение»? Чтобы оно обладало тем же функционалом? Можно только повторить монстра.

Доля истины в этом высказывании, разумеется, есть: чем универсальнее решение, тем оно монстроидальнее. Задача состоит в том, как этого монстра оптимизировать и минимизировать. Есть программисты, а есть быдлокодеры (у меня сегодня два цвета: чёрный и белый). Разница между первыми и вторыми заключается только лишь в умении использовать ресурсы серого вещества, именуемого мозгом. В результате у первых получается элегантное решение, а у вторых — Некрософт Виндовс Нерабочий Труп.

Это я всё к чему? Берём WordPress и смотрим:

MySQL: 45 запросов / 0.550 Потребление памяти: 10.1MB…

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

Пятьдесят плюс-минус пять запросов: много ли это? Фиг его знает, может и не много, ибо всё познаётся в сравнении. Ну так давайте сравним. Я "надругался" над несчастным WordPress и просто отрубил ему кэш. Готовы?

1462 запроса и 2.02 секунды (лог запросов превышает мегабайт). Те, кто знаком с оптимизацией запросов в MySQL, ужасайтесь вместе со мной.

Можно долго спорить о том, что кэш нельзя выключать, разработчики его не зря включили и всё в том же духе. Ответ: а почему нельзя было сразу спроектировать нормально, чтобы не требовались костыли в виде кэша? По-хорошему, кэш должен использоваться как средство, дающее дополнительное ускорение приложению, но не как средство, обеспечивающее нормальную жизнедеятельность приложения. Скажем так: стимуляторы при умеренном применении могут оказать положительный эффект на человека. Но когда стимуляторы используются только для поддержания жизнидеятельности человека — это уже другая песня.

Вот так.

Но, возможно, в следующей версии

Добавить в закладки
  • del.ici.ous
  • Digg
  • Furl
  • Google
  • Simpy
  • Spurl
  • Y! MyWeb
  • БобрДобр
  • Мистер Вонг
  • Яндекс.Закладки
  • Текст 2.0
  • News2
  • AddScoop
  • RuSpace
  • RUmarkz
  • Memori
  • Закладки Google
  • Писали
  • СМИ 2
  • Моё Место
  • Сто Закладок
  • Ваау!
  • Technorati
  • RuCity
  • LinkStore
  • NewsLand
  • Lopas
  • Закладки - I.UA
  • Connotea
  • Bibsonomy
  • Trucking Bookmarks
  • Communizm
  • UCA

Связанные записи

Комментарии к статье "WordPress под микроскопом" (5) »

  1. [Ноябрь 27, 2008 20:23] Lecactus:

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

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

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

    Ответить на данный комментарий

    #1
    • [Ноябрь 27, 2008 21:02] Vladimir:

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

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

      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
  2. [Ноябрь 28, 2008 09:56] Сергей М.:

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

    Ответить на данный комментарий

    #3
    • [Ноябрь 28, 2008 10:43] Vladimir:

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

      Те же 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 раз!

      Ответить на данный комментарий

      #4
  3. [Декабрь 2, 2008 14:33] WP File Cache 1.0 | Ars Longa, Vita Brevis:

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

    Ответить на данный комментарий

    #5

RSS-фид комментариев к данной статье.
TrackBack URL: http://blog.sjinks.org.ua/wordpress/410-monstrosa-horribilis/trackback/

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

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

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

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