PHP Memcache потенциальные проблемы?

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

  1. Пишу систему обмена баннерами.
  2. Информация о баннерах хранится в базе данных.
  3. Существуют разные сайты с разным трафиком, загружающие php-скрипт, который будет генерировать код для этих баннеров. (чтобы баннеры отображались на сайте клиента)
  4. Когда баннер показывается впервые - он кэшируется memcache.
  5. Баннер имеет время жизни кэша, например, 1 час.
  6. Каждый час кеш обновляется.

Потенциальная проблема, которую я вижу в этой задаче, находится на шагах 4 и 6. Если у нас есть, например, 100 сайтов с большим трафиком, может случиться так, что скрипт имеет несколько экземпляров, работающих одновременно. Как я могу гарантировать, что по истечении срока действия кеша он будет регенерирован один раз и данные останутся неповрежденными?


person tftd    schedule 13.04.2011    source источник


Ответы (1)


Как я могу гарантировать, что по истечении срока действия кеша он будет регенерирован один раз и данные останутся неповрежденными?

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

// returns false if there is no value or the value is expired
result = cache_check(key)

if (!result)
{
    result = fetch_from_db()

    // set it for next time, until it expires anyway
    cache_set(key, result, expiry)
}

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

Как бы то ни было, memcache хорошо работает в кластерной среде, и вы обнаружите, что настроить что-то подобное несложно, поэтому это должно довольно легко масштабироваться до того, что вам нужно.

person Jimmy Sawczuk    schedule 14.04.2011
comment
В моей ситуации у кеша должно быть время истечения срока действия, потому что нет никаких операций, которые пользователи могли бы выполнять, а не читать комментарии гипотетически. Спасибо за информацию! :) - person tftd; 14.04.2011
comment
Согласен, ваша ситуация больше похожа на метафору данных о погоде, которую я использовал. Но алгоритм, который я изложил, должен по-прежнему работать для вашего случая, и он будет более безотказным, чем простое заполнение этого кеша в хронологическом порядке (хотя в дополнение к этому может помочь добавление хронологической популяции). - person Jimmy Sawczuk; 14.04.2011
comment
Только еще один вопрос - если я сделаю это с кодом выше, у меня будут проблемы с одновременным запуском скриптов? Если, например, 2 скрипта работают одновременно, как им удастся договориться, кто первым установит кеш, а кто должен его читать? Оба они увидят, что кэшированный результат не существует, и попытаются его установить. Приведет ли это к ошибке или проблеме? - person tftd; 14.04.2011
comment
Это вообще не должно быть проблемой - они оба, как вы сказали, будут читать из источника данных, и один перезапишет другой. Это не проблема, если вы не выполняете зависимые операции (такие как увеличение значений кэша и т. д.). Пока вы просто собираете данные и кэшируете их, эти данные должны быть одинаковыми за этот короткий промежуток времени. Если это не так, ограничьте границы ваших данных, чтобы это был предсказуемый интервал кэширования (поэтому, если вы запускаете скрипт в 12:00, учитывайте только данные, созданные до 23:59:59). - person Jimmy Sawczuk; 14.04.2011
comment
Еще раз спасибо за помощь Джимми! Все выглядит вполне логично :) - person tftd; 14.04.2011