Шаблоны для кэширования связанных данных - PullRequest
5 голосов
/ 29 сентября 2010

В настоящее время я разрабатываю основу приложения и ищу способы оптимизации производительности. Моя установка основана на платформе CakePHP , но я считаю, что мой вопрос относится к любому технологическому стеку, так как он относится к кешированию данных.

Давайте возьмем типичное пост-авторское отношение, которое представлено двумя таблицами в моей БД. Когда я запрашиваю базу данных для определенного сообщения в блоге, в то же время встроенная функциональность ORM в CakePHP также выбирает автора сообщения, комментарии к сообщению и т. Д. Все это возвращается как один вложенный массив с большой задницей. , который я храню в кеше, используя уникальный идентификатор для соответствующего поста в блоге.

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

Но что происходит, когда обновляется не основная сущность (в данном случае сообщение в блоге), а некоторые связанные данные? Например, комментарий может быть удален, или автор может обновить свой аватар. Есть ли какие-либо подходы (шаблоны), которые я мог бы рассмотреть для отслеживания обновлений связанных данных и применения обновлений к моему кешу соответственно?

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

Ответы [ 2 ]

2 голосов
/ 29 сентября 2010

Это довольно просто, записи в кеше могут быть

  • добавил
  • уничтожены

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

Если вы хотите проявить смекалку, вы можете сделать так, чтобы ваш объект кеша указывал их зависимости и также кэшировал время последнего обновления для ваших таблиц БД.

Тогда вы могли бы

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

Вы можете даже интегрировать вышеперечисленное в свой уровень персистентности.

EDIT:
Конечно, выше, для того, когда вы хотите иметь согласованный кеш. Иногда, и для некоторых данных, вы можете ослабить требования согласованности, и есть сценарии, где простой TTL будет достаточно хорош (для тривиального примера, если у вас есть ttl 1 сек, у вас должны быть в основном проблемы с пользователями и они могут помочь обработка данных, и с более высокими временами вы все еще можете быть в порядке - например, допустим, вы кэшируете список кодов ISO стран; ваше приложение может будет в порядке, если вы скажете, давайте кешируем это на 86400 секунд).

Кроме того, вы также можете отслеживать время предоставления информации пользователю, например,

  • скажем, пользователь видел данные A из кэша, и мы знаем, что эти данные были созданы / изменены в момент времени t1
  • пользователь вносит изменения в данные A (и делает их данными B) и фиксирует изменение
  • прикладной уровень может затем проверить, являются ли данные A все еще такими же, как в БД (если кэшированные данные, по которым пользователь принимал решения и / или изменения действительно были свежими)
  • если оно было не свежим, то возникает конфликт, и пользователь должен подтвердить изменения

Это имеет дополнительную стоимость чтения данных A из БД, но это происходит только при записи. Кроме того, конфликт может возникать не только из-за кеша, но также из-за того, что несколько пользователей пытаются изменить данные (т. Е. Это связано со стратегиями блокировки).

1 голос
/ 29 сентября 2010

Один из подходов к memcached - использовать теги (http://code.google.com/p/memcached-tag/).Например, у вас есть «вложенный массив с большой задницей», скажем, он включает информацию об авторах, саму запись и отображается на главной странице и в каком-то поле на боковой панели.Таким образом, он получает теги: frontpage, {auhothor-id}, sidebar, {post-id} - теперь, если кто-то изменяет информацию об авторе, вы сбрасываете каждую запись в кэше тегом {author-id}.Но это только одно решение, и только для Cache Backends, которые поддерживают теги, например, не APC (afaik).Надеюсь, что дал вам пример.

...