Теория кэша (часть вторая, практическая, дополненная)

    Это вторая, дополнительная (upd: дополненная), часть моей статьи посвященной кэшированию информации при веб-разработке. Первая имеет название Теория кэша.

    UPD: После многочисленных коментариев я сильно переработал статью, внес в неё больше конкретики и примеров, а так же убрал спорные моменты (например, касательно memcached). Спасибо всем, за конструктивную критику.

    В данной статье я попытаюсь описать практические стороны кэширования, ориентированные, прежде всего, на сайты и системы управления контентом. Сразу предупреждаю, это мое личное мнение, которое не претендует на истину в последней инстанции. Большинство терминологии — моё, вы можете использовать его, если считаете нужным на своё усмотрение. Конструктивная критика приветствуется.

    Итак.

    Что нужно кэшировать


    Как ни покажется странным, кэшировать целесообразно далеко не всё. Кэширующие механизмы сами по себе потребляют ресурсы, и если скажем, информация изменяется так же часто, как и выводится, то смысла кэшировать эту информацию никакого нет (например, системы статистики). Так же не стоит кэшировать процессы, которые и без того протекают быстро.

    Например: Данные изменяются раз в 1 секунду. Происходит запрос на получение этих данных раз в 2 секунды. Данные кешируются 0,1 секунды, а отдаются из кеша 0,2 сек. Тогда при обращении к данным всегда будет получатся ситуация, когда нам потребуется перестроение данных — которая будет занимать 1 + 0,1 сек. А отдаваться данные из кеша практически не будут. Мы проигрываем эти 0,1 сек из-за кеша.

    Первое, что должно быть кэшировано – информация, которая вычисляется крайне долго и ресурсоемко, и используется очень часто. Применимо к сайтам – это результаты выполнения модулей (или приложений), которые используют сложные запросы к базе данных. Кроме этого к ресурсоемким процессам относятся обращения к внешним ресурсам, использующим установку соединения (сокеты, curl и др.), а так же работу с большим объемом сложных данных (парсинг шаблонов, работа с изображениями и др.).

    Куда нужно кэшировать


    Далее в порядке убывания по скорости доступа к кэшу:

    Память. Это memcached, APC, XCache и другие подобные технологии в том же духе. Они (как правило) предоставляют максимальную скорость доступа, но объем сильно ограничен. Память не подходит для больших данных, но хорошо подходит для сравнительно небольших объемов наиболее часто используемых данных, таких как скажем распарсеные шаблоны и др.

    Например, у нас используется SAX-парсер. Он медленно парсит шаблоны. Сделаем следущее:

    При запросе к шаблону сначала проверяется, находится ли он в памяти. Если да, то вытаскивается, делается unserialize и отдается. Если нет, мы создаем объект (парсим шаблон), сериализуем (serialize) его и помещаем в память (имя обозначим как хэш-код от пути файла). Осталось только решить, на каком основании будем обновлять данные кэша. Это можно сделать 2-мя способами:

    1. Мы вообще не будем проверять изменения, а кэш будет существовать некоторый прмежуток времени, скажем, обновляться раз в час. Соответственно, при физическом изменении шаблона они вступят в силу максимум через час.

    2. Мы будем контролировать изменения шаблона по времени его последнего сохранения. Для этого нам понадобиться еще одна переменная в памяти — время заненсения данных к кэш (можно назвать как имя переменной шаблона в памяти с префиксом time). Соответственно, мы должны будем её устанавливать равным текущему времени при сохранении объекта шаблона в памяти. Далее, при обращении к шаблону мы сначала сравниваем время изменения файла шаблона (filemtime) со временем закешированного в памяти. И если время изменения шаблона больше времени кэша, то выполняем его обновление. При таком подходе кэш может существовать вечно, если сам шаблон никогда не будет изменятся. Но как только он изменится, перестроится сам кэш.


    Файловая система. Наиболее частоиспользуемый способ. Но и тут есть свои подводные камни. Доступ к файлам существенно замедляется, в директории их становится очень много (чем больше файлов, тем меньше скорость), а на некоторых файловых системах вообще существуют ограничения на количество (ext2 – 32768 файлов в директории). За этим надо строго следить. Например, нельзя для кэширования каких-то табличных данных сваливать их в одну директорию и делать названия равными первичным ключам. У вас такая схема просто когда-нибудь переполнится.

    Вот так можно это сделать на php:
    <?
    function saveCache($name, $data)
    {
    $hash = sha1($name);
    $chunks = str_split($hash, 4);
    $cache_dir = CACHE_DIR.'/'.$chunks[0].'/'.$chunks[1];
    if (!is_dir($cache_dir)) mkdir($cache_dir, 0775, true);
    return file_put_contents($cache_dir.'/'.$hash, serialize($data));
    }
    ?>


    База данных. Тоже может быть использована для кэша. У базы данных есть сильное преимущество – выборка посредством SELECT. Если данных немного, но они зависят от огромного количество условий, то использование БД вполне оправдано, особенно если грамотно создать индексы в таблице. Напрмер, таблицу в БД можно использовать как хранилище результата выборки сложного запроса с объединением многих больших таблиц с применением большого количества условий. Саму выбоку можно поместить во временную таблицу, и выбирать данные уже из неё. Условия выборки будут тоже сложные, но многочилсенных JOIN уже не будет, что повысит скорость (особенно если используется ENGINE MEMORY применимо к MySQL).

    Еще одно достоинство кэширование в БД – это упреждающая подготовка кеша. Скажем, можно первым и единственным запросом вытащить все данные для кэширования на конкретной странице и потом использовать уже их, если это нужно. Кэширование в БД конечно медленное, но грамотная организация может серьезно повысить эффективность использования кэша. И еще – существует SQLite, которая тоже хорошо подходит для этого. Особым эксклюзивом считается создание самой базы SQLite в memcached.

    Использование БД для кэша мне представляется редким вариантом. Это больше возможность, нежели практическое применение. Просто, не стоит её упускать из вида.

    Как нужно кэшировать


    Для кэширования обычно используются хеширование строки, содержащей все параметры от которых зависит кэш. Если хотя бы какой-нибудь параметр изменился, то и сам хэш-код изменится. Для хранения в файловой системе от хеша «отрубаются» первые несколько символов и создаются соответствующие директории, чтоб не было переполнения файловой системе. Время изменения для файловой системы – это время модификации файла, для БД нужно отдельное поле, для памяти – отдельный параметр (см. пример выше).

    Без хеш-кода у вас строка зависимостей может сильно распухнуть, тем более, если их много.

    Развернутый пример:

    Скажем, в базе 50000 статей. Запрос к базе на получение одной статьи работает долго, что не удивительно с таким объемом. Простой счучай — у нас нет JOIN других талиц.

    Делаем следущее — прописываем некоторую зависимость в таблицу зависимостей. Таблица у нас может быть простым массивом, который сериализован и положен в файл. Это нужно для проверки актуальности кэша, что бы решить перестроить закешированные данные в связи с их изменением или можно использовать имеющиеся в кэше. При любом изменении нашей таблице в БД обновляем эту зависимость в таблице, т.е. устанавливаем время равное текущему. Объемы у нас большие, значит лучше использовать кеширование в файловую систему.

    Кладем результат выполнения в кэш. При повторном запросе, сравниваем время изменения файла кэша с временем из таблицы зависимостей. Если время файла кэша меньше, перестраиваем — иначе отдаем то что в кэше.

    Теперь. Если у нас в одной из 50000 статей мы изменили одну букву, то кэш дропнется для всех, что не является эффективным. Попробуем этого избежать:

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

    Кэш ленты явно зависит от заблицы зависимостей (и неявно зависит от каждой отдельной статьи), т.е. времени последнего изменения таблицы со статьями в БД. Но отдельно взятая статья условно зависит от этого времени, т.е. она зависит от него при условии, что изменилась именно эта статья. Поэтому при показе отдельной статьи мы не будем использовать это время: если есть кэш статьи, то его покажем. Если нет — то построим статью и положим в кэш. Но, важное условие при этом — при редактировании отдельно взятой статьи мы должны удалить её кэш.

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

    На что еще нужно обратить внимание


    При кэшировании в файловую систему нельзя весь кэш пихать в одно место. То есть для каждых отдельных объектов лучше использовать свой директорий, например для страниц /cache/pages, для пользователей /cache/users и так далее. Это нужно, чтоб случайно данные не совпали. Допустим, у вас 2 разных сущности, с одинаковыми id. Так получилось, что надо сохнранить кэш обоих только по этому id. Хэш в обоих случаях будет одинаков, тем самым возникнет конфликт. Но если для каждой сущности будет выделен своё место, этого не будет.

    При удалении элемента нужно не забывать удалять и сам кэш. Иначе со временем он распухнет из-за большого количества неактуальных данных. Как вариант – периодическое физическое удаление всего кэша.

    Еще существует такая штука как «быстрый» кэш (FastCache, терминология моя). Идея FastCache заключается в том, что бы закэшировать наиболее часто используемые объекты наиболее быстрым образом, отметая все остальное. Например, можно положить полностью созданную главную страницу в память и отдавать её, если ничего не изменилось, незалогиненым пользователям. Основная нагрузка идет именно на главную страницу, поэтому это может сильно разгрузить ресурсы.

    Заключение



    Как правильно заметили в одном из комментариев прошлой статьи – кэширование — это часть оптимизации сайта, которое особенно эффективно при высоконагруженных системах. Эффективность работы сайта не состоит из эффективности одного только кэша. Более того, иногда он может быть вообще лишним, поэтому стоит хорошо подумать, прежде чем «прикручивать кэш». Если, например, посещаемость сайта менее 1000 человек в день о кэшировании можно не думать. Хотя конечно, смотря какой сайт.

    Спасибо за прочтение!
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 60

      0
      Исправьте: «часть», а не «чась»
        +13
        В практической части наверно нужно привести примеры реализации.
          +4
          Простой пример кэша «ручками» для статики:
          У нас есть какая-то директория, защищенная на чтение для пользователя (.htaccess).
          Пользователь запрашивает какой-то урл (как известно он уникальный)
          Хэшируем урл md5 получаем хэш
          Проверяем, есть ли в директории файл с именем хэш или хэш.gz
          Файл есть — выдаем с нужными заголовками
          Если файла нет — при помощи ob_start() и его поддерживающих функций собираем весь код страницы.
          Жмем если надо весь код gz со степенью сжатия 6 (наиболее оптимально) получаем ужатый весь код
          Записываем ужатый весь код в директориия/хэш.gz или директориия/хэш
          Выдаем пользоветелю ужатый весь код или весь код

            +2
            Привет, Артемий. Все что будет сказано в этом комментарии имеет отношение исключительно к нагруженным проектам.

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

            Что нужно кэшировать
            кэшировать нужно абсолютно всё. В твоём примере данные извлекаются за 0.1 секунды, а из кэша отдаются за 0.2. Проблема в том что тест синтетический — на нагруженном проекте данные будут извлекаться за 0.9, а из кэша по прежнему отдаваться за 0.2, разумеется это зависит от того какие именно данные и куда производится кэширование, будем считать, что мы правильно определили куда кэшировать эти конкретные данные, и даже при этом тайминги будут различаться примерно так. Суть в том, что в твоей теории ты забываешь об окружении, а окружение — это уже практика.

            Куда нужно кэшировать
            Память — это очень правильно. Для кэширования объектов. Тут нет замечаний.

            кэширование в файловую систему.
            Во-первых, смотрим сюда en.wikipedia.org/wiki/Ext2 — ты говоришь о лимите файлов — теоретический лимит там указан как 1.3 умножить на 10 в 20 степени. число 32768 — это максимальное количество директорий внутри директории, но не файлов.
            Так или иначе если в генерации страницы участвует 100-300 объектов (каждый из которых закэширован в файловую систему в виде отдельного файла) на нагруженном сервере эта генерация займет значительно больше времени чем вычитывание этих объектов из памяти — почему больше написано чуть ниже про файловые бд.

            Файловые базы данных — TDB, SQLite, DB4
            На действительно нагруженных проектах сервера выполняют невероятное количество операций с диском, особенно если часть статики крутится на одном сервере с пхп. И любое обращение к памяти «под нагрузкой» будет в «сто раз» быстрее чем обращение к диску, так как диск постоянно занят. Но попробуем пренебречь этими фактами и допустить что на самом деле данные меняются один раз в сутки, после изменения данных мы генерируем кэш и работаем только с ним оставшиеся 23 с копейками часа — это как раз теория. На практике нет — данные меняются очень часто. Поэтому кэширование в файлы будет работать лишь очень короткое время, затем вся польза такого кэширования будет сведена на нет.

            О твоем развернутом примере.
            Во-первых — 50 000 статей это мелочь, это такая мелочь что не стоит и думать о времени извлечения одной статьи из базы. Думать стоит о построении коллекций, но даже об этом при правильной реализации хранения в базе думать не приходится — ведь хранить сам контент по которому не строятся коллекции в одной таблице с временем публикации глупо. Во-вторых, приведенная схема, основанная на времени изменения таблицы в базе мне очень знакома, и ты сам знаешь почему. К сожалению она ущербна, как ты и написал, инвалидация кэша происходит при изменении одного итема. В-третьих поддержание зависимостей на уровне пхп кода достаточно сложная задача для программиста и не поддается автоматизации — пробовали, знаем. Итого: пример совершенно не разъясняет сути стратегии и является глубоко теоретическим.

            О том «на что нужно обратить внимание»
            Про кэширование в файловую систему уже выше написал. кэширование разных объектов нужно просто организовывать так, чтобы при формировании хеша использовался и айдишник объекта и его имя. Далее — твоё утверждение, что основная нагрузка приходится на главную страницу — абсолютно неверно. Главная страница, как правило, кэшируется и очень быстро отдаётся, настоящая нагрузка распределена по всем остальным страницам сайта, в этом и заключается основная проблема упреждающего кэширования и сильно распухших кэшей — мы никогда заранее не знаем на какую именно страницу сайта придет пользователь, или робот поисковой системы. В результате тратим время на генерацию этих страниц и кэшируем редко запрашиваемые страницы, получая распухший кэш и настоящую нагрузку на сервер. Твой вариант с периодическим удалением всего кэша в автоматическом режиме не реализуем. Сейчас ты можешь сказать, что кэш можно удалять в зависимости от того сколько места он занимает на диске, сколько времени прошло с последнего удаления и так далее, но все это не более чем костыль и к стабильности отношения не имеет.
              0
              а вот если бы были примеры практической реализации, то вышеприведенные проблемы автор бы сам заметил.
          0
          Спасибо за статьи, интересно.

          По поводу того, что кэшировать постоянно изменяющиеся данные — не целесообразно — немного не соглашусь, тут есть нюансы.
          Если получить данные рессурсоёмко, а запрашивают их очень часто, например 100 раз в секунду, то может смысл и их кэшировать, например, кэш на 1 секунду. При этом рессурсоёмкая операция будет выполняться 1 раз в секунду, а остальные 99 — быстро. А от того, что данные могут быть актуальны по состоянию на 1 секунду назад — не всегда важно.

          Повторюсь, это не правило, а лишь частный случай, который показвает, что даже динамические данные может иметь смысл кэшировать.
            0
            Ещё добавлю

            > можно положить полностью созданную главную страницу в память и отдавать её

            Да, о таком способе когда-то писал Spectator. Предлагалось использовать в качестве ключа кэша URI страницы. Способ не для всех проектов, но по своему хороший.
              0
              Не забываем про GET/POST и динамические блоки страницы, которые зависят от серверных параметров и событий, иначе может получиться что пользователь не увидит, ну например, смены дня/ночи.
                0
                Я написал, «Способ не для всех проектов, но по своему хороший».
              0
              Да, было немного не правильно выражено. Я исправил.
              +4
              Ну, или если вы все-таки каким-то чудом настроите у себя FastCGI

              Автор, если у вас есть какие-то проблемы с настройкой FastCGI, то это не значит, что они есть у других.
              Кстати, в MySQL существует Engine MEMORY, которая вроде тоже использует для таблицы память.

              Подтверждаю, она действительно использует память :)
              Вообще это чисто моя идея, но предполагаю что не я один её придумал, хотя реализаций я не видел.

              Никто не спорит, что это чисто ваша идея.

              Ну а вообще спасибо за статью, посмеялся :)
                +4
                Спасибо, я внес соответствующие поправки. Рад, что вас развеселил.
                  +3
                  Напишите свою статью про кэш, чтобы все прочитали и заапплодировали.
                  А то кричать о собственной осведомленности могут многие, а решиться что-то написать почему-то не могут.
                  Поэтому и приходится радоваться тому, что есть.
                    +1
                    Удивительно. Давно не видел таких внятных комментов с таким количеством минусов :)
                    +10
                    Мне одному кажется, что пост откровенно слабый, с кучей общих слов и совсем без конкретики?
                      +3
                      просто это пост для тех, кто ещё не «занимался» кешированием. Для людей с начальным уровнем, вполне полезный пост.
                        +3
                        Боюсь, что людям с начальным уровнем этот пост может добавить непонимания. Автор как-то очень лихо свалил в одну кучу кеш SQL, memcached и файловый кеш. Все эти три способа могут применяться одновременно и для разных (!) целей.

                        То что написано про memcached это, простите, откровенный бред. Читать про то что это такое и зачем нужно лучше из первый рук.
                          +1
                          > могут применяться одновременно и для разных (!) целей
                          Не понял вас. Я где-то сказал, что должно применяться только в отдельности и для одной и той же цели? Довод неуместен.

                          > memcached это, простите, откровенный бред
                          Будте добры, аргументируйте свои слова. Я положительно настроен на конструктивную критику, если вы сможете объяснить, почему вы так считаете — и соглашусь и исправлю написанное.
                            0
                            По первому пункту. Просто нельзя так сваливать в кучу все типы кеша. А уж если свалилось, стоит написать для каких целей уместно использовать тот или иной способ.

                            Второй. www.danga.com/memcached/
                      • UFO just landed and posted this here
                          +2
                          Та часть была откровенно безграмотной и провальной. Я до сих пор в недоумении, почему сообщество ее так высоко оценило. Думаю, это объясняется «крутым названием»: Теория кэша.
                          Если вчитаться — понимаешь, что автор плохо понимает то, о чем пишет (касается не только кэша и его теории(???), но и ЯП). В своих постах в прошлом топике я свое мнение аргументировал. Наше обсуждение статьи с автором вы можете прочитать, если захотите.

                          • UFO just landed and posted this here
                              0
                              Сообщество оценило актуальность темы и не более. То есть, оценками дали понять, что тема востребована.
                                0
                                Т.е. судило по названию топика, но никак по его содержанию (потому что не читало?).
                                Я как раз про это и говорю: за умным названием скрываются пространные рассуждения, порой, ошибочные и неграмотные.
                                Странная оценка.
                                  0
                                  Ну, во всяком случае, лучше ничего нет. А для размышлений на первое время пойдёт :)
                                  Взяли бы и написали что-то грамотное, правильное. Это же теория. А их доказать ещё нужно. Вот слово «практическая» часть, конечно зря написано было изначально.
                            +3
                            Я не признаю такой критики как «плохо», «слабо», «вяло» и так далее. Скажите, с чем конкретно вы не согласны. Кажется весь пост — слабым — флаг вам в руки — напишите такой, который бы не был таковым. Я только обеими руками за.
                            +3
                            При кэшировании в файловую систему нельзя весь кэш пихать в одно место. То есть для каждых отдельных объектов лучше использовать свой директорий, например для страниц /cache/pages, для пользователей /cache/users и так далее.


                            В таком изложении это напоминает народную примету. Думаю, подобные вещи стоит описывать развёрнуто.
                              0
                              «Memcached нужен больше для обмена данными между приложениями»
                              Не только. Мемкэш хорошо подходит для распределенного кэша (по нескольким серверам).

                              «Файловая система. Наиболее надежный и быстрый способ.»
                              Быстрее памяти?
                                0
                                > Мемкэш хорошо подходит для распределенного кэша
                                Да, я это и имел ввиду. Опять плохое выражение. Спасибо, что обратили внимание.

                                > Быстрее памяти?
                                Знаете, говорите что хотите, но когда я проверял работоспособность memcached (речь только о memcached), оно показало, что обращение к нему чуть-чуть быстрее, чем к файловой системе. Тут ключевое слово «И». Да, я считаю, что файловая система — наиболее надежный И быстрый (в совокупности) способ.
                                  +1
                                  Memcached отлично использовать для тяжёлых запросов, часто возникает необходимость выгрузить данные в кеш которые к примеру часто используются но которые можно обновлять с определённой периодичностью — почемуто только для множества серверов? Я боюсь с такой категоричностью как раз таки и новичков вы введёте в заблуждение.
                                  С файлами — известно что include это очень тормозная операция, особенно когда их много, а в случае с кешем часто бывает что нужно раскидывать различные данные в кеш чтобы легче было с ними манипулировать.
                                  Файловый кеш неплохой вариант для сайтов где нет возможности установить memcache — к примеру для массовых решений (например софт который обязан работать на всех серверах).
                                    0
                                    «Да, я считаю, что файловая система — наиболее надежный И быстрый (в совокупности) способ. „
                                    А как вы измеряли надежность представленных способов?
                                      –4
                                      Просто. После перезагрузки сервера Memcached данные насколько я знаю теряются. Поправте меня, если это не так. А с фалами такого не будет. Только исходя из этого.
                                        0
                                        Тогда я бы на другую чашу весов добавил то, что за файлами вам надо приглядывать самому, а мемкэш удаляет устаревшие ключи без вашего участия. Поэтому его надежность выше.
                                          –4
                                          Хорошо, вы меня убедили.
                                            0
                                            Както я использовал файловый кеш для кэширования.
                                            Это было давно, никаких APC и не было.
                                            Время жизни кеша было от 20 секунд до 2х часов.
                                            Есно дело файлы не стирались, просто при фетче filemtime проверялось.
                                            Через три года работы в папке было 160гигов и стиралась она ПОЧТИ ТРИ ЧАСА(тоесть под миллион гдето файликов)!

                                            Сейчас файловый кеш я использую только для подсистемы mirror
                                            Снегерили страничку для человека(неавторизованного)- сохранили.
                                            Снегерили страничку для пользователя(авторизованного) — удалили
                                            Надо выдать страничку, но зашел робот или сайту кирдык(админ «мучиет» базу данных\мемкешед грухнулся\апача 502...) — выдали ее из кеша.

                                            Сайт(мой) сам по себе может выдавать гдето 200-300 страниц в секунду(конект к базе, сборка страницы и тд)
                                            Файловый кеш может выдавать тысячи и при этом ковыряться в носу.
                                            Как не странно 70% посетителей сайтов — это роботы (я то знаю).
                                            Выдавайте им страницы из файлового кеша до конекта к базе, а лучше прям нгинксом и нагрузка на сервер упадет на 70%…
                                            70% это дохрена!
                                  • UFO just landed and posted this here
                                      0
                                      Предвижу трилогию автора по кэшу. Жду =)
                                        +1
                                        Танго и Кэш =) Вскоре следует ожидать статью под названием «Теория Танго»! Заранее извиняюсь за мой искрометный юмор!
                                        А по существу, мне было бы намного интереснее узнать про организацию системы кэширования в распределенных средах и что делать с кэшированием при конкурентных запросах. Может быть в третьей части?
                                          0
                                          Самое интересное там, насколько я понимаю — « не сразу устаревающий» кэш.
                                            0
                                            Извиняюсь за нескромный вопрос… там это где?
                                              0
                                              В кэшировании распределенных сред
                                          +2
                                          Уважаемый, enartemy, я прочитал вашу второю статью. Прочитал не один раз, как и первое ваше творение на эту тему.

                                          Как ни покажется странным, кэшировать целесообразно далеко не всё. Кэширующие механизмы сами по себе потребляют ресурсы, и если скажем, информация изменяется так же часто, как и выводится, то смысла кэшировать эту информацию никакого нет (например, системы статистики). Так же не стоит кэшировать процессы, которые и без того протекают быстро.

                                          То, что не надо кэшировать все подряд — согласен. Остальную часть я вам предлагаю удалить.
                                          Главным аргументом в пользу кэширования должна служить не скорость изменения или вывода информации, за размер затрат на получение и вывод информации.
                                          Как я уже писал вам в прошлой статье, многие системы предоставления отчетов, статистики работают долго. Чем долбить несчастный сервер чудовищными запросами пользователей, проще иметь под рукой кэш запросов, хоть в файле, хоть в памяти. Этот кэш будет переодически обновляться. С одной стороны, пользователям не надо ждать по 10-20 минут, пока сервер потеет и тужится выдать результат, выполняя десятки ресурсоемких однотипных операций. Есть и минус — данные в кэше будут всегда немного устаревшими.

                                          Кроме этого к ресурсоемким процессам относятся обращения к внешним ресурсам, использующим установку соединения (сокеты, ...)

                                          Сокеты быстро работают, очень быстро. А для того, чтобы не тратить время на соединения, давно придуман пул соединений. Опять же, неверный вывод. То, с чем вы установили соединение может долго отвечать, но применение кэша только из-за того, что устанавливается соединение нецелесообразно.

                                          Память. Это memcached, APC, XCache
                                          Если вы пишите для новичков, расскажите, что это. Потому что ваша статья для знающих людей — бесполезна.

                                          База данных.
                                          Я вообще ничего не понял. Вы предлагаете использовать БД для хранения экша, или говорите о кэшировании запросов и помещении таблиц в память? Какая-то манная каша повисла на абзаце.

                                          Как нужно кэшироватьМного слов ни о чем. Опять теория и рассуждения.

                                          enartemy, вы старались, вам наверняка обидно, что я так критикую ваш труд.
                                          В общем, вы разберитесь в том, что пишите.
                                            0
                                            В общем, вы разберитесь в том, что пишите.

                                            А лучше представьте рабочие примеры, которые применяются в web-разработках с тестами внутри. Заодно и каша в вашей статье пропадёт.
                                              0
                                              Вот я тоже уже думаю, что без рабочих примеров статья выглядит кашей. Для меня это естественно не так, но что уж поделать.
                                              0
                                              Уважаемый, yaneblog.

                                              > То, что не надо кэшировать все подряд — согласен. Остальную часть я вам предлагаю удалить.

                                              Смотрите. Данные изменются 1 раз в секунду. Данные извлекаются 1 раз в 2 секунды. При получении данных всегда будет необходимо их обновление — никогда не получится так, что мы можем взять данные из кэша. Смысл? Процесс протекает за 0,01 секунды. Кеш срабатывает 0,02 секнуды. Нужно кешировать?

                                              Если я удалю вторую часть — тогда будет действительно каша. «не надо кэшировать все подряд» — а что конкретно не надо-то.

                                              > Этот кэш будет переодически обновляться.
                                              Это называется кеширование по времени, я упоминал про него в прошлой статье.

                                              > Сокеты быстро работают, очень быстро.
                                              Для меня быстро — это тысячные доли секунды. Сокеты работают десятые доли секунды. Да быстро, если опреровать объемами 10-20 минут, но эти времена не применимы к генерации веб-страницы на-лету. Это же касается «применение кэша только из-за того, что устанавливается соединение нецелесообразно» — иногда и это бывает критичным.

                                              Поймите, это Веб. Здесь нет 10-20 минут. Будете вы 20 минут ждать, пока страница хабра откроется? А вы представте только какая нужна база данных и сколько должно быть к ней запросов, что бы отобразить кждай кусочек страницы. И что же, она гененрируется 10-20 мин? Если она 10 сек генеритья, это уже будет раздражать.

                                              > Если вы пишите для новичков, расскажите, что это.
                                              Я не могу рассказывать вообще все, чтоб вообще все всем было понятно. Это невозможно. Что уж вы так плохо о людях думаете, они не могут найти сами информацию, если их это заинтересовало?

                                              > База данных. Я вообще ничего не понял.
                                              Я говорил о применении базы данных для хранения закешированных результатов.

                                              Уважаемый yaneblog, вы тратите уйму времени, что бы прочитать это все, осмыслить и высказать все ваши многочисленные замечания. Используйте это более разумным способом — напишите об этом статью. Хорошую. Развернутую. И без каши. Назовите её, если хотите, разумным ответом на мои выдумки — я не обижусь. Тогда может у нас и получится диалог. А пока — это спор слепого с глухим.

                                                0
                                                А, вот и мой пропавший коментарий… Странно, он появлся спустя неготорое время. Глючит хабр, глючит…
                                                  0
                                                  это кэширование вывода =)
                                                0
                                                Блин… Вторй за уже така ситуация — пишу коммент, где все расписываю, а потом он пропадает, причем первый раз было в прошлой статье… Ладно, смысл такой.

                                                Уважаемый yaneblog. Я посмотрел ваши статьи, мне они понравились. Ну так чем со мной спорить, — серьезно — напишите свою статью об этом. Хорошую. Развернутую. Без каши, как у меня. Заодно я увижу насколько вы хорошо разбираетесть в проблеме. Это совершенно без прикола. Тогда есть смысл продолжать полемику, а пока — это спор слепого с глухим, потому что вы считаете — что я не разбираюсь, а я считаю — что вы не разбираетесь.

                                                Я честно ответил на все ваши замечания в пропавшем коменте, но второй раз этого делать не буду, уж извините.

                                                Жду вашей статьи.
                                                  0
                                                  Пропадания комментов при их отправке, это ужасно. Сам пару раз так обламывался.
                                                  Хорошо, я напишу статью с примерами из производственной практики.
                                                –15
                                                ноут за такую статью не получить =)
                                                  0
                                                  Я полагаю, автор старался не за ноутбук. Работа проделана, работа спорная, но как говорил один великий человек — «в споре рождается истина». Спор есть, будем рожать истину :)
                                                    –8
                                                    кармадрочеры атакуют
                                                  • UFO just landed and posted this here
                                                    • UFO just landed and posted this here
                                                        0
                                                        >Использование БД для кэша мне представляется редким вариантом. >Это больше возможность, нежели практическое применение.
                                                        Тем не менее, столкнулся с ней как-то раз воочию. Часть логики была вынесена в PL/SQL хранимые процедуры, и кэшировались результаты этой части как раз в базу.
                                                        • UFO just landed and posted this here
                                                            0
                                                            посыл не тот

                                                            главное не инструкция, а мозги у имплементирующего. Кеш это как дикая рекурсия — проблемы никогда не видно невооруженным глазом, надо ясно представлять что делают железки по вашему заказу.
                                                              0
                                                              тут многие пишут, что «статья слабая» и «много воды». и они — правы.

                                                              1. совсем не понимаю, как кэшировать в файле всю сериализованную таблицу вообще могла прийти в голову?

                                                              2. нужно сразу определиться, какие у нас нагрузки, сколько у нас серверов и какие объёмы данных. например, если мы кэшируем данные в файлах, но в file system cache нашей операционной системы они все не помещаются, то производительность резко упадёт, а (на хоть сколько-нибудь загруженной системе) винчестер через несколько недель тупо выйдет из строя.
                                                              ещё нужно определить узкое место — веб-машина (которая генерирует страницу для клиента) или база. ведь кэш мы можем наращивать сколько угодно, а вот mysql при более чем 500 (ну, тысяче) запросах в секунду работает уже не всегда и не у всех. далее я буду предполагать, что процессора нам не жалко, а базу — жалко.

                                                              3. и почему цифры приведены такие странные? понятно, что они «демонстрационные» и «для наглядности», но нельзя наглядностью оправдывать взятые совершенно с потолка цифры.
                                                              запрос к мемкэшу выполняется порядка 0.001 — 0.01 сек. зависит от задержки в сети.
                                                              запрос к базе выполняется, конечно, дольше. не забываем про то, что к БД нужно подключиться, а БД должна ещё сделать выборку из своей системной таблицы с пользователями и проверить ваш пароль (а если это mysql, настроенная каким-нибудь жопоруким кретином, то ещё и сделает запрос на получение символического имени того хоста, к которому вы к ней обращаетесь) — это в том случае, если без persistent. И, вне зависимости от того, persistent ли соединение или нет, БД будет делать выборку по таблицам привелегий на базу данных, на таблицу, к которой вы обращаетесь, и на колонки этой таблицы — всё это занимает время.

                                                              4. вообще, стандартная стратегия кэширования довольно проста и работает в 99% случаев.
                                                              запросы вида «select * from table where id=123» — кэшировать с ключом table_123. при update/delete из кэша — удалять.
                                                              запросы вида «select * from table where some_field=r5283r78» — либо не кэшировать, либо поменять на «select id from table where ...» и далее выбирать уже эти id'ы с помощью мемкэшевского multiselect'а и (если там чего-то не оказалась) второго запроса к базе, складыя его результаты в кэш тоже.
                                                              сложные поисковые запросы либо не кэшируются вообще, либо (если это критично) кэшируются на небольшое время (с ключом типа «search_».md5(serialize($serachParams))), но кэш таких поисков никак не обновляется.
                                                                0
                                                                а, да.
                                                                APC, естественно, быстрее, чем Memcache. раза в 2, насколько я помню. мемкэш работает через сокеты, а APC — через shared memory. НО: у APC кэшированные объекты хранятся с помощью односвязаного списка, т.е. время операций с кэшем линейно зависит от количества объектов. и, если закэшировать 10000 объектов (которые могут быть мелкими и занимать даже меньше 128 мб), то мемкэш начнёт серьёзно обгонять APC. в мемкэше всё хранится с помощью хэш-таблицы и, вероятно, какого-то дерева в случае хэш-коллизий. время в худшем случае пропорционально логарифму от количества объектов, что в реальном мире означает константу.

                                                                у XCache такой проблемы, как у APC, нет.

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

                                                                  ещё раз извините.

                                                                Only users with full accounts can post comments. Log in, please.