Кэширование фрагментов русской куклы с автоматически истекающими ключами

Вопрос основан на 2 статьях:
- Basecamp Next от DHH из 37 сигналов
- Расширенное кэширование в Rails от Адама Хокинса

Я немного растерялся из-за последствий использования русской куклы для кэширования, а именно:

  1. При использовании ключей с автоматическим истечением срока действия кажется, что каждый запрос приведет к доступу к базе данных для получения метки времени объекта - я что-то упустил? (Я понимаю, что в лучшем случае вы должны делать это только для ключа верхнего уровня в иерархии, но все же...)

  2. В первой статье они кэшируют список задач, а также каждый элемент задачи. Кэширование списка имеет смысл, так как экономит много времени (запрос БД для всех элементов). Но зачем кэшировать отдельные элементы? Вы уже идете в базу данных, чтобы получить метку времени Элемента, так что именно вы экономите? Генерация нескольких строк HTML?

  3. Во 2-й статье Адам кэширует фрагменты вида следующим образом: cache [post, 'main-content']...cache [post, 'comments']Когда комментарий добавлен, он меняет отметку времени публикации, и, следовательно, делает недействительными обе записи. Тем не мение, main-content не изменился - вы не хотите его регенерировать!!! Как можно было бы сделать недействительными только комментарии. (Это на самом деле очень распространенный пользовательский случай - модель, которая имеет несколько логически независимых частей: сам объект, различные ассоциации, данные в каком-то другом хранилище и т. Д.)

Мне кажется, что кэширование русской куклы имеет смысл только тогда, когда у вас есть глубокая иерархия вложенных объектов (в basecamp у вас есть проект -> список задач -> список задач -> список элементов). Однако, если у вас мелкая иерархия, лучше просто сделать недействительность самостоятельно.

Любая обратная связь будет оценена!
Благодарю.

2 ответа

Решение
  1. Верхний уровень должен попасть в базу данных. Вы можете избежать этого, сохранив отметку времени в отдельной записи кэша с ключами по модели и идентификатору. Один из комментаторов статьи 1 (Мануэль Ф. Лара) предложил то же самое: "Есть ли другой тайник, подобный проектам /15-кратный, где у вас всегда есть последняя метка времени для списка проектов?"

  2. Я думаю, что вы правы насчет "самого низкого" уровня во вложенности. Возможно, вам придется провести некоторое тестирование, чтобы увидеть относительную производительность доступа к БД по сравнению с визуализацией крошечной частичной.

  3. Еще один хороший момент. Согласно документам, если вы передадите символ :touch он обновит этот атрибут в дополнение к updated_at - может быть, есть способ пропустить изменение Post#updated_at и только обновить столбец, как comments_updated_at, Тогда вы можете использовать последний для кеширования. Но если вы пытаетесь избежать доступа к БД, вам придется хранить еще один ключ кеша для этой метки времени (как в #1 выше).

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

  1. Да. Но, как правило, сценарии как в лучшем, так и в довольно удачном случае встречаются довольно часто.
  2. Да. В некоторых приложениях, которые я разрабатываю, рендеринг представления занимает в 10-20 раз больше времени, чем выполнение запросов. Посмотрите на свои критерии.
  3. Если рендеринг поста является дорогостоящим, вы можете не хотеть трогать пост, а вместо этого составить ключ кеша списка комментариев из [@post.comments.max(:updated_at), @post.comments.size],
Другие вопросы по тегам