Кэширование фрагментов русской куклы с автоматически истекающими ключами
Вопрос основан на 2 статьях:
- Basecamp Next от DHH из 37 сигналов
- Расширенное кэширование в Rails от Адама Хокинса
Я немного растерялся из-за последствий использования русской куклы для кэширования, а именно:
При использовании ключей с автоматическим истечением срока действия кажется, что каждый запрос приведет к доступу к базе данных для получения метки времени объекта - я что-то упустил? (Я понимаю, что в лучшем случае вы должны делать это только для ключа верхнего уровня в иерархии, но все же...)
В первой статье они кэшируют список задач, а также каждый элемент задачи. Кэширование списка имеет смысл, так как экономит много времени (запрос БД для всех элементов). Но зачем кэшировать отдельные элементы? Вы уже идете в базу данных, чтобы получить метку времени Элемента, так что именно вы экономите? Генерация нескольких строк HTML?
Во 2-й статье Адам кэширует фрагменты вида следующим образом:
cache [post, 'main-content']
...cache [post, 'comments']
Когда комментарий добавлен, он меняет отметку времени публикации, и, следовательно, делает недействительными обе записи. Тем не мение,main-content
не изменился - вы не хотите его регенерировать!!! Как можно было бы сделать недействительными только комментарии. (Это на самом деле очень распространенный пользовательский случай - модель, которая имеет несколько логически независимых частей: сам объект, различные ассоциации, данные в каком-то другом хранилище и т. Д.)
Мне кажется, что кэширование русской куклы имеет смысл только тогда, когда у вас есть глубокая иерархия вложенных объектов (в basecamp у вас есть проект -> список задач -> список задач -> список элементов). Однако, если у вас мелкая иерархия, лучше просто сделать недействительность самостоятельно.
Любая обратная связь будет оценена!
Благодарю.
2 ответа
Верхний уровень должен попасть в базу данных. Вы можете избежать этого, сохранив отметку времени в отдельной записи кэша с ключами по модели и идентификатору. Один из комментаторов статьи 1 (Мануэль Ф. Лара) предложил то же самое: "Есть ли другой тайник, подобный проектам /15-кратный, где у вас всегда есть последняя метка времени для списка проектов?"
Я думаю, что вы правы насчет "самого низкого" уровня во вложенности. Возможно, вам придется провести некоторое тестирование, чтобы увидеть относительную производительность доступа к БД по сравнению с визуализацией крошечной частичной.
Еще один хороший момент. Согласно документам, если вы передадите символ
:touch
он обновит этот атрибут в дополнение кupdated_at
- может быть, есть способ пропустить изменениеPost#updated_at
и только обновить столбец, какcomments_updated_at
, Тогда вы можете использовать последний для кеширования. Но если вы пытаетесь избежать доступа к БД, вам придется хранить еще один ключ кеша для этой метки времени (как в #1 выше).
Я полагаю, вы должны решить, стоит ли все это для вас. 2 статьи показывают простые, надуманные примеры для обучения принципам. В приложении со сложными ассоциациями метод кэширования "поколения" может быть более управляемым.
- Да. Но, как правило, сценарии как в лучшем, так и в довольно удачном случае встречаются довольно часто.
- Да. В некоторых приложениях, которые я разрабатываю, рендеринг представления занимает в 10-20 раз больше времени, чем выполнение запросов. Посмотрите на свои критерии.
- Если рендеринг поста является дорогостоящим, вы можете не хотеть трогать пост, а вместо этого составить ключ кеша списка комментариев из
[@post.comments.max(:updated_at), @post.comments.size]
,